LJSUP-17669: Login.bml form refactoring
[livejournal.git] / htdocs / export_comments.bml
blobd7fea6ad18422153e7cb87f6003b594e21bedfb3
1 <?_code
3     use strict;
4     use vars qw(%GET);
5     use LJ::TimeUtil;
7     my $remote = LJ::get_remote();
8     return "<?needlogin?>" unless $remote;
10     my $authas = $GET{'authas'} || $remote->{'user'};
11     my $mode = $GET{get};
12     my $can_view = LJ::check_priv($remote, "siteadmin", "commentview") && ($mode ne 'comment_body');
13     my $u = $can_view ? LJ::load_user($authas) : LJ::get_authas_user($authas);
14     return LJ::bad_input($ML{'error.invalidauth'}) unless $u;
16     my @errors = ();
18     my $dbcr = LJ::get_cluster_reader($u);
19     push @errors, $ML{'error.nodb'} unless $dbcr;
21     # don't let people hit us with silly GET attacks
22     push @errors, "This page can't be viewed except via POST."
23         if BML::get_client_header('Referer') && !LJ::did_post();
25     #mode check
26     push @errors, "Invalid mode."
27         unless $mode =~ m/^comment_(?:meta|body)$/;
29     # error stuff
30     return LJ::bad_input(@errors) if @errors;
32     # from now on, we manage our own output
33     BML::suppress_headers();
34     BML::suppress_content();
36     # print top
37     LJ::Request->content_type("text/xml; charset=utf-8");
38     LJ::Request->send_http_header();
39     LJ::Request->print("<?xml version=\"1.0\" encoding='utf-8'?>\n<livejournal>\n");
41     # startid specified?
42     my $maxitems = $mode eq 'comment_meta' ? 10000 : 1000;
43     my $numitems = $GET{numitems};
44     my $gather;
46     if ( defined $numitems && ($numitems > 0) && ($numitems <= $maxitems) ) {
47         $gather = $numitems;
48     }
49     else {
50         $gather = $maxitems;
51     }
53     my $startid = $GET{startid}+0;
54     my $endid = $startid + $gather;
56     # get metadata
57     my $rows = $dbcr->selectall_arrayref('
58         SELECT jtalkid,
59                nodeid,
60                parenttalkid,
61                posterid,
62                state,
63                datepost
64           FROM talk2
65          WHERE nodetype = \'L\'
66            AND journalid = ?
67            AND jtalkid >= ?
68            AND jtalkid < ?',
69         undef,
70         $u->{userid},
71         $startid,
72         $endid
73     );
75     # now let's gather them all together while making a list of posterids
76     my ( %posterids, %comments );
78     foreach my $r ( @{$rows || []} ) {
79         $comments{$r->[0]} = {
80             nodeid       => $r->[1],
81             parenttalkid => $r->[2],
82             posterid     => $r->[3],
83             state        => $r->[4],
84             datepost     => $r->[5],
85         };
86         $posterids{$r->[3]} = 1 if $r->[3]; # don't include 0 (anonymous)
87     }
89     # now we have two choices: comments themselves or metadata
90     if ( $mode eq 'comment_meta' ) {
91         # meta data is easy :)
92         my $max = $dbcr->selectrow_array('
93             SELECT MAX(jtalkid)
94               FROM talk2
95              WHERE journalid = ?
96                AND nodetype = \'L\'',
97             undef,
98             $u->{userid},
99         );
100         $max += 0;
101         LJ::Request->print("<maxid>$max</maxid>\n");
102         my $nextid = $startid + $gather;
103         LJ::Request->print("<nextid>$nextid</nextid>\n") unless ($nextid > $max);
105         # load posterids
106         my $us = LJ::load_userids(keys %posterids);
108         # now spit out the metadata
109         LJ::Request->print("<comments>\n");
111         while (my ($id, $data) = each %comments) {
112             my $ret = "<comment id='$id'";
113             $ret .= " posterid='$data->{posterid}'" if $data->{posterid};
114             $ret .= " state='$data->{state}'" if $data->{state} ne 'A';
115             $ret .= " jitemid='$data->{nodeid}'";
116             $ret .= " />\n";
117             LJ::Request->print($ret);
118         }
120         LJ::Request->print("</comments>\n<usermaps>\n");
122         # now spit out usermap
123         my $ret = '';
125         while (my ($id, $user) = each %$us) {
126             $ret .= "<usermap id='$id' user='$user->{user}' />\n";
127         }
129         LJ::Request->print($ret);
130         LJ::Request->print("</usermaps>\n");
131     }
132     # comment data also presented in glorious XML:
133     elsif ($mode eq 'comment_body') {
134         # get real comments from startid to a limit of 10k data, however far that takes us
135         my @ids = sort { $a <=> $b } keys %comments;
137         # call a load to get comment text
138         my $texts = LJ::get_talktext2($u, @ids);
140         # get props if we need to
141         my $props = {};
142         if ($GET{'props'}) {
143             LJ::load_talk_props2($u->{userid}, \@ids, $props);
144         }
146         # now start spitting out data
147         LJ::Request->print("<comments>\n");
148         foreach my $id (@ids) {
149             # get text for this comment
150             my $data = $comments{$id};
151             my $text = $texts->{$id};
152             my ($subject, $body) = @{$text || []};
154             # only spit out valid UTF8, and make sure it fits in XML, and uncompress it
155             LJ::text_uncompress(\$body);
156             LJ::text_out(\$subject);
157             LJ::text_out(\$body);
158             $subject = LJ::exml($subject);
159             $body = LJ::exml($body);
161             # setup the date to be GMT and formatted per W3C specs
162             my $date = LJ::TimeUtil->mysqldate_to_time($data->{datepost});
163             $date = LJ::TimeUtil->time_to_w3c($date, 'Z');
165             # print the data
166             my $ret = "<comment id='$id' jitemid='$data->{nodeid}'";
167             $ret .= " posterid='$data->{posterid}'" if $data->{posterid};
168             $ret .= " state='$data->{state}'" if $data->{state} ne 'A';
169             $ret .= " parentid='$data->{parenttalkid}'" if $data->{parenttalkid};
170             if ($data->{state} eq 'D') {
171                 $ret .= " />\n";
172             } else {
173                 $ret .= ">\n";
174                 $ret .= "<subject>$subject</subject>\n" if $subject;
175                 $ret .= "<body>$body</body>\n" if $body;
176                 $ret .= "<date>$date</date>\n";
177                 foreach my $propkey (keys %{$props->{$id} || {}}) {
178                     $ret .= "<property name='$propkey'>";
179                     $ret .= LJ::exml($props->{$id}->{$propkey});
180                     $ret .= "</property>\n";
181                 }
182                 $ret .= "</comment>\n";
183             }
184             LJ::Request->print($ret);
185         }
186         LJ::Request->print("</comments>\n");
187     }
189     # all done
190     LJ::Request->print("</livejournal>\n");
192 _code?><?_c <LJDEP>
193 </LJDEP> _c?>