User:AnomieBOT/source/tasks/TemplateReplacer12.pm
Appearance
Due to breaking changes in AnomieBOT::API, this task will probably not run anymore. If you really must run it, try getting a version from before 2009-03-23. |
Approved 2009-01-16, Completed 2009-01-19 Wikipedia:Bots/Requests for approval/AnomieBOT 23 |
package tasks::TemplateReplacer12;
=pod
=for warning
Due to breaking changes in AnomieBOT::API, this task will probably not run
anymore. If you really must run it, try getting a version from before
2009-03-23.
=begin metadata
Bot: AnomieBOT
Task: TemplateReplacer12
BRFA: Wikipedia:Bots/Requests for approval/AnomieBOT 23
Status: Completed 2009-01-19
Created: 2009-01-15
Replace {{tlx|Film needs cast section}}, {{tlx|Filmimage}}, and {{tlx|Film
needs synopsis}} (and redirects) with {{tlx|Film}} with appropriate needs-X
parameters. Also, perform some cleanup to {{tlx|Film}} on pages edited for this
reason.
=end metadata
=cut
use utf8;
use strict;
use AnomieBOT::Task;
use vars qw/@ISA/;
@ISA=qw/AnomieBOT::Task/;
sub new {
my $class=shift;
my $self=$class->SUPER::new();
bless $self, $class;
return $self;
}
=pod
=for info
Approved 2009-01-16, Completed 2009-01-19<br />[[Wikipedia:Bots/Requests for approval/AnomieBOT 23]]
=cut
sub approved {
return -1;
}
sub run {
my ($self, $api)=@_;
my $res;
$api->task('TemplateReplacer12');
$api->read_throttle(0);
$api->edit_throttle(10);
# List of templates to replace in this task
my %tf=(
'Film needs cast section' => 'needs-cast',
'Filmimage' => 'needs-image',
'Film needs synopsis' => 'needs-synopsis',
);
my @templates=keys %tf;
my $req="[[WP:BOTREQ#More .7B.7BFilm.7D.7D cleanup|request]]";
# Spend a max of 5 minutes on this task before restarting
my $endtime=time()+300;
# Get a list of templates redirecting to our targets
my %templates=();
foreach my $template (@templates){
$templates{"Template:$template"}=$tf{$template};
$res=$api->query([],
list => 'backlinks',
bltitle => "Template:$template",
blfilterredir => 'redirects',
bllimit => 'max',
);
$templates{$_->{'title'}}=$tf{$template} foreach (@{$res->{'query'}{'backlinks'}});
}
# Before starting, get the list of alternate names for our target
my %WPF=('Template:Film'=>1);
$res=$api->query([],
list => 'backlinks',
bltitle => 'Template:Film',
blfilterredir => 'redirects',
bllimit => 'max',
);
$WPF{$_->{'title'}}=1 foreach (@{$res->{'query'}{'backlinks'}});
delete $WPF{$_} foreach (values %templates);
# Also, get redirects to WikiProjectBanners and WikiProjectBannerShell, for
# renumbering if necessary
my %WPB=();
my %B=('Template:WikiProjectBanners'=>1,'Template:WikiProjectBannerShell'=>2);
while(my ($t,$c)=each %B){
$WPB{$t}=$c;
$res=$api->query([],
list => 'backlinks',
bltitle => $t,
blfilterredir => 'redirects',
bllimit => 'max',
);
if($res->{'code'} ne 'success'){
$self->warn("Failed to retrieve redirect list for $t: ".$res->{'error'}."\n");
return 60;
}
$WPB{$_->{'title'}}=$c foreach (@{$res->{'query'}{'backlinks'}});
}
foreach my $template (@templates){
# Get the list of pages to check
my %q=(
list => 'embeddedin',
eititle => "Template:$template",
eilimit => 'max',
);
do {
$res=$api->query(%q);
if($res->{'code'} ne 'success'){
$self->warn("Failed to retrieve transclusion list for $template: ".$res->{'error'}."\n");
return 60;
}
if(exists($res->{'query-continue'})){
$q{'eicontinue'}=$res->{'query-continue'}{'embeddedin'}{'eicontinue'};
} else {
delete $q{'eicontinue'};
}
# Process found pages
foreach (@{$res->{'query'}{'embeddedin'}}){
my $title=$_->{'title'};
$self->warn("Checking for $template in $title\n");
# WTF?
if(exists($_->{'missing'})){
$self->warn("$title is missing? WTF?\n");
next;
}
# Ok, check the page
my $tok=$api->edittoken($title);
if($tok->{'code'} eq 'shutoff'){
$self->warn("Task disabled: ".$tok->{'content'}."\n");
return 300;
}
if($tok->{'code'} ne 'success'){
$self->warn("Failed to get edit token for $title: ".$tok->{'error'}."\n");
next;
}
next if exists($tok->{'missing'});
# Get page text
my $intxt=$tok->{'revisions'}[0]{'*'};
# First step is to determine if the replacement is already on
# the page.
my $has_WPF=0;
my %tf=();
$self->process_templates($intxt, sub {
$has_WPF=1 if exists($WPF{'Template:'.$_[0]});
return undef unless exists($templates{'Template:'.$_[0]});
$tf{$templates{'Template:'.$_[0]}}='{{'.$_[0].'}}';
return undef;
});
# Now, we actually perform the replacement
my @a=values %tf;
$a[-1]='and '.$a[-1] if @a>1;
my $summary="Replacing ".join((@a>2)?', ':' ', @a)." with {{Film|".join("=yes|",keys %tf)."=yes}} (and removing unused parameters) per $req";
my $outtxt=$self->process_templates($intxt, sub {
my $name=shift;
my @params=@{shift()};
shift; # $wikitext
shift; # $data
my $oname=shift;
if(exists($templates{"Template:$name"})){
return '' if $has_WPF;
$has_WPF=1;
$oname=~s/\Q$name\E/Film/i;
$name='Film';
}
return undef unless exists($WPF{"Template:$name"});
# We have the replacement template now, either by finding
# the existing one or by replacing the target template if
# none was already present. Now, set the various need-X
# parameters.
foreach (keys %tf){
@params=grep(!/^\s*\Q$_\E\s*=\s*$/, @params);
push @params, "$_=yes" if(!grep(/^\s*\Q$_\E\s*=/, @params));
}
# Since we're here anyway, clean up the Film parameters.
@params=grep(!/^\s*(?:importance|attention|auto|portal[12345]-name)\s*=/, @params);
my $n='Film';
$oname=~s/^(\s*)\S(?:.*\S)?(\s*)$/$1$n$2/s;
# Ok, return the new template code now.
return "{{$oname|".join("|", @params)."}}";
});
# Need to edit?
if($outtxt ne $intxt){
# Post-process to fix
# WikiProjectBanners/WikiProjectBannerShell numbering.
$outtxt=$self->process_templates($outtxt, sub {
my $name=shift;
my @params=@{shift()};
shift; # $wikitext
shift; # $data
my $oname=shift;
return undef unless exists($WPB{"Template:$name"});
my @p_name=();
my @p_num=();
foreach ($self->process_paramlist(@params)){
if($_->{'name'}=~/^\d+$/){
push @p_num, $_->{'value'} unless $_->{'value'}=~/^\s*$/;
} else {
push @p_name, $_->{'text'};
}
}
for(my $i=0; $i<@p_num; $i++){
push @p_name, ($i+1).'='.$p_num[$i];
}
return "{{$oname|".join("|", @p_name)."}}";
});
$self->warn("$summary in $title\n");
my $r=$api->edit($tok, $outtxt, $summary, 1, 1);
if($r->{'code'} ne 'success'){
$self->warn("Write failed on $title: ".$r->{'error'}."\n");
next;
}
} else {
$self->warn("Nothing to do in $title\n");
}
# If we've been at it long enough, let another task have a go.
return 0 if time()>=$endtime;
}
} while(exists($q{'eicontinue'}));
}
# No more pages to check, try again in 10 minutes or so in case of errors.
return 600;
}
1;