[dw-free] syn_merge console command needs WTF updating
[commit: http://hg.dwscoalition.org/dw-free/rev/b43c5610af84]
http://bugs.dwscoalition.org/show_bug.cgi?id=822
Fix the syn_merge command, which lets admins with the proper privs merge
duplicate feeds.
Patch by
fu.
Files modified:
http://bugs.dwscoalition.org/show_bug.cgi?id=822
Fix the syn_merge command, which lets admins with the proper privs merge
duplicate feeds.
Patch by
![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Files modified:
- cgi-bin/DW/User/Edges/WatchTrust.pm
- cgi-bin/LJ/ConfCheck/General.pm
- cgi-bin/LJ/Console/Command/SynMerge.pm
- cgi-bin/ljdefaults.pl
- t/console-syndicated.t
-------------------------------------------------------------------------------- diff -r 5e6c5d092470 -r b43c5610af84 cgi-bin/DW/User/Edges/WatchTrust.pm --- a/cgi-bin/DW/User/Edges/WatchTrust.pm Thu Jun 10 19:01:12 2010 +0800 +++ b/cgi-bin/DW/User/Edges/WatchTrust.pm Thu Jun 10 19:05:10 2010 +0800 @@ -440,7 +440,7 @@ sub trusted_by_userids { sub trusted_by_userids { my ( $u, %args ) = @_; $u = LJ::want_user( $u ) or confess 'not a valid user object'; - my $limit = int(delete $args{limit}) || 50000; + my $limit = int(delete $args{limit}) || $LJ::MAX_WT_EDGES_LOAD; confess 'unknown option' if %args; return DW::User::Edges::WatchTrust::Loader::_wt_userids( @@ -454,7 +454,7 @@ sub trusted_userids { sub trusted_userids { my ( $u, %args ) = @_; $u = LJ::want_user( $u ) or confess 'not a valid user object'; - my $limit = int(delete $args{limit}) || 50000; + my $limit = int(delete $args{limit}) || $LJ::MAX_WT_EDGES_LOAD; confess 'unknown option' if %args; return DW::User::Edges::WatchTrust::Loader::_wt_userids( @@ -468,7 +468,7 @@ sub watched_by_userids { sub watched_by_userids { my ( $u, %args ) = @_; $u = LJ::want_user( $u ) or confess 'not a valid user object'; - my $limit = int(delete $args{limit}) || 50000; + my $limit = int(delete $args{limit}) || $LJ::MAX_WT_EDGES_LOAD; confess 'unknown option' if %args; return DW::User::Edges::WatchTrust::Loader::_wt_userids( @@ -482,7 +482,7 @@ sub watched_userids { sub watched_userids { my ( $u, %args ) = @_; $u = LJ::want_user( $u ) or confess 'not a valid user object'; - my $limit = int(delete $args{limit}) || 50000; + my $limit = int(delete $args{limit}) || $LJ::MAX_WT_EDGES_LOAD; confess 'unknown option' if %args; return DW::User::Edges::WatchTrust::Loader::_wt_userids( diff -r 5e6c5d092470 -r b43c5610af84 cgi-bin/LJ/ConfCheck/General.pm --- a/cgi-bin/LJ/ConfCheck/General.pm Thu Jun 10 19:01:12 2010 +0800 +++ b/cgi-bin/LJ/ConfCheck/General.pm Thu Jun 10 19:05:10 2010 +0800 @@ -247,6 +247,11 @@ add_conf('$MAX_FRIENDOF_LOAD', type => 'int', des => "The maximum number of friend-ofs ('fans'/'followers') to load for a given user. Defaults to 5000. Beyond that, a user is just too popular and saying 5,000 is usually sufficient because people aren't actually reading the list.", ); + +add_conf('$MAX_WT_EDGES_LOAD', + type => 'int' + des => "The maximum number of users to load for watch/trust edges when we can afford to be sloppy about the results returned. It is possible to override this limit to get the full list, but most of the time, you won't need to. Defaults to 50,000.", + ); add_conf('$MAX_SCROLLBACK_LASTN', type => 'int', diff -r 5e6c5d092470 -r b43c5610af84 cgi-bin/LJ/Console/Command/SynMerge.pm --- a/cgi-bin/LJ/Console/Command/SynMerge.pm Thu Jun 10 19:01:12 2010 +0800 +++ b/cgi-bin/LJ/Console/Command/SynMerge.pm Thu Jun 10 19:05:10 2010 +0800 @@ -52,6 +52,11 @@ sub execute { my $to_u = LJ::load_user($to_user) or return $self->error("Invalid user: '$to_user'."); + # we don't want to unlimit this, so reject if we have too many users + my @ids = $from_u->watched_by_userids( limit => $LJ::MAX_WT_EDGES_LOAD+1 ); + return $self->error( "Unable to merge feeds. Too many users are watching the feed '" . $from_u->user . "'. We only allow merges for feeds with at most $LJ::MAX_WT_EDGES_LOAD watchers." ) + if scalar @ids > $LJ::MAX_WT_EDGES_LOAD; + foreach ($to_u, $from_u) { return $self->error("Invalid user: '" . $_->user . "' (statusvis is " . $_->statusvis . ", already merged?)") unless $_->is_visible; @@ -87,25 +92,35 @@ sub execute { return $self->error("Database Error: " . $dbh->errstr) if $dbh->err; - # 4) make users who befriend 'from_user' now befriend 'to_user' - # 'force' so we get master db and there's no row limit - if (my @ids = LJ::get_friendofs($from_u, { force => 1 } )) { - + # 4) make users who watch 'from_user' now watch 'to_user' + # we can't just use delete_ and add_ edges, because we would lose + # custom group and colors data + if ( @ids ) { # update ignore so we don't raise duplicate key errors - $dbh->do("UPDATE IGNORE friends SET friendid=? WHERE friendid=?", - undef, $to_u->id, $from_u->id); + $dbh->do( 'UPDATE IGNORE wt_edges SET to_userid=? WHERE to_userid=?', + undef, $to_u->id, $from_u->id ); return $self->error("Database Error: " . $dbh->errstr) if $dbh->err; # in the event that some rows in the update above caused a duplicate key error, # we can delete the rows that weren't updated, since they don't need to be # processed anyway - $dbh->do("DELETE FROM friends WHERE friendid=?", undef, $from_u->id); + $dbh->do( "DELETE FROM wt_edges WHERE to_userid=?", undef, $from_u->id ); return $self->error("Database Error: " . $dbh->errstr) if $dbh->err; # clear memcache keys - LJ::memcache_kill($_, 'friend') foreach @ids; + foreach my $id ( @ids ) { + LJ::memcache_kill( $id, 'wt_edges' ); + LJ::memcache_kill( $id, 'wt_list' ); + LJ::memcache_kill( $id, 'watched' ); + } + + LJ::memcache_kill( $from_u->id, 'wt_edges_rev' ); + LJ::memcache_kill( $from_u->id, 'watched_by' ); + + LJ::memcache_kill( $to_u->id, 'wt_edges_rev' ); + LJ::memcache_kill( $to_u->id, 'watched_by' ); } # log to statushistory diff -r 5e6c5d092470 -r b43c5610af84 cgi-bin/ljdefaults.pl --- a/cgi-bin/ljdefaults.pl Thu Jun 10 19:01:12 2010 +0800 +++ b/cgi-bin/ljdefaults.pl Thu Jun 10 19:05:10 2010 +0800 @@ -324,6 +324,9 @@ # default to limit to 2000 results $LJ::MAX_DIR_SEARCH_RESULTS ||= 2000; + + # default to limit to 50,000 watch or trust edges to load + $LJ::MAX_WT_EDGES_LOAD ||= 50_000; } return 1; diff -r 5e6c5d092470 -r b43c5610af84 t/console-syndicated.t --- a/t/console-syndicated.t Thu Jun 10 19:01:12 2010 +0800 +++ b/t/console-syndicated.t Thu Jun 10 19:05:10 2010 +0800 @@ -7,8 +7,7 @@ use LJ::Test qw (temp_user temp_feed); use LJ::Test qw (temp_user temp_feed); local $LJ::T_NO_COMMAND_PRINT = 1; -#plan tests => 7; -plan skip_all => 'Fix this test!'; +plan tests => 10; my $u = temp_user(); my $feed1 = temp_feed(); @@ -39,7 +38,26 @@ is($run->("syn_editurl " . $feed2->user is($run->("syn_editurl " . $feed2->user . " $LJ::SITEROOT/feed.rss"), "error: URL for account " . $feed2->user . " not changed: URL in use by " . $feed1->user); + +my $u2 = temp_user(); +my $u3 = temp_user(); + +$u->add_edge( $feed1, watch => { nonotify => 1 } ); +$u2->add_edge( $feed1, watch => { nonotify => 1 } ); + +$u2->add_edge( $feed2, watch => { nonotify => 1 } ); +$u3->add_edge( $feed2, watch => { nonotify => 1 } ); +# check colors? + +my $oldlimit = $LJ::MAX_WT_EDGES_LOAD; +$LJ::MAX_WT_EDGES_LOAD = 1; +is( $run->( "syn_merge " . $feed1->user . " to " . $feed2->user . " using $LJ::SITEROOT/feed.rss#2" ), + "error: Unable to merge feeds. Too many users are watching the feed '" . $feed1->user . "'. We only allow merges for feeds with at most $LJ::MAX_WT_EDGES_LOAD watchers." ); + +$LJ::MAX_WT_EDGES_LOAD = $oldlimit; is($run->("syn_merge " . $feed1->user . " to " . $feed2->user . " using $LJ::SITEROOT/feed.rss#2"), "success: Merged " . $feed1->user . " to " . $feed2->user . " using URL: $LJ::SITEROOT/feed.rss#2."); $feed1 = LJ::load_user($feed1->user); ok($feed1->is_renamed, "Feed redirection set up correctly."); +is(scalar $feed1->watched_by_userids, 0, "No watches remaining for " . $feed1->user); +is(scalar $feed2->watched_by_userids, 3, "3 watchers for " . $feed2->user); --------------------------------------------------------------------------------