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

Content deleted Content added
AnomieBOT (talk | contribs)
Updating published sources: PUICloser: * Approved! AFDMergeFromCleaner: * Add handling of deleted pages * Clean up reporting code * Run to completion each time.
AnomieBOT (talk | contribs)
Updating published sources: General: * Update for the addition of 'rvslots'. DatedCategoryDeleterTest: * Disable. It's clear that task won't be needed. BrokenRedirectDeleter: * Handle pages with newlines before the <code>#REDIRECT</code>.
 
(22 intermediate revisions by the same user not shown)
Line 1:
{{ombox|type=notice|text= ApprovalApproved requested 20082009-1201-2903<br />[[Wikipedia:Bots/Requests for approval/AnomieBOT 20]]}}
<sourcesyntaxhighlight lang="perl">
package tasks::AFDMergeFromCleaner;
 
Line 7:
=begin metadata
 
Bot: AnomieBOT
Task: AFDMergeFromCleaner
BRFA: Wikipedia:Bots/Requests for approval/AnomieBOT 20
Status: BRFA
Status: Approved 2009-01-03
Rate: Max 6 edits/minute
Created: 2008-12-29
 
Remove instances of {{tl|afd-mergefrommerge from}} where the merge has been completed.
Report instances of {{tl|afd-mergefrommerge from}} where the AFDed page is now a redirect
to a different target.
 
Line 38 ⟶ 39:
 
=for info
ApprovalApproved requested 20082009-1201-2903<br />[[Wikipedia:Bots/Requests for approval/AnomieBOT 20]]
 
=cut
 
sub approved {
return 03;
}
 
Line 50 ⟶ 51:
my $res;
 
