User:AnomieBOT/source/tasks/BadImageTagger.pm

From Wikipedia, the free encyclopedia
package tasks::BadImageTagger;

=pod

=begin metadata

Bot:     AnomieBOT
Task:    BadImageTagger
BRFA:    None
Status:  On hold
Created: 2012-03-20

Add {{tl|restricted use}} to files listed at [[MediaWiki:Bad image list]], and
remove it from files not listed at that page.

=end metadata

=cut

use utf8;
use strict;

use Data::Dumper;
use POSIX;
use Date::Parse;
use AnomieBOT::Task qw/bunchlist/;
use vars qw/@ISA/;
@ISA=qw/AnomieBOT::Task/;

sub new {
    my $class=shift;
    my $self=$class->SUPER::new();
    $self->{'next'}=0;
    bless $self, $class;
    return $self;
}

=pod

=for info
Coding pending need. Not approved yet.

=cut

sub approved {
    return 0;
}

sub run {
    my ($self, $api)=@_;
    my $res;

    $api->task('BadImageTagger', 0, 10, qw/d::Redirects d::Templates d::Talk/);

    my $screwup="Errors? [[User:AnomieBOT/shutoff/BadImageTagger]]";

    # Spend a max of 5 minutes on this task before restarting
    my $starttime=time();
    my $endtime=time()+300;

    # Get template list
    my %templates=$api->redirects_to_resolved('Template:Restricted use');
    if(exists($templates{''})){
        if($templates{''}{'code'} eq 'shutoff'){
            $api->warn("Task disabled: ".$templates{''}{'content'}."\n");
            return 300;
        }
        $api->warn("Failed to get Template:Restricted use redirects: ".$templates{''}{'error'}."\n");
        return 60;
    }

    # Get the bad image list
    $res=$api->query(prop=>'revisions',rvprop=>'content',titles=>'MediaWiki:Bad image list');
    if($res->{'code'} eq 'shutoff'){
        $api->warn("Task disabled: ".$res->{'content'}."\n");
        return 300;
    }
    if($res->{'code'} ne 'success'){
        $api->warn("Failed to get bad image list: ".$res->{'error'}."\n");
        next;
    }
    my $txt=(values %{$res->{'query'}{'pages'}})[0]{'revisions'}[0]{'*'};
    my @pages=($txt=~/^\*.*?\[\[:?(.*?)\]\]/gm);
    my %files=();
    my $iter=$api->iterator(
        titles    => bunchlist(500, @pages),
        prop      => 'imageinfo',
        iiprop    => '',
        iilimit   => 1,
        redirects => 1,
    );
    while(my $f=$iter->next){
        if(!$f->{'_ok_'}){
            $api->warn("Could not retrieve image info from iterator: ".$f->{'error'}."\n");
            return 60;
        }
        next unless $f->{'imagerepository'} eq 'local' || $f->{'imagerepository'} eq 'shared';
        $files{$f->{'title'}}=$f;
    }

    # Load list of transclusions of {{badimage}}
    my %bl=();
    $iter=$api->iterator(
        generator    => 'embeddedin',
        geititle     => $templates{'Template:Restricted use'},
        geinamespace => '6|7',
        geilimit     => 'max',
    );
    while(my $p=$iter->next){
        if(!$p->{'_ok_'}){
            $api->warn("Could not retrieve transclusions from iterator: ".$p->{'error'}."\n");
            return 60;
        }
        $bl{$p->{'title'}}=1;
    }

    # First, tag any images needing tagging
    foreach my $f (keys %files) {
        if(!exists($bl{$f})){
            my $tok=$api->edittoken($f, EditRedir => 1);
            next if $tok->{'code'} eq 'invalidtitle';
            if($tok->{'code'} eq 'shutoff'){
                $api->warn("Task disabled: ".$tok->{'content'}."\n");
                return 300;
            }
            if($tok->{'code'} eq 'pageprotected'){
                $api->warn("Cannot edit $f: ".$tok->{'error'}."\n");
                $api->whine("[[:$f]] is protected", "I cannot tag [[:$f]] with {{tl|restricted use}}, as the page is protected. Please tag it manually.");
                next;
            }
            if($tok->{'code'} eq 'botexcluded'){
                $api->warn("Excluded from $f: ".$tok->{'error'}."\n");
                $api->whine("Excluded from [[:$f]]", "I cannot tag [[:$f]] with {{tl|restricted use}}, as the page contains a bot exclusion template applying to me. Please tag it manually.");
                next;
            }
            if($tok->{'code'} ne 'success'){
                $api->warn("Failed to get edit token for $f: ".$tok->{'error'}."\n");
                next;
            }

            my $txt="{{restricted use}}\n".($tok->{'revisions'}[0]{'*'}//'');
            $api->log("Tagging $f");
            my $r=$api->edit($tok, $txt, "Tagging image listed at [[MediaWiki:Bad image list]] with {{restricted use}}. $screwup", 1, 1);
            if($r->{'code'} ne 'success'){
                $api->warn("Write failed on $f: ".$r->{'error'}."\n");
                next;
            }
        }
    }

    # Next, untag any images needing untagging
    foreach my $f (keys %bl) {
        my $istalk=$f=~/^File talk:/;
        next if(!$istalk && exists($files{$f}));

        my $tok=$api->edittoken($f, EditRedir => 1, imageinfo => { prop=>'', limit=>1 });
        if($tok->{'code'} eq 'shutoff'){
            $api->warn("Task disabled: ".$tok->{'content'}."\n");
            return 300;
        }
        if($tok->{'code'} eq 'pageprotected'){
            $api->warn("Cannot edit $f: ".$tok->{'error'}."\n");
            $api->whine("[[:$f]] is protected", "I cannot remove {{tl|restricted use}} from [[:$f]], as the page is protected. Please untag it manually.");
            next;
        }
        if($tok->{'code'} eq 'botexcluded'){
            $api->warn("Excluded from $f: ".$tok->{'error'}."\n");
            $api->whine("Excluded from [[:$f]]", "I cannot remove {{tl|restricted use}} from [[:$f]], as the page contains a bot exclusion template applying to me. Please untag it manually.");
            next;
        }
        if($tok->{'code'} ne 'success'){
            $api->warn("Failed to get edit token for $f: ".$tok->{'error'}."\n");
            next;
        }

        my $intxt=($tok->{'revisions'}[0]{'*'}//'');
        my $outtxt=$api->process_templates($intxt, sub {
            my $name=shift;
            return undef unless exists($templates{"Template:$name"});
            return '';
        });
        $outtxt=~s/^\s*|\s*$//g;
        #$outtxt='{{db-imagepage}}' if($tok->{'ns'}==6 && $tok->{'imagerepository'} ne 'local');
        if($intxt ne $outtxt){
            $api->log("Untagging $f");
            my $summary=$istalk?'Removing {{restricted use}} from file talk page; it will be added to the file page if necessary.':'Removing {{restricted use}} from image not listed at [[MediaWiki:Bad image list]].';
            my $r=$api->edit($tok, $outtxt, "$summary $screwup", 1, 1);
            if($r->{'code'} ne 'success'){
                $api->warn("Write failed on $f: ".$r->{'error'}."\n");
                next;
            }
        } else {
            $api->warn("Tried to remove {{restricted use}} from $f, but I couldn't find it!");
        }
    }

    return $starttime+3600-time();
}

1;