afuna: Cat under a blanket. Text: "Cats are just little people with Fur and Fangs" (Default)
afuna ([personal profile] afuna) wrote in [site community profile] changelog2009-08-05 03:49 pm

[dw-free] allow crossposting from clients

[commit: http://hg.dwscoalition.org/dw-free/rev/1c0901cf5b11]

http://bugs.dwscoalition.org/show_bug.cgi?id=1305

Move all the exciting crossposting action to ljprotocol.pl, so that
everything that posts to Dreamwidth will go through the crossposting logic.

Patch by [personal profile] superliminal.

Files modified:
  • cgi-bin/ljprotocol.pl
  • htdocs/editjournal.bml
  • htdocs/update.bml
--------------------------------------------------------------------------------
diff -r ba0755847a96 -r 1c0901cf5b11 cgi-bin/ljprotocol.pl
--- a/cgi-bin/ljprotocol.pl	Wed Aug 05 09:56:59 2009 +0000
+++ b/cgi-bin/ljprotocol.pl	Wed Aug 05 15:48:33 2009 +0000
@@ -982,6 +982,32 @@ sub common_event_validation
            ! LJ::Tags::is_valid_tagstring($req->{props}->{taglist});
 
     return 1;
+}
+
+sub schedule_xposts
+{
+    my ($u, $ditemid, $deletep, $fn) = @_;
+    my @successes;
+    my @failures;
+    my @accounts = DW::External::Account->get_external_accounts($u);
+    foreach my $acct (@accounts) {
+        my ($xpostp, $info) = $fn->($acct);
+        if ($xpostp) {
+            my $sclient = LJ::theschwartz();
+            my $info = {uid => $u->userid,
+                        accountid => $acct->acctid,
+                        ditemid => $ditemid,
+                        delete => $deletep,
+                        %{$info}};
+            my $job = TheSchwartz::Job->new_from_array('DW::Worker::XPostWorker', $info);
+            if ($sclient && $job && $sclient->insert($job)) {
+                push @successes, $acct;
+            } else {
+                push @failures, $acct;
+            }
+        }
+    }
+    return (\@successes, \@failures);
 }
 
 sub postevent
@@ -1498,6 +1524,10 @@ sub postevent
 
     my $entry = LJ::Entry->new($uowner, jitemid => $jitemid, anum => $anum);
 
+    if (LJ::u_equals($u, $uowner) && $req->{xpost} ne '0') {
+        schedule_xposts($u, $ditemid, 0, sub { ((shift)->xpostbydefault, {}) });
+    }
+
     # run local site-specific actions
     LJ::run_hooks("postpost", {
         'itemid'    => $jitemid,
@@ -1548,6 +1578,8 @@ sub editevent
 sub editevent
 {
     my ($req, $err, $flags) = @_;
+    my $res;
+    my $deleted = 0;
     un_utf8_request($req);
 
     return undef unless authenticate($req, $err, $flags);
@@ -1604,6 +1636,8 @@ sub editevent
          "compressed, security, allowmask, year, month, day, ".
          "rlogtime, anum FROM log2 WHERE journalid=$ownerid AND jitemid=$itemid");
 
+    my $ditemid = $itemid * 256 + $oldevent->{anum};
+
     ($oldevent->{subject}, $oldevent->{event}) = $dbcm->selectrow_array
         ("SELECT subject, event FROM logtext2 ".
          "WHERE journalid=$ownerid AND jitemid=$itemid");
@@ -1649,6 +1683,8 @@ sub editevent
     # simple logic for deleting an entry
     if (!$flags->{'use_old_content'} && $req->{'event'} !~ /\S/)
     {
+        $deleted = 1;
+
         # if their newesteventtime prop equals the time of the one they're deleting
         # then delete their newesteventtime.
         if ($u->{'userid'} == $uowner->{'userid'}) {
@@ -1664,7 +1700,7 @@ sub editevent
         # delete is initiated.
         $uowner->log_event('delete_entry', {
                 remote => $u,
-                actiontarget => ($req->{itemid} * 256 + $oldevent->{anum}),
+                actiontarget => $ditemid,
                 method => 'protocol',
             })
             unless $flags->{noauth};
@@ -1675,9 +1711,8 @@ sub editevent
         # what they just deleted.  (or something... probably rare.)
         LJ::set_userprop($u, "dupsig_post", undef);
 
-        my $res = { 'itemid' => $itemid,
-                    'anum' => $oldevent->{'anum'} };
-        return $res;
+        $res = {itemid => $itemid, anum => $oldevent->{anum}};
+        goto END;
     }
 
     # now make sure the new entry text isn't $CannotBeShown
@@ -1794,7 +1829,7 @@ sub editevent
                        LJ::mysqldate_to_time($eventtime, 1),
                        LJ::mysqldate_to_time($oldevent->{'logtime'}, 1),
                        $sec,
-                       $itemid*256 + $oldevent->{'anum'});
+                       $ditemid);
 
         LJ::MemCache::set([$ownerid, "log2:$ownerid:$itemid"], $row);
 
@@ -1875,7 +1910,7 @@ sub editevent
 
     LJ::memcache_kill($ownerid, "dayct2");
 
-    my $res = { 'itemid' => $itemid };
+    $res = {itemid => $itemid};
     if (defined $oldevent->{'anum'}) {
         $res->{'anum'} = $oldevent->{'anum'};
         $res->{'url'} = LJ::item_link($uowner, $itemid, $oldevent->{'anum'});
@@ -1891,6 +1926,13 @@ sub editevent
 
     LJ::run_hooks("editpost", $entry);
 
+ END:
+    my $xpost_string = $curprops{$itemid}->{xpost};
+    if ($xpost_string && LJ::u_equals($u, $uowner) && $req->{xpost} ne '0') {
+        my $xpost_info = DW::External::Account->xpost_string_to_hash($xpost_string);
+        schedule_xposts($u, $ditemid, $deleted,
+                        sub { ($xpost_info->{(shift)->acctid}, {}) });
+    }
     return $res;
 }
 
diff -r ba0755847a96 -r 1c0901cf5b11 htdocs/editjournal.bml
--- a/htdocs/editjournal.bml	Wed Aug 05 09:56:59 2009 +0000
+++ b/htdocs/editjournal.bml	Wed Aug 05 15:48:33 2009 +0000
@@ -205,6 +205,7 @@ body<=
                             'user' => $u->{'user'},
                             'usejournal' => $usejournal,
                             'itemid' => $itemid,
+                            'xpost' => '0'
                             );
                 LJ::entry_form_decode(\%req, \%POST);
 