$api->task('AFDMergeFromCleaner', 0, 10, qw/d::Templates d::Redirects/);
if($self->{'nextrun'}==0){
 
my $t=$api->fetch('nextrun');
if($self->{'nextrun'}=$$t if(defined($t) && $$t=~/^\d+$/0 && exists($$t<=time(api->store->{'nextrun'}));{
my $t=$api->fetch(store->{'nextrun')};
if( $self->{'nextrun'}=$t if $t=0){~/^\d+$/;
}
my $starttime=time();
Line 58 ⟶ 61:
return $t if $t>0;
 
$api->taskmy @templates=('AFDMergeFromCleanerAfd-merge from');
$api->read_throttle(0);
$api->edit_throttle(10);
 
my @templates=('Afd-mergefrom');
my $screwup=' Errors? [[User:'.$api->user.'/shutoff/AFDMergeFromCleaner]]';
my $report='User:'.$api->user.'/Afd-mergefrom report';
 
# Get a list of templates redirecting to our targets
my %templates=$api->redirects_to_resolved(map "Template:$_", @templates);
foreach my $template if(@exists($templates{''})){
$api->warn("Failed to get redirects to target templates: ".$templates{''}{'error'}."\n");
$templates{"Template:$template"}=1;
$res=$self->fullquery($api,return undef,60;
list => 'backlinks',
bltitle => "Template:$template",
blfilterredir => 'redirects',
bllimit => 'max',
);
$templates{$_->{'title'}}=1 foreach (@{$res->{'query'}{'backlinks'}});
}
 
Line 82 ⟶ 75:
my %deleted=();
my $ret=21600;
 
my $linktmpl='User:'.$api->user.'/la';
 
MAINLOOP:
Line 95 ⟶ 90:
$res=$api->query(%q);
if($res->{'code'} ne 'success'){
$selfapi->warn("Failed to retrieve transclusion list for $template: ".$res->{'error'}."\n");
$ret=60;
last MAINLOOP;
Line 115 ⟶ 110:
}
 
$selfres=$api->warnquery("Checkingtitles for=> $templatesubject, in $title\n"redirects=>1);
if($res->{'code'} ne 'success'){
$api->warn("Failed to retrieve redirect target for $subject: ".$res->{'error'}."\n");
bltitle => "Template:$template",ret=60;
bllimit => 'max',last MAINLOOP;
}
my $rsubject=$subject;
$templates{$_->{'title'}}=1 foreach (@{$res->{'query'}{'backlinksredirects'}});{
$rsubject=$_->{'to'} if($_->{'from'} eq $rsubject);
}
 
$api->log("Checking for $template in $title");
 
# WTF?
if(exists($_->{'missing'})){
$selfapi->warn("$title is missing? WTF?\n");
next;
}
Line 126 ⟶ 132:
my $tok=$api->edittoken($title);
if($tok->{'code'} eq 'shutoff'){
$selfapi->warn("Task disabled: ".$tok->{'content'}."\n");
return 300;
}
if($tok->{'code'} ne 'success'){
$selfapi->warn("Failed to get edit token for $title: ".$tok->{'error'}."\n");
next$ret=60;
last MAINLOOP;
}
next if exists($tok->{'missing'});
 
# Get page text
my $intxt=$tok->{'revisions'}[0]{'slots'}{'main'}{'*'};
 
# First, find the template and pull out the relevant parameter
my @from=();
$selfapi->process_templates($intxt, sub {
return undef unless exists($templates{'Template:'.$_[0]});
my $f=undef;
foreach ($selfapi->process_paramlist(@{$_[1]})){
($f=$_->{'value'})=~s/^\s+|\s+$//g if $_->{'name'} eq 1;
}
Line 156 ⟶ 163:
$res=$api->query(titles => join('|',@f), redirects=>1);
if($res->{'code'} ne 'success'){
$selfapi->warn("Failed to retrieve mergefrom page list for $title: ".$res->{'error'}."\n");
$ret=60;
last MAINLOOP;
Line 163 ⟶ 170:
foreach (@{$res->{'query'}{'redirects'}}){
my ($f,$t)=($_->{'from'}, $_->{'to'});
if($t eq $subject || $t eq $rsubject){
$f=$norm{$f} if exists($norm{$f});
$remove{$f}=1;
} elsif($subject ne $rsubject){
$redirected{"$f>$rsubject>$t"}="| {{$linktmpl|$f}} || {{$linktmpl|$subject}}<br />→ {{$linktmpl|$rsubject}} || {{$linktmpl|$t}} || ";
} else {
$redirected{"$f>$subject>$t"}="| [[:{{$linktmpl|$f]]}} || [[:{{$linktmpl|$subject]]}} || [[:{{$linktmpl|$t]]}} || \n";
}
}
Line 176 ⟶ 185:
my $f=$_->{'title'};
$f=$norm{$f} if exists($norm{$f});
$remove{exists($norm{$f})?$norm{$f}:$f}=12;
$deleted{"$f>$subject"}="| [[:{{$linktmpl|$f]]}} || [[:{{$linktmpl|$subject]]}} || \n";
}
}
 
# Remove the removable templates
my $outtxt=$selfapi->process_templates($intxt, sub {
returnmy undef unless exists($templates{'Template:'.$_[0]})name=shift;
my @params=@{shift()};
shift; # $wikitext
shift; # $data
my $oname=shift;
 
return undef unless exists($templates{'Template:'.$name});
my $f=undef;
foreach ($selfapi->process_paramlist(@{$_[1]}params)){
($f=$_->{'value'})=~s/^\s+|\s+$//g if $_->{'name'} eq 1;
}
return undef unless exists($remove{$f})?'':undef;
return '' if $remove{$f}==2;
$oname=~s/_/ /g;
$oname=~s/^(\s*)\S(?:.*\S)?(\s*)$/${1}afd-merged-from$2/is;
return "{{$oname|".join("|",@params)."}}";
});
 
Line 194 ⟶ 213:
if($outtxt ne $intxt){
my $summary="Removing obsolete {{$template}}";
$selfapi->warnlog("$summary in $title\n");
my $r=$api->edit($tok, $outtxt, $summary.$screwup, 1, 1);
if($r->{'code'} ne 'success'){
$selfapi->warn("Write failed on $title: ".$r->{'error'}."\n");
next;
}
Line 205 ⟶ 224:
}
 
if($ret==21600){ # No error above
my $tok=$api->edittoken($report);
if( my $tok=$api->{'code'} eq 'shutoff'edittoken($report){;
$self->warnif("Task disabled: ".$tok->{'contentcode'}."\n" eq 'shutoff');{
$api->warn("Task disabled: ".$tok->{'content'}."\n");
return 300;
}
}
if($tok->{'code'} ne 'success'){
$selfapi->warn("Failed to get edit token for $report: ".$tok->{'error'}."\n");
$ret=60;
last;
}
my $intxt=exists($tok->{'revisions'}[0]{'*slots'})?$tok->{'revisionsmain'}[0]{'*'}: // '';
foreach my $s (split(/(?=(?:^|\n)==)/, $intxt)){
if($s=~/^\n?==\s*Redirected\s*==/){
foreach (split $s=~s/\n/, |}.*$//s){;
nextforeach unless(split /^\| \[\[:([^]]+)\]\] n\|-\|n/, \[\[:([^]]+$s)\]\] \|\| \[\[:([^]]+)\]\] \|\|/;{
next unless exists($redirected{"$1>$2> s/[\r\n]\s*$3"})//;
next unless /^\Q| {{$linktmpl|\E([^]]+)\Q}} || {{$linktmpl|\E([^]]+)\Q}} || {{$linktmpl|\E([^]]+)\Q}} ||/;
$redirected{"$1>$2>$3"}=$_;
next unless exists($redirected{"$1>$2>$3"});
$redirected{"$1>$2>$3"}=$_;
} elsif(/^==\s*Deleted\s*==/){
foreach (split /\n/, $s){ }
} next unless elsif($s=~/^\| n?==\[s*Deleted\[:([^]]+s*==/)\]\] \|\| \[\[:([^]]+)\]\] \|\|/;{
$deleted{"$1>$2"s=~s/\|}=.*$_//s;
foreach (split /\n\|-\n/, $s){
list => 'backlinks',s/[\r\n]\s*$//;
next unless /^\Q| {{$linktmpl|\E([^]]+)\Q}} || {{$linktmpl|\E([^]]+)\Q}} ||/;
$deleted{"$1>$2"}=$_;
}
}
}
my $outtxt="== Redirected ==\n";
}
$outtxt.="The following table lists pages referred to by {{tl|afd-mergefrommerge from}} are redirects to some page other than that with the {{tl|afd-mergefrommerge from}}. Please correct the {{tl|afd-mergefrommerge from}}, either by removing it (if the page was correctly merged elsewhere), undoing the incorrect redirection, or pointing it to the correct page. This table will be updated automatically.\n\n";
my $outtxt="== Redirected ==\n";
$outtxt.="{| class=\"wikitable sortable\"\n";
$outtxt.="The following table lists pages referred to by {{tl|afd-mergefrom}} are redirects to some page other than that with the {{tl|afd-mergefrom}}. Please correct the {{tl|afd-mergefrom}}, either by removing it (if the page was correctly merged elsewhere), undoing the incorrect redirection, or pointing it to the correct page. This table will be updated automatically.\n\n";
$outtxt.="{|! class=\"wikitablePage sortable\"!! AFD merge to !! Redirect to !! Note\n";
$outtxt.="! Page !! AFD merge to !! Redirect to !! Note|-\n";
$outtxt.=join("\n|-\n", sort values %redirected);
$outtxt.=join("\n|-}\n\n", sort values %redirected);
$outtxt.="|}\n== Deleted ==\n";
$outtxt.="The following table lists deleted pages that were referred to by {{tl|afd-mergefrommerge from}}; the offending {{tl|afd-mergefrommerge from}} has already been removed. Please double-check whether the deletion was correct. If so, just remove the row from the table; if not, undelete the page and restore the {{tl|afd-mergefrommerge from}}. This table will '''not''' be updated automatically.\n\n";
$outtxt.="== Deleted ==\n";
$outtxt.="{| class=\"wikitable sortable\"\n";
$outtxt.="The following table lists deleted pages that were referred to by {{tl|afd-mergefrom}}; the offending {{tl|afd-mergefrom}} has already been removed. Please double-check whether the deletion was correct. If so, just remove the row from the table; if not, undelete the page and restore the {{tl|afd-mergefrom}}. This table will '''not''' be updated automatically.\n\n";
$outtxt.="{|! class=\"wikitablePage sortable\"!! AFD merge to !! Note\n";
$outtxt.="! Page !! AFD merge to !! Note|-\n";
$outtxt.=join("\n|-\n", sort values %deleted);
$outtxt.=join("\n|-}\n\n", sort values %deleted);
$outtxt.="|}\n\n";
 
if($outtxt ne $intxt){
my $summary="Updating list of non-matching merges";
$selfapi->warnlog("$summary in $report\n");
my $r=$api->edit($tok, $outtxt, $summary.$screwup, 1, 1);
if($r->{'code'} ne 'success'){
$selfapi->warn("Write failed on $report: ".$r->{'error'}."\n");
$ret=60;
); }
}
}
Line 257 ⟶ 282:
$starttime+=$ret;
$self->{'nextrun'}=$starttime;
$api->store(->{'nextrun', \}=$starttime);
 
return $ret;
Line 264 ⟶ 289:
1;
 
</syntaxhighlight>
</source>