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;