@@ -242,46 +243,31 @@ body<=
                 # selected crosspost.
                 my $xpost_result = '';
                 if ($journalu == $remote && ($POST{prop_xpost_check} || $GET{prop_xpost_check})) {
-                    my @xpost_success;
-                    my @xpost_errors;
-
-                    # get the accounts for the user
-                    my @accounts = DW::External::Account->get_external_accounts($remote);
-                    foreach my $acct(@accounts) {
-                        my $acctid = $acct->acctid;
-                        # see if we said to xpost to this account
-                        if ($POST{"prop_xpost_$acctid"} || $GET{"prop_xpost_$acctid"}) {
-                            # get the auth information
-                            my %auth;
-                            if ($POST{"prop_xpost_resp_$acctid"} || $GET{"prop_xpost_resp_$acctid"}) {
-                                $auth{auth_response} = $POST{"prop_xpost_resp_$acctid"} || $GET{"prop_xpost_resp_$acctid"};
-                                $auth{auth_challenge} = $POST{"prop_xpost_chal_$acctid"} || $GET{"prop_xpost_chal_$acctid"};
-                            } else {
-                                $auth{password} = $POST{"prop_xpost_password_$acctid"} || $GET{"prop_xpost_password_$acctid"};
-                            }
-                            # send this to theschwartz to crosspost
-                            my $sclient = LJ::theschwartz();
-                            my $job = TheSchwartz::Job->new_from_array(
-                                'DW::Worker::XPostWorker', { 
-                                    'uid' => $remote->userid, 
-                                    'ditemid' => $ditemid, 
-                                    'accountid' => $acctid, 
-                                    'password' => $auth{password}, 
-                                    'auth_challenge' => $auth{auth_challenge}, 
-                                    'auth_response' => $auth{auth_response},
-                                    'delete' => $deleted } );
-                            # if we have a client and job, then request 
-                            # the crosspost
-                            if ($sclient && $job && $sclient->insert($job)) {
-                                push @xpost_success, "<li>" . BML::ml('xpost.request.success', {'account' => $acct->displayname}) . "</li>";
-                            } else {
-                                # one of them didn't work.
-                                push @xpost_errors, "<li><div style='color: red;'><strong>" . BML::ml('xpost.request.failed', { 'account' => $acct->displayname, 'editurl' => $edititemlink })  . " </strong></div></li>";
-                            }
-                        }
-                    }
-                    $xpost_result .= join ("\n", @xpost_success);
-                    $xpost_result .= join ("\n", @xpost_errors);
+                    my ($xpost_successes, $xpost_failures) =
+                        LJ::Protocol::schedule_xposts($remote, $ditemid, $deleted,
+                                                      sub {
+                                                          my $acctid = (shift)->acctid;
+                                                          ($POST{"prop_xpost_$acctid"} || $GET{"prop_xpost_$acctid"},
+                                                           {password => $POST{"prop_xpost_password_$acctid"}
+                                                                        || $GET{"prop_xpost_password_$acctid"},
+                                                            auth_challenge => $POST{"prop_xpost_chal_$acctid"}
+                                                                              || $GET{"prop_xpost_chal_$acctid"},
+                                                            auth_response => $POST{"prop_xpost_resp_$acctid"}
+                                                                             || $GET{"prop_xpost_resp_$acctid"}})
+                                                      });
+                    $xpost_result .= join("\n",
+                                          map {"<li>"
+                                               . BML::ml('xpost.request.success',
+                                                         {account => $_->displayname})
+                                               . "</li>"}
+                                              @{$xpost_successes});
+                    $xpost_result .= join("\n",
+                                          map {"<li><div style='color: red;'><strong>"
+                                               . BML::ml('xpost.request.failed',
+                                                         {account => $_->displayname,
+                                                          'editurl' => $edititemlink})
+                                               . " </strong></div></li>"}
+                                              @{$xpost_failures});
                 }
 
                 my $result = "<?h1 $ML{'.success.head'} h1?>";
