Content deleted Content added
Updating published sources: General: * New task, OnThisDayTagger. AnomieBOT::API: * Error message when setting a non-numeric debug bitmask. |
Updating published sources: OnThisDayTagger: * Don't skip "1" for {{tl|ArticleHistory}}. |
||
(26 intermediate revisions by the same user not shown) | |||
Line 1:
{{ombox|type=notice|text=
<
package tasks::OnThisDayTagger;
Line 7:
=begin metadata
Bot: AnomieBOT
Task: OnThisDayTagger
BRFA: Wikipedia:Bots/Requests for approval/AnomieBOT 30
Status:
Created: 2009-05-14
Line 25:
use strict;
use AnomieBOT::Task qw/:time/;
use Data::Dumper;
use POSIX;
Line 31:
use vars qw/@ISA/;
@ISA=qw/AnomieBOT::Task/;
my @months=qw/January February March April May June July August September October November December/;
my $monthre="(?:".join("|",@months).")";
my $skip_links_re=join('|',
"$monthre \\d{1,2}",
'\d{4}',
'List of historical anniversaries',
'List of days of the year',
);
$skip_links_re=qr/^(?:$skip_links_re)$/;
Line 45 ⟶ 49:
my $whine_to='User talk:AnomieBOT';
my $mode='
my $list='/tmp/otd-pages.txt';
Line 51 ⟶ 55:
my $class=shift;
my $self=$class->SUPER::new();
$self->{'order'}=100;
$self->{'nextday'}=0;
bless $self, $class;
return $self;
Line 60 ⟶ 64:
=for info
=cut
sub approved {
return
}
Line 74 ⟶ 78:
$api->task('OnThisDayTagger', 0, 10, qw/d::Talk d::Timestamp d::Templates d::Redirects/);
my $screwup=' Errors? [[User:'.$api->user.'/shutoff/OnThisDayTagger]]';
$api->store->{'nextday'}=5643 unless exists($api->store->{'nextday'});
my $starttime=time;
my $today=day_from_timestamp($starttime);
if($mode eq 'list'){
Line 86 ⟶ 91:
for(my $d=1; $d<=31; $d++){
my $md=sprintf("%02d-%02d",$m,$d);
next unless
my $res=$api->query([],
titles =>
prop => 'revisions',
rvprop => 'ids|timestamp',
Line 172 ⟶ 177:
}
my $
my $
$res=$api->edit($tok, $outtxt, "Adding/updating {{OnThisDay}}. $screwup", 0, 1);
$api->warn("Write failed on $title: $res->{error}\n");
sleep(10);
redo;
}
}
}
close X;
return undef;
}
Line 193 ⟶ 203:
while($self->{'nextday'}<$today){
# First, create the categories if they don't already exist
my $tok=$api->edittoken(day("Category:Selected anniversaries (%Y)", $self->{'nextday'}), EditRedir=>1);
if($tok->{'code'} eq 'shutoff'){
$api->warn("Task disabled: ".$tok->{'content'}."\n");
return 300;
}
if($tok->{'code'} ne 'success'){
$api->warn("Failed to get edit token for year category: ".$tok->{'error'}."\n");
} elsif(exists($tok->{'missing'})){
$api->edit($tok, "[[Category:Selected anniversaries]]", "Creating dated subcategory, to prevent redlinks. $screwup", 0, 1);
}
$tok=$api->edittoken(day("Category:Selected anniversaries (%B %Y)", $self->{'nextday'}), EditRedir=>1);
if($tok->{'code'} eq 'shutoff'){
$api->warn("Task disabled: ".$tok->{'content'}."\n");
return 300;
}
if($tok->{'code'} ne 'success'){
$api->warn("Failed to get edit token for month category: ".$tok->{'error'}."\n");
} elsif(exists($tok->{'missing'})){
my $y=day("%Y", $self->{'nextday'});
my $m=day("%m", $self->{'nextday'});
$api->edit($tok, "[[Category:Selected anniversaries ($y)|0$m]]", "Creating dated subcategory, to prevent redlinks. $screwup", 0, 1);
}
# Load day page
my $day=$self->{'nextday'};
my $fday=day("%F", $self->{'nextday'});
Line 208 ⟶ 243:
# Strip out non-rendered content
my ($txt, $nowiki)=$api->strip_nowiki($page->{'revisions'}[0]{'slots'}{'main'}{'*'});
while(my ($k,$v)=each %$nowiki){
$nowiki->{$k}='' if $v=~/^<!--/;
}
$txt=$1 if $txt=~m!<onlyinclude>(.*?)</onlyinclude>!s;
$txt=~s!<noinclude>(.*?)</noinclude>!!
$txt=~s!</?includeonly>!!g;
# Replace time-varying templates
$txt=~s/\{\{IsLeapYear\}\}/{{IsLeapYear|{{CURRENTYEAR}}}}/g;
my $x=day("%-d", $self->{'nextday'});
$txt=~s/\{\{CURRENTDAY\}\}/$x/g;
$x=day("%w", $self->{'nextday'});
$txt=~s/\{\{CURRENTDOW\}\}/$x/g;
$x=day("%m", $self->{'nextday'});
$txt=~s/\{\{CURRENTMONTH\}\}/$x/g;
$x=day("%Y", $self->{'nextday'});
$txt=~s/\{\{CURRENTYEAR\}\}/$x/g;
$txt=$api->replace_nowiki($txt, $nowiki);
Line 234 ⟶ 269:
title => $page->{'title'},
text => $txt,
prop => 'wikitext',
);
if($res->{'code'} eq 'shutoff'){
Line 246 ⟶ 282:
# Transform ''' to <b>
$txt=doAllQuotes($api, $res->{'expandtemplates'}{'
# Extract just the bold parts
Line 296 ⟶ 332:
my %pages=map { $_->{'title'}=>$_ } values %{$res->{'query'}{'pages'}};
foreach my $l (@l){
my $t=$api->apply_redirect_map( $l, \%map );
if(!exists($pages{$t})){
$api->warn("No result for $l ".day("(%F)", $day)."\n");
Line 319 ⟶ 354:
# Tag the talk pages
foreach my $
my $title="Talk:$
$api->log("Tagging $title for ".day("%F", $day));
my $tok=$api->edittoken("$title", EditRedirect => 1);
Line 326 ⟶ 361:
$api->warn("Task disabled: ".$tok->{'content'}."\n");
return 300;
} elsif($tok->{'code'} eq 'botexcluded'){
push @err, "* I am excluded from editing [[$title]], cannot tag for [[".join(']] / [[', @{$res{$otitle}})."]]";
next;
} elsif($tok->{'code'} ne 'success'){
$api->warn("Failed to get edit token for $title: ".$tok->{'error'}."\n");
return 60;
}
if(exists($tok->{'redirect'})){
push @err, "* [[$title]] is a redirect, cannot tag for [[".join(']] / [[', @{$res{$
next;
}
my $
my $
$res=$api->edit($tok, $outtxt, "Adding/updating {{OnThisDay}} for $fday. $screwup", 0, 1);
if($res->{'code'} ne 'success'){
$api->warn("Write failed on $title: $res->{error}\n");
return 60;
}
}
}
Line 364 ⟶ 405:
my $next=86400-($starttime%86400)-(time-$starttime);
return $next;
}
Line 371 ⟶ 413:
# The anniversary pages were created 2004-02-26 through 2004-02-28; We count
# 2004-02-26 as day 0. This function does
# Thankfully, it correctly converts
sub day {
my $fmt=shift;
my $day=shift;
return
}
Line 382 ⟶ 424:
my $ts=shift;
my ($min,$max)=(0,5000);
my $target=
while(1){
my $day=day("%F",$max);
Line 415 ⟶ 457:
my $start=$api->ISO2timestamp(day("%Y-%m-%dT00:00:00Z",$day+1));
my
titles => day("Wikipedia:Selected anniversaries/%B %-d",$day),
rvlimit => 1,
rvprop => 'ids|timestamp|content',
rvslots => 'main',
rvdir => 'older',
rvstart => $start,
prop => 'revisions',
);
while(
$page->{'code'}='success';
my $t=$api->ISO2timestamp($page->{'revisions'}[0]{'timestamp'});
Line 432 ⟶ 473:
$api->store->{"day $day"}=$page;
$api->store->{"day $day"}{'cached'}=1;
$
return $page;
}
}
}
Line 573 ⟶ 611:
my %dates=@_;
my %redir=
if(
}
my %redir2=$api->redirects_to_resolved('Template:Article history');
if(exists($redir2{''})){
$api->warn("Could not load list of redirects to Template:Article history: ".$redir2{''}{'error'}."\n");
return undef;
}
# Update an existing OnThisDay template?
my $done=0;
$txt=$api->process_templates($txt, sub {
Line 593 ⟶ 633:
return unless exists($redir{"Template:$name"});
# Read existing parameters
my %p=();
my $mx=0;
foreach (@$params){
$mx=$1 if(/^\s*(?:date|oldid)(\d+)\s*=/ && $mx < $1);
if(/^\s*(date\d+)\s*=\s*(\d{4}-\d{2}-\d{2})\s*$/){
$p{$1}=$2;
} elsif(/^\s*(date\d+)\s*=\s*((?i)$monthre)\s+(\d{1,2})(?:\s*,)?\s+(\d{4})\s*$/){
my $m; for($m=0; $m<@months; $m++){ last if lc($months[$m]) eq lc($2); }
$p{$1}=sprintf("%04d-%02d-%02d", $4, $m+1, $3);
} elsif(/^\s*(date\d+)\s*=\s*(\d{1,2})\s+((?i)$monthre)(?:\s*,)?\s+(\d{4})\s*$/){
my $m; for($m=0; $m<@months; $m++){ last if lc($months[$m]) eq lc($3); }
$p{$1}=sprintf("%04d-%02d-%02d", $4, $m+1, $2);
} elsif(/^\s*(oldid\d+)\s*=\s*(\d+)\s*$/){
$p{$1}=$2;
}
}
@$params=();
for(my $i=1; $i<=$mx; $i++){
$dates{$p{"date$i"}}=$p{"oldid$i"} if(exists($p{"date$i"}) && exists($p{"oldid$i"}) && !exists($dates{$p{"date$i"}}));
}
# (Re-)insert parameters
my $i=1;
$i++ while grep(/^\s*oldid$i\s*=/, @$params);
Line 599 ⟶ 662:
push @$params, "date$i=$date", "oldid$i=".$dates{$date};
$i++;
}
$done=1;
return "{{$oname|".join('|', @$params)."}}";
});
return $txt if $done;
# Update an existing ArticleHistory template?
$txt=$api->process_templates($txt, sub {
my $name=shift;
my $params=shift;
shift; # $wikitext
shift; # $data
my $oname=shift;
return unless exists($redir2{"Template:$name"});
# Find next unused number, and check which dates aren't already used
my %p=();
my $mx=0;
foreach (@$params){
$mx=$1 if(/^\s*otd(\d+)(?:date|oldid)\s*=/ && $mx < $1);
$mx=1 if(/^\s*otd(?:date|oldid)\s*=/ && $mx < 1);
if(/^\s*(otd\d*date)\s*=\s*(\d{4}-\d{2}-\d{2})\s*$/){
$p{$1}=$2;
} elsif(/^\s*(otd\d*date)\s*=\s*((?i)$monthre)\s+(\d{1,2})(?:\s*,)?\s+(\d{4})\s*$/){
my $m; for($m=0; $m<@months; $m++){ last if lc($months[$m]) eq lc($2); }
$p{$1}=sprintf("%04d-%02d-%02d", $4, $m+1, $3);
} elsif(/^\s*(otd\d*date)\s*=\s*(\d{1,2})\s+((?i)$monthre)(?:\s*,)?\s+(\d{4})\s*$/){
my $m; for($m=0; $m<@months; $m++){ last if lc($months[$m]) eq lc($3); }
$p{$1}=sprintf("%04d-%02d-%02d", $4, $m+1, $2);
} elsif(/^\s*(otd\d*oldid)\s*=\s*(\d+)\s*$/){
$p{$1}=$2;
}
}
# Delete any already-listed dates
delete $dates{$p{"otddate"}} if(exists($p{"otddate"}) && exists($p{"otdoldid"}) && exists($dates{$p{"otddate"}}));
for(my $i=1; $i<=$mx; $i++){
delete $dates{$p{"otd${i}date"}} if(exists($p{"otd${i}date"}) && exists($p{"otd${i}oldid"}) && exists($dates{$p{"otd${i}date"}}));
}
# Add new parameters
foreach my $date (sort keys %dates){
++$mx;
push @$params, "otd${mx}date=$date", "otd${mx}oldid=".$dates{$date}."\n";
}
$done=1;
Line 606 ⟶ 714:
if(!exists($self->{'loaded skip redirects'})){
my %skip=$api->
if(exists($skip{''})){
$api->warn("Could not load list of redirects for skip templates: ".$skip{''}{'error'}."\n");
Line 618 ⟶ 726:
my $templ='{{OnThisDay';
my $i=1;
$templ.="|date$i=$date|oldid$i=
$i++;
}
Line 640 ⟶ 748:
$wikitext=_unstrip_templates($wikitext,$data);
my $
utf8::encode( $tmp ) if utf8::is_utf8( $tmp );
my $tag="\x02".sha256_base64($tmp)."\x03";
$tag=~tr!+/=!-_!d;
$data->{$tag}=$wikitext;
Line 650 ⟶ 760:
my $templ=shift;
$wikitext=~s!(\x02[a-zA-Z0-9_-]+\x03)!
return $wikitext;
}
Line 656 ⟶ 766:
1;
</syntaxhighlight>
|