User:AnomieBOT/source/tasks/PERTableUpdater.pm: Difference between revisions

Content deleted Content added
Fixed typo
AnomieBOT (talk | contribs)
Updating published sources: PERTableUpdater: * Use {{tl|v}} to generate view and history links.
 
(17 intermediate revisions by 3 users not shown)
Line 1:
{{ombox|type=notice|text= 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.}}
<syntaxhighlight lang="perl">
package tasks::PERTableUpdater;
Line 14:
 
Update [[User:AnomieBOT/PERTable]], [[User:AnomieBOT/TPERTable]],
[[User:AnomieBOT/EPERTable]], [[User:AnomieBOT/SPERTable]], and
[[User:AnomieBOT/EDITREQTableCOIREQTable]], and [[User:AnomieBOT/PREQTable]].
 
=end metadata
Line 31:
@ISA=qw/AnomieBOT::Task/;
 
my %colors=(
'red' => ' style="background-color:#ffbfdc"',
'yellow' => ' style="background-color:#fff9bf"',
'green' => ' style="background-color:#e4ffcc"',
'clear' => '',
);
my %protact=(
'modify' => 'Modified',
Line 82 ⟶ 76:
}
if(($api->store->{"ver"}//1) < 2){
for my $tag (qw/PER TPER SPER EDITREQ/) {
next unless exists($api->store->{"$tag pages"});
my %old = %{$api->store->{"$tag pages"}};
Line 92 ⟶ 86:
}
$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 114 ⟶ 116:
return 60;
}
my $ln = 0;
for my $line (split /\r?\n/, $tb->{'content'}){
$ln++;
my $re=$line;
my %opts=();
Line 133 ⟶ 137:
 
$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 ( $@ ) {
$apiself->warnwarnBadRegex( $api, "$page:$ln: Ignoring bad regex '$re' in: $page@\n");
next;
}
 
# Log non-fatal warnings too.
eval {
use warnings FATAL => 'all';
qr/^(?:$re)$/si;
};
if ( $@ ) {
$self->warnBadRegex( $api, "$page:$ln: Warning: $@\n");
}
 
Line 155 ⟶ 175:
 
# Fields are:
# 0: Namespaces to color green"attention" instead of clear"normal"
# 1: "Tag", also used in the name of the subpage the table is put on
# 2: Category name, no prefix
Line 161 ⟶ 181:
# 4: URL fragment for request links
# 5: NID component of the urn links
# 6: List of colorscolor-classes to apply based on page protection level:
# 0: unprotected
# 1: semi-protected
Line 167 ⟶ 187:
# 3: extended-confirmed protected
# 4: template protected
# 5: User CSS/JSJSON page
# 6: fullyUser protectedCSS/JS page
# 7: fully protected
# 8: "fully" protected via title blacklist
# 89: cascading protection
# 910: 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/rederror error error rederror rederror rednormal rederror yellownormal clearcaution yellowcaution yellowcaution yellowerror/]],
[[10,828],'TPER','Wikipedia template-protected edit requests','template-protected','edittemplateprotected','x-wp-edittemplateprotected',[qw/rederror rederror rederror rederror clearnormal rederror rederror yellowerror redcaution rederror error error/]],
[[10,828],'EPER','Wikipedia extended-confirmed-protected edit requests','extended-confirmed-protected','editextendedprotected','x-wp-editextendedprotected',[qw/rederror rederror rederror clearnormal rederror rederror rederror rederror rederror rederror error error/]],
[[10,828],'SPER','Wikipedia semi-protected edit requests','semi-protected','editsemiprotected','x-wp-editsemiprotected',[qw/rederror clearnormal yellowcaution rederror rederror rederror rederror rederror rederror rederror error error/]],
[[0],'EDITREQIPER','RequestedWikipedia editsinterface-protected edit requests','COIinterface-protected','requestediteditinterfaceprotected','x-wp-requestediteditinterfaceprotected',[qw/clearerror error error error yellowerror yellowerror rednormal rederror rederror rederror rederror rednormal/]],
[[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 ($greennsattentionns,$tag,$cat,$type,$tgt,$urn,$colors)=@$data;
my $iter=$api->iterator(
generator => 'categorymembers',
Line 226 ⟶ 250:
touched => ISO2timestamp($p->{'touched'}),
});
$pages{$t}{$tt}{'reqisredir'} = defined( $p->{'redirect'} );
delete $pages{$t}{$tt}{'color'};
delete $pages{$t}{$tt}{'prottype'};
Line 251 ⟶ 276:
 
# Protection scoring "bitmap":
# 0x4000x8000 = MediaWiki-namespace CSS/JS auto-protection
# 0x2000x4000 = CascadingMediaWiki-namespace auto-protection
# 0x1000x2000 = FullCascading protection
# 0x800x1000 = User scriptFull auto-protection
# 0x400x100 = TemplateUser script auto-protection
# 0x20 0x80 = Extended-confirmedUser JSON auto-protection
# 0x10 0x40 = SemiTemplate-protection
# 0x08 0x20 = DirectlyExtended-appliedconfirmed protection
# 0x02 0x10 = Title blacklist 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$!)){
$pd->{'prottype'}='Site JS page';
$protscore=0xc000;
} elsif($p->{'ns'}==8 && ($p->{'contentmodel'} eq 'css' || $t=~m!\.css$!)){
$pd->{'prottype'}='Site CSS page';
$protscore=0xc000;
} elsif($p->{'ns'}==8){
$pd->{'prottype'}='MediaWiki page';
$protscore=0x4000x4000;
} elsif($p->{'ns'}==2 && ($p->{'contentmodel'} eq 'javascript' || $t=~m!/.*\.js$!)){
$pd->{'prottype'}='User JS page';
$protscore=0x800x100;
} elsif($p->{'ns'}==2 && ($p->{'contentmodel'} eq 'css' || $t=~m!/.*\.css$!)){
$pd->{'prottype'}='User CSS page';
$protscore=0x100;
} elsif($p->{'ns'}==2 && ($p->{'contentmodel'} eq 'json' || $t=~m!/.*\.json$!)){
$pd->{'prottype'}='User JSON page';
$protscore=0x80;
}
Line 287 ⟶ 323:
$pd->{'prottype'}=$tb->{'source'};
my $line=$tb->{'line'};
$pd->{'reason'}=qq(Matching line: <syntaxhighlight lang="text" enclose="none"inline>$line</syntax).qq(highlight>);
$protscore=$sc;
}
Line 297 ⟶ 333:
next unless $pp->{'type'} eq $prottype;
my $sc=0;
$sc|=0x1000x1000 if $pp->{'level'} eq 'sysop';
$sc|=0x40 if $pp->{'level'} eq 'templateeditor';
$sc|=0x20 if $pp->{'level'} eq 'extendedconfirmed';
$sc|=0x10 if $pp->{'level'} eq 'autoconfirmed';
$sc|=exists($pp->{'source'})?0x2000x2000:0x08;
$sc|=0x2000x2000 if exists($pp->{'cascade'});
next if $sc<$protscore;
if(exists($pp->{'source'})){
Line 328 ⟶ 364:
if($protscore & 0x40){
$pd->{'color'}=$colors->[4] if($protscore & 0x40);
$pd->{'color'}=$colors->[78] if($protscore & 0x02);
}
$pd->{'color'}=$colors->[5] if($protscore & 0x80);
$pd->{'color'}=$colors->[6] if($protscore & 0x100);
$pd->{'color'}=$colors->[87] if($protscore & 0x2000x1000);
$pd->{'color'}=$colors->[9] if($protscore & 0x4000x2000);
$pd->{'color'}='green'$colors->[10] if($pd->{'color'} eq 'clear'protscore && grep($p->{'ns'}==$_, @$greenns)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 367 ⟶ 405:
}
$pd->{'logtitle'}=$pg;
$pd->{'isredir'}=defined( $p->{'redirect'} );
 
# now fill in the rest
Line 378 ⟶ 417:
# The formatting here is a little strange, for backwards compat
my @pages=map { values %$_ } values %pages;
my $txt = qq(<div class="veblenbot-pertable"noinclude>{{User:AnomieBOT/PERTableHeader}}</noinclude>\n);
$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 384 ⟶ 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]] <div {{v|$pg|h|style="float:right;white-space:nowrap">[[$pg|v]]&middot;<span class="plainlinks">[//en.wikipedia.org/w/index.php?title=$pg&action=history h]</span></div>}}\n);
$txt.=qq(|-\n);
$txt.=qq(|\n);
Line 393 ⟶ 434:
$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=$colors{$p->{'color'}};
my $t=$p->{'title'};
my $et=encodetitle($p->{'logtitle'});
Line 399 ⟶ 440:
my $pt=$p->{'prottype'};
my $r=$p->{'reason'};
my $txt.tl =qq(| $p->{'isredir'} ? "{{-r|1=$t}}" : "[[:$c\n)t]]";
my $txt.ttl =qq( $p->{'reqisredir'} ? "{{-r|1=$tt#$tgt|2=request}}" [[:$t]] ("[[$tt#$tgt|request]])\n)";
$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 419 ⟶ 462:
next;
}
my $intxt=$tok->{'revisions'}[0]{'slots'}{'main'}{'*'}//'';
$intxt=~s/^\s+|\s+$//;
$intxt=~s#<!--TS-->.*<!--/TS-->#<!--TS-->~~~~~<!--/TS-->#g;
Line 434 ⟶ 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" );
}