diff -r ba0755847a96 -r 1c0901cf5b11 htdocs/update.bml
--- a/htdocs/update.bml	Wed Aug 05 09:56:59 2009 +0000
+++ b/htdocs/update.bml	Wed Aug 05 15:48:33 2009 +0000
@@ -375,6 +375,7 @@
                     'password'    => $POST{'password'},
                     'usejournal'  => $POST{'usejournal'},
                     'tz'          => 'guess',
+                    'xpost'       => '0'
                     );
 
         LJ::entry_form_decode(\%req, \%POST);
@@ -445,48 +446,32 @@
                     # crosspost if we're posting to our own journal and have
                     # selected crosspost.
                     if ($ju == $remote && ($POST{prop_xpost_check} || $GET{prop_xpost_check})) {
-                        my @xpost_success;
-                        my @xpost_errors;
-
-                        # get the accounts for the user
-                        my @accounts = DW::External::Account->get_external_accounts($remote);
-                        foreach my $acct(@accounts) {
-                            my $acctid = $acct->acctid;
-                            # see if we said to xpost to this account
-                            if ($POST{"prop_xpost_$acctid"} || $GET{"prop_xpost_$acctid"}) {
-                                # xpost to this account.
-                                my $result = {};
-                                my %auth;
-                                if ($POST{"prop_xpost_resp_$acctid"} || $GET{"prop_xpost_resp_$acctid"}) {
-                                    $auth{auth_response} = $POST{"prop_xpost_resp_$acctid"} || $GET{"prop_xpost_resp_$acctid"};
-                                    $auth{auth_challenge} = $POST{"prop_xpost_chal_$acctid"} || $GET{"prop_xpost_chal_$acctid"};
-                                } else {
-                                    $auth{password} = $POST{"prop_xpost_password_$acctid"} || $GET{"prop_xpost_password_$acctid"};
-                                }
-                                # send this to theschwartz to crosspost
-                                my $sclient = LJ::theschwartz();
-                                my $job = TheSchwartz::Job->new_from_array(
-                                    'DW::Worker::XPostWorker', { 
-                                        'uid' => $remote->userid, 
-                                        'ditemid' => $itemid, 
-                                        'accountid' => $acctid, 
-                                        'password' => $auth{password}, 
-                                        'auth_challenge' => $auth{auth_challenge}, 
-                                        'auth_response' => $auth{auth_response} });
-                                # if we have a client and job, then request 
-                                # the crosspost
-                                if ($sclient && $job && $sclient->insert($job)) {
-                                    push @xpost_success, "<li>" . BML::ml('xpost.request.success', {'account' => $acct->displayname}) . "</li>";
-                                } else {
-                                    # one of them didn't work.
-                                    push @xpost_errors, "<li><div style='color: red;'><strong>" . BML::ml('xpost.request.failed', { 'account' => $acct->displayname, 'editurl' => $edititemlink })  . " </strong></div></li>";
-                                }
-                            }
-                        }
-
+                        my ($xpost_successes, $xpost_errors) =
+                            LJ::Protocol::schedule_xposts($remote, $itemid, 0,
+                                                          sub {
+                                                              my $acctid = (shift)->acctid;
+                                                              ($POST{"prop_xpost_$acctid"} || $GET{"prop_xpost_$acctid"},
+                                                               {password => $POST{"prop_xpost_password_$acctid"}
+                                                                            || $GET{"prop_xpost_password_$acctid"},
+                                                                auth_challenge => $POST{"prop_xpost_chal_$acctid"}
+                                                                                  || $GET{"prop_xpost_chal_$acctid"},
+                                                                auth_response => $POST{"prop_xpost_resp_$acctid"}
+                                                                                 || $GET{"prop_xpost_resp_$acctid"}})
+                                                          });
                         $$body .= "<ul>\n";
-                        $$body .= join ("\n", @xpost_success);
-                        $$body .= join ("\n", @xpost_errors);
+                        $$body .= join("\n",
+                                       map { "<li>"
+                                             . BML::ml('xpost.request.success',
+                                                       {account => $_->displayname})
+                                             . "</li>" }
+                                           @{$xpost_successes});
+                        $$body .= join("\n",
+                                       map { "<li><div style='color: red;'><strong>"
+                                             . BML::ml('xpost.request.failed',
+                                                       {account => $_->displayname,
+                                                        editurl => $edititemlink })
+                                             . " </strong></div></li>" }
+                                           @{$xpost_errors});
                         $$body .= "</ul>\n";
                         $$body .= "<br/>";
                     }
--------------------------------------------------------------------------------