User:AnomieBOT/source/tasks/TemplateTalkRedirectCreator.pm: Difference between revisions

Content deleted Content added
AnomieBOT (talk | contribs)
Updating published sources: TFDClerk, IFDCloser, PUICloser: * The "metadata" class was removed from the closing templates, so remove it from the is_closed regex * Add a sanity check to make sure the bot doesn't screw up if this sort of thing happens ag...
 
AnomieBOT (talk | contribs)
Updating published sources: TemplateTalkRedirectCreator: * Use continuation in database query, so the bot doesn't wind up uselessly looping forever if more than 500 invalid pages pile up at the beginning of the list.
Line 79:
}
my $where = join( ' OR ', @where );
 
my $query = qq{
my ($dbh, $schema);
SELECT p1.page_namespace + 1 AS ns, p1.page_title AS title
eval {
FROM page as p1
($dbh, $schema) = $api->connectToReplica( 'enwiki' );
LEFT JOIN page as p2 ON( p2.page_namespace = p1.page_namespace + 1 and p2.page_title = p1.page_title )
WHERE p2.page_id IS NULL AND ( $where )
LIMIT 500
};
if ( $@ ) {
$api->warn( "Error connecting to replica: $@\n" );
return 300;
}
 
my $cont = $self->{'dbcontinue'} // '';
 
# Spend a max of 5 minutes on this task before restarting
my $endtime=time()+300;
 
while ( time() < $endtime1 ) {
return 0 if $api->halting;
 
Line 96 ⟶ 100:
my @rows;
eval {
my@rows ($dbh,= $schema) =@{ $apidbh->connectToReplicaselectall_arrayref( 'enwiki' );qq{
@rows = @{ $dbh->selectall_arrayref( $query,SELECT {p1.page_namespace SliceAS => {}ns, }p1.page_title )AS };title
FROM page as p1
LEFT JOIN page as p2 ON( p2.page_namespace = p1.page_namespace + 1 and p2.page_title = p1.page_title )
WHERE p2.page_id IS NULL AND ( $where ) $cont
ORDER BY p1.page_namespace, p1.page_title
LIMIT 500
}, { Slice => {} } ) };
};
if ( $@ ) {
Line 107 ⟶ 117:
my %redirects = ();
for my $row (@rows) {
my $title = $rns{$row->{'ns'}+1} . ':' . $row->{'title'};
$title =~ s/_/ /g;
 
Line 118 ⟶ 128:
$redirects{$title} = $basetitle;
}
next unless %redirects;
 
if ( %redirects ) {
# Bypass double redirects and remove missing target pages
my $res = $api->query(
titles => join('|', values %redirects),
redirects => 1
);
if($res->{'code'} ne 'success'){
$api->warn("Failed to retrieve redirect list: ".$res->{'error'}."\n");
return 60;
}
my %map = ();
if ( exists($res->{'query'}{'normalized'} ) ) {
$map{$_->{'from'}} = $_->{'to'} foreach @{$res->{'query'}{'normalized'}};
}
if ( exists($res->{'query'}{'redirects'} ) ) {
$map{$_->{'from'}} = $_->{'to'} foreach @{$res->{'query'}{'redirects'}};
}
my %exists = ();
if ( exists($res->{'query'}{'pages'} ) ) {
for my $p (values %{$res->{'query'}{'pages'}}) {
$exists{$p->{'title'}} = 1 if $p->{'pageid'}//0;
}
} my %map = ();
while( my ($redir, $target) =if each( %redirectsexists($res->{'query'}{'normalized'} ) ) {
my %seen=( $targetmap{$_->{'from'}} = $_->{'to'} 1foreach )@{$res->{'query'}{'normalized'}};
while ( exists( $map{$target} ) ) {
$target = $map{$target};
$redirects{$redir} = $target;
if ( exists( $seen{$target} ) ) {
$api->warn("Redirect loop involving [[$target]]");
delete $redirects{$redir};
last;
}
$seen{$target}=1;
}
deleteif $redirects{$redir} unless( exists( $existsres->{$target'query'}{'redirects'} ); ) {
$map{$_->{'from'}} = $_->{'to'} foreach @{$res->{'query'}{'redirects'}};
}
 
# Now, create the redirects
while( my ($redir, $target) = each( %redirects ) ) {
return 0 if $api->halting;
 
my $tok=$api->edittoken($redir, EditRedir => 1);
if($tok->{'code'} eq 'shutoff'){
$api->warn("Task disabled: ".$tok->{'content'}."\n");
return 300;
}
if($tok->{'code'}my ne%exists 'success'= (){;
if ( $api->warnexists("Failed to get edit token for $redir: ".$tokres->{'errorquery'}."\n"{'pages'} ); ) {
next;for my $p (values %{$res->{'query'}{'pages'}}) {
$exists{$p->{'title'}} = 1 if $p->{'pageid'}//0;
}
}
if while( !existsmy ($tok->{'missing'}redir, $target) = each( %redirects ) ) {
$api->logmy %seen=(" $redirtarget already=> exists,1 skipping");
next;while ( exists( $map{$target} ) ) {
$target = $map{$target};
$redirects{$redir} = $target;
if ( exists( $seen{$target} ) ) {
$api->warn("Redirect loop involving [[$target]]");
delete $redirects{$redir};
last;
}
$seen{$target}=1;
}
delete $redirects{$redir} unless exists( $exists{$target} );
}
 
my# $txtNow, =create "#REDIRECTthe [[$target]]";redirects
while( my ($summary="Redirectingredir, to [[$target]]) = each( to%redirects avoid) decentralized) discussion";{
return 0 if $api->halting;
 
my $tok=$api->edittoken($redir, EditRedir => 1);
# Create page
if($apitok->log("$summary{'code'} ineq $redir"'shutoff');{
my $r = $api->editwarn($tok,"Task $txt,disabled: ".$summary, 0, 1tok->{'content'}."\n");
if($r->{'code'} ne 'success'){ return 300;
$api->warn("Write failed on $redir".$r->{'error'}."\n");
next;if($tok->{'code'} ne 'success'){
$api->warn("Failed to get edit token for $redir: ".$tok->{'error'}."\n");
}
next;
}
if ( !exists($tok->{'missing'} ) ) {
$api->log("$redir already exists, skipping");
next;
}
 
# If we've been atmy it$txt long= enough, let another task have a"#REDIRECT go.[[$target]]";
my $summary="Redirecting to [[$target]] to avoid decentralized discussion";
return 0 if time()>=$endtime;
 
# Create page
$api->log("$summary in $redir");
my $r = $api->edit($tok, $txt, $summary, 0, 1);
if($r->{'code'} ne 'success'){
$api->warn("Write failed on $redir".$r->{'error'}."\n");
next;
}
 
# If we've been at it long enough, let another task have a go.
return 0 if time()>=$endtime;
}
}
 
# On the next time around, skip any we've already processed this run
my ($ns, $title) = @{$rows[$#rows]}{'ns','title'};
$title = $dbh->quote( $title );
$cont = " AND (p1.page_namespace > $ns OR p1.page_namespace = $ns AND p1.page_title > $title)";
$self->{'dbcontinue'} = $cont;
 
# If we've been at it long enough, let another task have a go.
return 0 if time()>=$endtime;
}
 
$self->{'dbcontinue'} = '';
 
return 21600;