mark: A photo of Mark kneeling on top of the Taal Volcano in the Philippines. It was a long hike. (Default)
Mark Smith ([staff profile] mark) wrote in [site community profile] changelog2009-09-18 06:20 am

[dw-free] allow crossposting from clients

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

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

Enable crossposting by default for third party clients.

Patch by [personal profile] superluminal.

Files modified:
  • cgi-bin/ljprotocol.pl
  • htdocs/editjournal.bml
  • htdocs/update.bml
--------------------------------------------------------------------------------
diff -r c7898ce3a58f -r aae36b18c269 cgi-bin/ljprotocol.pl
--- a/cgi-bin/ljprotocol.pl	Fri Sep 18 02:59:12 2009 +0000
+++ b/cgi-bin/ljprotocol.pl	Fri Sep 18 06:20:05 2009 +0000
@@ -982,6 +982,38 @@ sub common_event_validation
            ! LJ::Tags::is_valid_tagstring($req->{props}->{taglist});
 
     return 1;
+}
+
+sub schedule_xposts {
+    my ( $u, $ditemid, $deletep, $fn ) = @_;
+    return unless LJ::isu( $u ) && $ditemid > 0;
+    return unless $fn && ref $fn eq 'CODE';
+
+    my ( @successes, @failures );
+    my $sclient = LJ::theschwartz() or return;
+    my @accounts = DW::External::Account->get_external_accounts( $u );
+
+    foreach my $acct ( @accounts ) {
+        my ( $xpostp, $info ) = $fn->( $acct );
+        next unless $xpostp;
+
+        my $jobargs = {
+            uid       => $u->userid,
+            accountid => $acct->acctid,
+            ditemid   => $ditemid + 0,
+            delete    => $deletep ? 1 : 0,
+            %{$info}
+        };
+
+        my $job = TheSchwartz::Job->new_from_array( 'DW::Worker::XPostWorker', $jobargs );
+        if ( $job && $sclient->insert($job) ) {
+            push @successes, $acct;
+        } else {
+            push @failures, $acct;
+        }
+    }
+
+    return ( \@successes, \@failures );
 }
 
 sub postevent
@@ -1514,6 +1546,10 @@ sub postevent
 
     my $entry = LJ::Entry->new($uowner, jitemid => $jitemid, anum => $anum);
 
+    if ( $u->equals( $uowner ) && $req->{xpost} ne '0' ) {
+        schedule_xposts( $u, $ditemid, 0, sub { ((shift)->xpostbydefault, {}) } );
+    }
+
     # run local site-specific actions
     LJ::run_hooks("postpost", {
         'itemid'    => $jitemid,
@@ -1567,6 +1603,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);
@@ -1623,6 +1661,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");
@@ -1641,6 +1681,20 @@ sub editevent
     ### make sure this user is allowed to edit this entry
     return fail($err,302)
         unless ($ownerid == $oldevent->{'ownerid'});
+
+    ### load existing meta-data
+    my %curprops;
+    LJ::load_log_props2($dbcm, $ownerid, [ $itemid ], \%curprops);
+
+    # xpost helper for later
+    my $schedule_xposts = sub {
+        my $xpost_string = $curprops{$itemid}->{xpost};
+        if ( $xpost_string && $u->equals( $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}, {}) } );
+        }
+    };
 
     ### what can they do to somebody elses entry?  (in shared journal)
     ### can edit it if they own or maintain the journal, but not if the journal is read-only
@@ -1668,6 +1722,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'}) {
@@ -1683,7 +1739,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};
@@ -1694,8 +1750,10 @@ sub editevent
         # what they just deleted.  (or something... probably rare.)
         LJ::set_userprop($u, "dupsig_post", undef);
 
-        my $res = { 'itemid' => $itemid,
-                    'anum' => $oldevent->{'anum'} };
+        # pass the delete
+        $schedule_xposts->();
+
+        $res = { itemid => $itemid, anum => $oldevent->{anum} };
         return $res;
     }
 
@@ -1722,10 +1780,6 @@ sub editevent
     # updating an entry:
     return undef
         unless common_event_validation($req, $err, $flags);
-
-    ### load existing meta-data
-    my %curprops;
-    LJ::load_log_props2($dbcm, $ownerid, [ $itemid ], \%curprops);
 
     ## handle meta-data (properties)
     my %props_byname = ();
@@ -1813,7 +1867,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);
 
@@ -1894,7 +1948,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'});
@@ -1919,6 +1973,9 @@ sub editevent
         my @handles = $sclient->insert_jobs(@jobs);
         # TODO: error on failure?  depends on the job I suppose?  property of the job?
     }
+
+    # ensure our xposted edit fires
+    $schedule_xposts->();
 
     return $res;
 }
diff -r c7898ce3a58f -r aae36b18c269 htdocs/editjournal.bml
--- a/htdocs/editjournal.bml	Fri Sep 18 02:59:12 2009 +0000
+++ b/htdocs/editjournal.bml	Fri Sep 18 06:20:05 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 c7898ce3a58f -r aae36b18c269 htdocs/update.bml
--- a/htdocs/update.bml	Fri Sep 18 02:59:12 2009 +0000
+++ b/htdocs/update.bml	Fri Sep 18 06:20:05 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/>";
                     }
--------------------------------------------------------------------------------

Post a comment in response:

This account has disabled anonymous posting.
If you don't have an account you can create one now.
HTML doesn't work in the subject.
More info about formatting

If you are unable to use this captcha for any reason, please contact us by email at support@dreamwidth.org