![]() | Per WP:BOT#Approval, any bot or automated editing process that only
affects only the operators' user and talk pages (or subpages thereof), and which are not otherwise disruptive, may be run without prior approval. |
package tasks::WatchlistUpdater;
use strict;
use AnomieBOT::Task;
use vars qw/@ISA/;
@ISA=qw/AnomieBOT::Task/;
use POSIX qw/strftime/;
use Data::Dumper;
my %pages=(
'User:Anomie/uw-templates' => {
frequency => 12*60*60,
prefix => 'Uw-',
namespace => '10'
}
);
my $maxlen=100*1024*1024;
sub approved {
### notice type=notice
# Per [[WP:BOT#Approval]], any bot or automated editing process that only
# affects only the operators' user and talk pages (or subpages thereof),
# and which are not otherwise disruptive, may be run without prior
# approval.
return 1;
}
sub run {
my ($self, $api)=@_;
my ($k,$v,$k2,$v2,$k3,$v3,@x);
$api->task('WatchlistUpdater');
$api->read_throttle(6);
$api->edit_throttle(10);
return 300 if $self->check_shutoff($api, 'WatchlistUpdater');
if(!exists($self->{'lastrun'})){
my %lastrun=();
values(%pages);
while(($k,$v)=each(%pages)){
my $res=$api->query(
titles => $k,
prop => 'revisions',
rvuser => $api->user,
rvprop => 'timestamp',
rvlimit => 1
);
if($res->{'code'} ne 'success'){
warn "Failed to retrieve last edit date for $k, cannot run task";
return 60;
}
$res=[values(%{$res->{'query'}{'pages'}})];
if(exists($res->[0]{'revisions'}[0]{'timestamp'})){
$lastrun{$k}=$self->ISO2timestamp($res->[0]{'revisions'}[0]{'timestamp'});
} else {
$lastrun{$k}=0;
}
}
$self->{'lastrun'}=\%lastrun;
}
while(($k,$v)=each(%pages)){
next unless time()>=$self->{'lastrun'}{$k}+$v->{'frequency'};
my $starttime=strftime("%d %b %Y %T", gmtime());
my $tok=$api->edittoken($k);
if($tok->{'code'} ne 'success'){
$self->warn("Failed to retrieve edit token for $k: ".$tok->{'error'});
next;
}
if(exists($tok->{'missing'})){
$self->warn("Page $k does not exist");
next;
}
my $intxt=$tok->{'revisions'}[0]{'*'};
my $table="{| class=\"wikitable\"\n";
my %q=(
list => 'allpages',
apprefix => $v->{'prefix'},
apnamespace => $v->{'namespace'},
aplimit => 'max'
);
my $res;
do {
$res=$api->query(%q);
if($res->{'code'} ne 'success'){
$self->warn("Failed to retrieve data for $k: ".$res->{'error'});
next;
}
if(exists($res->{'query-continue'})){
$q{'apfrom'}=$res->{'query-continue'}{'allpages'}{'apfrom'};
}
foreach (@{$res->{'query'}{'allpages'}}){
if($_->{'ns'}==0){
$v2="\x5b\x5b".$_->{'title'}."\x5d\x5d";
$v3="\x5b\x5bTalk:".$_->{'title'}."\x5d\x5d";
} elsif($_->{'ns'}==1){
$v3="\x5b\x5b".$_->{'title'}."\x5d\x5d";
($v2=$v3)=~s/Talk://i;
} elsif(($_->{'ns'}&1)==0){
$v2="\x5b\x5b".$_->{'title'}."\x5d\x5d";
($v3=$v2)=~s/^([^:]+):/$1 talk:/;
} else {
$v3="\x5b\x5b".$_->{'title'}."\x5d\x5d";
($v2=$v3)=~s/ talk:/:/i;
}
$table.="|-\n|$v2 || $v3\n";
last if length($table)>$maxlen;
}
} while(length($table)<=$maxlen && exists($res->{'query-continue'}));
$table.="|}";
$table='<strong class="error">List of pages is too long</strong>' if length($table)>$maxlen;
$table=~s/\x5b\x5b(Category|Image):/\x5b\x5b:$1:/ig;
my $endtime=strftime("%d %b %Y %T", gmtime());
my ($i,$j);
$i=index($intxt,'<!-- SNIP HERE -->');
$j=index($intxt,"{| class=\"wikitable\"\n",($i<0)?0:$i);
my $t=($j<0)?'':substr($intxt,$j);
$t=~s/\s+$//;
if($t eq $table){
$self->warn("No update needed for $k\n");
$self->{'lastrun'}{$k}=time();
next;
}
my $outtxt=$intxt;
$outtxt=substr($outtxt,0,$i) if $i>=0;
$outtxt.="<!-- SNIP HERE -->\n<small>Last update happened between $starttime GMT and $endtime GMT</small>\n$table";
$res=$api->edit($tok, $outtxt, 'Updating list of watched pages', 0, 1);
if($res->{'code'} eq 'success'){
$self->warn("Updated $k\n");
$self->{'lastrun'}{$k}=time();
} else {
$self->warn("Write for $k failed: ".$res->{'error'});
}
}
my $t=864000;
while(($k,$v)=each(%pages)){
my $tt=$self->{'lastrun'}{$k}+$v->{'frequency'}-time();
$t=$tt if $tt<$t;
}
$t=300 if $t<300;
return $t;
}
1;