Content deleted Content added
Updating published sources: PERTableUpdater: * Handle multiple requests (on different talk pages) pointing to the same target page. * As a side effect, that fixes the problem where the request link is wrong if the request gets archived. |
Updating published sources: PERTableUpdater: * Use {{tl|v}} to generate view and history links. |
||
(29 intermediate revisions by 4 users not shown) | |||
Line 14:
Update [[User:AnomieBOT/PERTable]], [[User:AnomieBOT/TPERTable]],
[[User:AnomieBOT/
[[User:AnomieBOT/COIREQTable]], and [[User:AnomieBOT/PREQTable]].
=end metadata
Line 30 ⟶ 31:
@ISA=qw/AnomieBOT::Task/;
my %protact=(
'modify' => 'Modified',
Line 81 ⟶ 76:
}
if(($api->store->{"ver"}//1) < 2){
for my $tag (qw/PER TPER SPER
next unless exists($api->store->{"$tag pages"});
my %old = %{$api->store->{"$tag pages"}};
my %new = ();
while(my ($k,$v) = each %old) {
$new{$k}{$v->{'talk'}} = $v if exists($v->{'talk'});
}
$api->store->{"$tag pages"} = \%new;
}
$api->store->{"ver"} = 2;
}
# Flush warnings daily
my $ts = time;
$ts -= $ts % 86400;
if ( ($api->store->{'warnedBadRegexDate'} // 0) < $ts) {
$api->store->{'warnedBadRegex'} = {};
$api->store->{'warnedBadRegexDate'} = $ts;
}
Line 103 ⟶ 106:
for my $source (@sources) {
my ($i, $name, $page) = @$source;
my $tb
if ( $page=~/^meta:(.+)$/ ) {
$tb=$api->copy( wikibase => 'https://meta.wikimedia.org/w/', assert => 'user' )->rawpage( $1 );
} else {
$tb=$api->rawpage($page);
}
if($tb->{'code'} ne 'success'){
$api->warn("Failed to load $page: ".$tb->{'error'}."\n");
return 60;
}
my $ln = 0;
for my $line (split /\r?\n/, $tb->{'content'}){
$ln++;
my $re=$line;
my %opts=();
Line 126 ⟶ 136:
$re="(?-i:$re)" if($opts{'casesensitive'}//0);
$re=~s!(\{\{\s*ns\s*:\s*(.+?)\s*\}\})! replace_ns($api,$2) // $1 !ge;
# Try to escape left-braces that aren't quantifiers or parameters to escapes
my $tmp = $re;
$re=~s#(?<!\\[a-zA-Z])(?<!\\)\{(?!\d+(?:,\d*)?})#\\{#g;
$self->warnBadRegex( $api, "$page:$ln: Escaped left-braces in regex (old): $tmp" ) if $tmp ne $re;
$self->warnBadRegex( $api, "$page:$ln: Escaped left-braces in regex (new): $re" ) if $tmp ne $re;
# Validate each line, in case someone screws up the blacklist page
eval {
no warnings;
qr/^(?:$re)$/si;
};
if ( $@ ) {
$self->warnBadRegex( $api, "$page:$ln: Ignoring bad regex '$re': $@\n");
next;
}
# Log non-fatal warnings too.
eval {
use warnings FATAL => 'all';
qr/^(?:$re)$/si;
};
if ( $@ ) {
$self->warnBadRegex( $api, "$page:$ln: Warning: $@\n");
}
# Let's just hope no one ever uses {{int:}} here...
Line 140 ⟶ 175:
# Fields are:
# 0: Namespaces to color
# 1: "Tag", also used in the name of the subpage the table is put on
# 2: Category name, no prefix
Line 146 ⟶ 181:
# 4: URL fragment for request links
# 5: NID component of the urn links
# 6: List of
# 0: unprotected
# 1: semi-protected
# 2: semi-protected via title blacklist
# 3:
# 4:
# 5:
# 6:
# 7:
# 8:
# 9: cascading protection
# 10: MediaWiki-namespace page
# 11: MediaWiki-namespace CSS/JS page
my @data=(
[[10,828],'PER','Wikipedia fully protected edit requests','protected','editprotected','x-wp-editprotected',[qw/
[[10,828],'TPER','Wikipedia template-protected edit requests','template-protected','edittemplateprotected','x-wp-edittemplateprotected',[qw/
[[10,828],'
[[
[[],'IPER','Wikipedia interface-protected edit requests','interface-protected','editinterfaceprotected','x-wp-editinterfaceprotected',[qw/error error error error error error normal error error error error normal/]],
[[0],'COIREQ','Wikipedia conflict of interest edit requests','COI','requestedit','x-wp-requestedit',[qw/normal caution caution caution error error error error error error error error/]],
[[],'PREQ','Wikipedia partial-block edit requests','partial block','editpartiallyblocked','x-wp-editpartiallyblocked',[qw/normal caution caution caution error error error error error error error error/]],
);
my $starttime=time;
for my $data (@data){
my ($
my $iter=$api->iterator(
generator => 'categorymembers',
Line 209 ⟶ 250:
touched => ISO2timestamp($p->{'touched'}),
});
$pages{$t}{$tt}{'reqisredir'} = defined( $p->{'redirect'} );
delete $pages{$t}{$tt}{'color'};
delete $pages{$t}{$tt}{'prottype'};
Line 216 ⟶ 258:
}
$api->store->{"$tag pages"}=\%pages;
$api->store->{"ver"} = 2;
if(%pages){
Line 233 ⟶ 276:
# Protection scoring "bitmap":
#
#
#
#
#
#
#
#
# 0x10 = Semi-protection
# 0x08 = Directly-applied protection
# 0x02 = Title blacklist protection
# Highest score by int value "wins".
my $protscore=0;
$pd->{'prottype'}='Not protected';
$pd->{'reason'}='';
if($p->{'ns'}==8 && ($p->{'contentmodel'} eq 'javascript' || $t=~m!\.js$!)){
$protscore=0xc000;
} elsif($p->{'ns'}==8 && ($p->{'contentmodel'} eq 'css' || $t=~m!\.css$!)){
$protscore=0xc000;
} elsif($p->{'ns'}==8){
$pd->{'prottype'}='MediaWiki page';
$protscore=
} elsif($p->{'ns'}==2 && ($p->{'contentmodel'} eq 'javascript' || $t=~m!/.*\.js$!)){
$pd->{'prottype'}='User JS page';
$protscore=
} elsif($p->{'ns'}==2 && ($p->{'contentmodel'} eq 'css' || $t=~m!/.*\.css$!)){
$pd->{'prottype'}='User CSS page';
$protscore=
} elsif($p->{'ns'}==2 && ($p->{'contentmodel'} eq 'json' || $t=~m!/.*\.json$!)){
$pd->{'prottype'}='User JSON page';
$protscore=0x80;
}
Line 264 ⟶ 319:
}
if ( $tb && $tb->{'source'} ) {
my $sc=exists($tb->{'opts'}{'autoconfirmed'})?0x12:
next if $sc<$protscore;
$pd->{'prottype'}=$tb->{'source'};
my $line=$tb->{'line'};
$pd->{'reason'}=qq(Matching line: <syntaxhighlight lang="text"
$protscore=$sc;
}
Line 278 ⟶ 333:
next unless $pp->{'type'} eq $prottype;
my $sc=0;
$sc|=
$sc|=
$sc|=0x20 if $pp->{'level'} eq 'extendedconfirmed';
$sc|=0x10 if $pp->{'level'} eq 'autoconfirmed';
$sc|=exists($pp->{'source'})?
$sc|=
next if $sc<$protscore;
if(exists($pp->{'source'})){
Line 291 ⟶ 347:
$pd->{'prottype'}='Fully protected' if $pp->{'level'} eq 'sysop';
$pd->{'prottype'}='Template-protected' if $pp->{'level'} eq 'templateeditor';
$pd->{'prottype'}='Extended-confirmed protected' if $pp->{'level'} eq 'extendedconfirmed';
$pd->{'prottype'}='Semiprotected' if $pp->{'level'} eq 'autoconfirmed';
$pd->{'prottype'}.=' with cascading' if exists($pp->{'cascade'});
Line 305 ⟶ 362:
}
$pd->{'color'}=$colors->[3] if($protscore & 0x20);
if($protscore & 0x40){
$pd->{'color'}=$colors->[4] if($protscore & 0x40); $pd->{'color'}=$colors->[8] if($protscore &
▲ $pd->{'color'}=$colors->[5];
▲ $pd->{'color'}=$colors->[6] if($protscore & 0x02);
}
$pd->{'color'}=$colors->[
$pd->{'color'}=$colors->[
$pd->{'color'}=
$pd->{'color'}=$colors->[9] if($protscore & 0x2000);
$pd->{'color'}=$colors->[10] if($protscore & 0x4000);
$pd->{'color'}=$colors->[11] if($protscore & 0x8000);
$pd->{'color'}='attention' if($pd->{'color'} eq 'normal' && grep($p->{'ns'}==$_, @$attentionns));
if($pd->{'reason'} eq ''){
Line 327 ⟶ 387:
}
if($le->{'action'} eq 'move_prot'){
$from="From [[:".$le->{'
$iter=$api->iterator(
list => 'logevents',
letype => 'protect',
letitle => $le->{'
lestart => $le->{'timestamp'},
);
Line 345 ⟶ 405:
}
$pd->{'logtitle'}=$pg;
$pd->{'isredir'}=defined( $p->{'redirect'} );
# now fill in the rest
Line 356 ⟶ 417:
# The formatting here is a little strange, for backwards compat
my @pages=map { values %$_ } values %pages;
my $txt = qq(<
$txt.=qq(<div class="veblenbot-pertable">\n);
$txt.=qq(<templatestyles src="Template:Edit_fully-protected/color_legend/styles.css"/>\n);
$txt.=qq({| class="wikitable" style="padding:0em"\n);
$txt.=qq(|-\n);
Line 362 ⟶ 425:
my $s=($ct==1?'':'s');
my $pg='User:AnomieBOT/'.$tag.'Table';
$txt.=qq(! <section begin="count" />$ct<section end="count" /> [[:Category:$cat|$type edit request$s]]
$txt.=qq(|-\n);
$txt.=qq(|\n);
Line 370 ⟶ 433:
$txt.=qq(! Protection level\n);
$txt.=qq(! class = "unsortable" | Last protection log entry\n);
for my $p (sort { my $x = $a->{'touched'} <=> $b->{'touched'}; $x = $a->{'title'} cmp $b->{'title'} if $x == 0; return $x; } @pages){
my $c=
my $t=$p->{'title'};
my $et=encodetitle($p->{'logtitle'});
Line 377 ⟶ 440:
my $pt=$p->{'prottype'};
my $r=$p->{'reason'};
my $
my $
$txt.=qq(|- class="protectededit-legend-$c"\n);
$txt.=qq(| $tl ($ttl)\n);
$txt.=strftime("| %F %H:%M\n", gmtime $p->{'touched'});
$txt.=qq(| $pt <span class="plainlinks">([//en.wikipedia.org/w/index.php?title=Special:Log&type=protect&page=$et log])</span>\n);
Line 397 ⟶ 462:
next;
}
my $intxt=$tok->{'revisions'}[0]{'slots'}{'main'}{'*'}//'';
$intxt=~s/^\s+|\s+$//;
$intxt=~s#<!--TS-->.*<!--/TS-->#<!--TS-->~~~~~<!--/TS-->#g;
Line 412 ⟶ 477:
$t=0 if $t<0;
return $t;
}
sub warnBadRegex {
my ($self, $api, $msg) = @_;
$msg =~ s/\s+$//;
my $file = __FILE__;
$msg =~ s/ at \Q$file\E line \d+\.$//;
if ( ! defined( $api->{'noedit'} ) ) {
my $warned = $api->store->{'warnedBadRegex'};
return if exists( $warned->{$msg} );
$warned->{$msg} = 1;
$api->store->{'warnedBadRegex'} = $warned;
}
$api->warn( "$msg\n" );
}
|