User:MilHistBot/aclass.pl

#!/usr/bin/perl -w
#
# aclass.pl -- Pass or fail an A class review
#     This Bot runs every hour, looking for A class articles that have been promoted by a MilHist administrator
#    If it finds one, it follows the steps involved in promoting or failing it.
# Usage: aclass.pl
#    30 Mar 13 Add failure option
#     2 Jun 14 Add reassessment options
#     7 Jun 14 Error handling
#    14 Aug 14 Change a message
#     6 Sep 14 Enhancements:
#        (a) Do not stop if a bad nomination is found
#        (b) Follow the redirect is the assessment page is a redirect
#        (c) Mark edits as bot but not minor
#        (d) Make STDERR a utf8
#     8 Sep 14 Some templates are listed with underscores instead of spaces
#        Perform step 4a (removal from nom page) first
#    22 Jan 16 Do not leave a blank line behind on the review page
#     9 Nov 16 Patches for nominators in strange format
#    17 Oct 17 Allow for Coordinators on meta
#    12 Nov 17 Higher MilHist Awards
#    20 Nov 17 Higher MilHist Awards
#    22 Feb 18 MilHist awards script

use English;
use strict;
use utf8;
use warnings;

use Carp qw(croak longmess);
use Data::Dumper;
use File::Basename;
use MediaWiki::Bot;
use POSIX;
use unicode::collate;
use XML::Simple;

binmode(STDOUT, ":utf8");
binmode(STDERR, ":utf8");

my $pagename;
my $talkpage;
my $assessment;
my $outcome;
my $redirect;

my $aclass_review = 'Wikipedia:WikiProject Military history/Assessment/A-Class review';

my $year;
my $month;
my $next_month;
my $next_year;

my $Collator = Unicode::Collate->new();
   
# log in to the wiki
my $editor = MediaWiki::Bot->new({
        assert        => 'bot',
        host        => 'en.wikipedia.org',
        protocol     => 'https',
        operator     => 'Hawekeye7',
    }) or die "new MediaWiki::Bot failed";
   
my $dirname = dirname (__FILE__, '.pl');
push @INC, $dirname;
require Cred;
my $cred = new Cred ();
my $log = $cred->log ();

require showcase;

sub error_exit ($) {
    my @message = @ARG;
    if ($editor->{error}->{code}) {
        push @message, ' (', $editor->{error}->{code} , ') : ' , $editor->{error}->{details};
    }
    $cred->error (@message);
}

sub set_date () {
    my @current_time = gmtime ();
    $year = $current_time[5] + 1900;
    $month = $current_time[4];
    ($next_month, $next_year) = (11 == $month) ? (0, $year+1) : ($month+1, $year);
}

sub nominators () {
    my $nom_text = $editor->get_text ($assessment) or
        error_exit ("Unable to find '$assessment')");

    my @nm = ($nom_text =~ /<small>''Nominator\(s\):(.+)/ig);
    my @nominators = ($nm[0] =~ /\[\[User:(.+?)\|/gi);

    @nominators or
        @nominators = $nm[0] =~ /{{u\|(.+?)}}/gi;

    @nominators or
        @nominators = $nm[0] =~ /{{user0\|(.+?)}}/gi;

    @nominators or
        error_exit "Unable to find nominator";

    return @nominators;
}

sub step1 ($$) {
    $cred->showtime ("Step1: Archiving the nomination page\n");
    my ($comment, $summary) = @ARG;
    my $text = $editor->get_text ($assessment) or
        error_exit ("Unable to find '$assessment'");

    my $page_text = join "\n",
        '{{subst:archive top}}',
        "$comment ~~~~",
        $text,
        '{{subst:archive bottom}}';

    $editor->edit ({
        page => $assessment,
        text => $page_text,
        summary => $summary,
        minor => 0,
    }) or
        error_exit ("unable to edit '$assessment'");

}

sub newaction ($$$$$$) {
    my ($action, $date, $link, $result, $revid, $id) = @ARG;
    my $newaction = join "\n",
        "|action${id}=$action",
        "|action${id}date=$date",
        "|action${id}link=$link",
        "|action${id}result=$result",
        "|action${id}oldid=$revid";
    return $newaction;
}

sub update_article_history ($$$$$$) {
    my ($text, $action, $date, $link, $result, $revid) = @ARG;
    $text =~ s/{{Article\s*History/{{ArticleHistory/is;
    my ($articleHistory) = $text =~ /{{ArticleHistory(.+?)}}/gis;
    if ($articleHistory) {
       
        my $has_nested_text;
        while ($text =~ /{{ArticleHistory[^}]+({{[^}]+}})/) {
#            print "Nested text!!!!\n";
            my $nested_text = $1;
#            print "nested text=$nested_text\n";   
            my $transformed_text = $nested_text;
            $transformed_text =~ s/{{(.+)}}/%%<$1>%%/;
#            print "transformed text=$transformed_text\n";   
            $text =~ s/\Q$nested_text\E/$transformed_text/;
            $has_nested_text = 1;                                    
        }

#        print "articlehistory='$articleHistory'\n";
        for (my $id = 1;; ++$id) {
            if ($articleHistory =~ /action$id/) {
#                print "\t\tfound action$id\n";
            } else {
#                print "\t\tno $id - going with that\n";
                my $newaction = newaction ($action, $date, $link, $result,  $revid, $id);
                $text =~ s/{{Article\s*History(.+?)}}/{{ArticleHistory$1\n$newaction\n}}/is;
                last;
            }
        }
       
        if ($has_nested_text) {
            $text =~ s/%%</{{/g;
            $text =~ s/>%%/}}/g;
        }

    } else {
        my $newaction = newaction ($action, $date, $link, $result, $revid, 1);
        $text =~ s/^/{{ArticleHistory\n$newaction\n}}\n/is;
    }
    return $text;
}

sub step23 ($$) {
    my ($result, $summary) = @ARG;

    $cred->showtime ("Step2: Get the permanent link\n");
    my ($history) = $editor->get_history ($pagename, 1) or
        error_exit ("Unable to get history of '$pagename'");

    my $revision = $history->{revid};

    $cred->showtime ("Step3: Update the talk page\n");
    my $text = $editor->get_text ($talkpage) or
        error_exit ("Unable to find '$talkpage'");
    $text = update_article_history ($text, 'WAR', '~~~~~', $assessment, $result, $revision); 
#    print $text, "\n";

    foreach ($text) {
        if ($outcome eq 'pass') {
            s/((WikiProject Ships|WPSHIPS|WikiProject Aviation|ShipwrecksWikiProject|WikiProject Military history|WPMILHIST|MILHIST).+?)class=(Start|Stub|B|C|GA)/$1class=A/igs;
        }
        if ($outcome eq 'demoted') {
            s/((WikiProject Ships|WPSHIPS|WikiProject Aviation|ShipwrecksWikiProject|WikiProject Military history|WPMILHIST|MILHIST).+?)class=A/$1class=C/igs;
        }
        s/A-class=current/A-Class=$outcome/igs;
    }
#    print $text, "\n";
   
    $editor->edit ({
        page => $talkpage,
        text => $text,
        summary => $summary,
        minor => 0,
    }) or
        error_exit ("unable to edit '$talkpage'");

}

sub step4a ($) {
    $cred->showtime ("Step4a: Update the review page\n");
    my ($summary) = @ARG;

    my $text = $editor->get_text ($aclass_review) or
        error_exit ("Unable to find '$aclass_review'");

#    print $text, "\n";
   
    $text =~ s/WikiProject_Military_history/WikiProject Military history/g;
    my $p = $redirect // $assessment;
    $text =~ s/{{\Q$p\E}}\s*\n//s or
        error_exit ("Unable to find '$p' on '$aclass_review'");
    undef $redirect;               
   
#    print $text, "\n"; ############

    $editor->edit ({
        page => $aclass_review,
        text => $text,
        summary => $summary,
        minor => 0,
    }) or
        error_exit ("Unable to edit '$aclass_review'");
}

sub step4b ($$) {
    $cred->showtime ("Step4b: Archive the review\n");
    my ($result, $summary) = @ARG;

    my $archive = "Wikipedia:WikiProject Military history/Assessment/$year";
    my $text = $editor->get_text ($archive);
   
    $text or do {

        $text = join "",
            "{{WPMILHIST Archive|category=review}}\n",
            "{{WPMILHIST Navigation}} __FORCETOC__\n",
            "== Promoted ==\n",
            "[[Wikipedia:WikiProject Military history/Assessment/$year/Promoted]]\n",
            "\n",
            "== Failed ==\n",
            "[[Wikipedia:WikiProject Military history/Assessment/$year/Failed]]\n",
            "\n",
            "== Kept ==\n",
            "[[Wikipedia:WikiProject Military history/Assessment/$year/Kept]]\n",
            "\n",
            "== Demoted ==\n",
            "[[Wikipedia:WikiProject Military history/Assessment/$year/Demoted]]\n",
            "[[Category:Requests for military history A-Class review| ]]\n",
            "\n";

        $editor->edit ({
            page => $archive,
            text => $text,
            summary => "Created new archive page for $year",
            minor => 0,
        }) or
            error_exit ("Unable to find '$archive'");
    };

    $archive = "Wikipedia:WikiProject Military history/Assessment/$year/$result";
    $text = $editor->get_text ($archive);
   
    $text or do {

        my $category = $result = 'Promoted' || $result eq 'Kept' ? 'Successful' : 'Failed';
       
        $text = join "",
            "== $result ==\n",
            "<!--Please add new reviews directly below this line-->\n",
            "\n",
            "<!--Add archived reviews at the top please-->\n",
            "\n",
            "<noinclude>[[Category:$category requests for military history A-Class review| ]]</noinclude>\n",
            "\n";

        $editor->edit ({
            page => $archive,
            text => $text,
            summary => "Created new page for $year/$result",
            minor => 0,
        }) or
            error_exit ("Unable to find '$archive'");
    };

    $cred->showtime ("    updating $archive\n");
    $text =~ s/(<!--Please add new reviews directly below this line-->)/$1\n{{$assessment}}/s or
        $cred->showtime ("unable to find review section - please fix the comment on the page!\n");   
#    print $text, "\n";

    $editor->edit ({
        page => $archive,
        text => $text,
        summary => $summary,
        minor => 0,
    }) or
        error_exit ("Unable to edit '$archive'");
}

sub step5 ($) {
    $cred->showtime ("Step5: Update the announcements page\n");
    my ($summary) = @ARG;
    my $announcements = "Template:WPMILHIST Announcements";
    my $text = $editor->get_text ($announcements) or
        error_exit ("unable to find '$announcements'");

#    print $text, "\n";
    my $link = "[[$assessment|$pagename]]";
    $text =~ s/WP:/Wikipedia:/g;
    $text =~ s/(•)* \Q$link//s;
#    print $text, "\n";
   
    $editor->edit ({
        page => $announcements,
        text => $text,
        summary => $summary,
        minor => 0,
    }) or
        error_exit ("Unable to edit '$announcements'");
}

sub step6 ($) {
    $cred->showtime ("Step6: Update the article showcase\n");
    my ($summary) = @ARG;
    my $showcase_a = 'Wikipedia:WikiProject Military history/Showcase/A';
    my $text = $editor->get_text ($showcase_a) or
        error_exit ("unable to find '$showcase_a'");
#    print $text, "\n";
    my $showcase = new showcase ($text);


    if ($outcome eq 'pass') {
        $showcase->add ($pagename);
    }

    if ($outcome eq 'demoted') {
        $showcase->del ($pagename);
    }

    $editor->edit ({
        page => $showcase_a,
        text => $showcase->text,
        summary => $summary,
        minor => 0,
    }) or
        error_exit ("unable to edit '$showcase_a'");
}

sub step7 ($) {
    $cred->showtime ("Step7: Update the newsletter\n");
    my ($summary) = @ARG;

    sub nominator_list () {
        my @nominators = map {"[[User:$ARG|$ARG]]"} nominators ();
        if (1 == @nominators) {
            return $nominators[0];
        } else {
            my $last = pop @nominators;
            my $nominator_list = join ', ', @nominators;
            $nominator_list = join ' and ', $nominator_list, $last;
            return $nominator_list;
        }
    }

    my $nominator_list = nominator_list ();
    my $new_entry = "; [[$pagename]] ($nominator_list)\n";

    my @months = qw(January February March April May June July August September October November December);
   
    my $next_date = "$months[$next_month] $next_year";
    my $newsletter ="Wikipedia:WikiProject Military history/News/$next_date/Articles";
    my $text = $editor->get_text ($newsletter);

    if ($text) {
        $cred->showtime ("\tupdating $newsletter\n");

        my @a = split(/^/, $text);
        my @b;
        my $inserting = 0;
        my $inserted = 0;

        foreach (@a) {
            if (/New A-Class articles/) {
                $inserting = 1;
            }
            if (/Footer/) {
                if  (! $inserted) {
                    my $x = pop @b;
                    if ($x !~ /^\s*$/) {
                        push @b, $x;
                    }
                    push @b, $new_entry, "\n";
                }
            }
            if ($inserting) {
                if (/^;\[\[(.+?)\]\]/) {
                    if ($Collator->cmp ($1, $new_entry) > 0) {
                        push @b, "\n", $new_entry;
                        $inserting = 0;
                        $inserted = 1;
                    }
                }
                if (/^$/) {
                    push @b, "\n", $new_entry;
                    $inserting = 0;
                    $inserted = 1;
                }
            }
            push @b, $ARG;
        }

        $text = join '', @b;

    }else {
        $cred->showtime ("\tcreating $newsletter\n");

        $text = join "",
            "{{Wikipedia:WikiProject Military history/News/$next_date/Header}}__NOTOC__\n\n",
            "{{WPMILHIST Newsletter section header 2|New featured articles}}\n\n",
            "{{WPMILHIST Newsletter section header 2|New featured lists}}\n\n",
            "{{WPMILHIST Newsletter section header 2|New featured topics}}\n\n",
            "{{WPMILHIST Newsletter section header 2|New featured pictures}}\n\n",
            "{{WPMILHIST Newsletter section header 2|New featured portals}}\n\n",
            "{{WPMILHIST Newsletter section header 2|New A-Class articles}}\n",
            $new_entry, "\n",
            "{{Wikipedia:WikiProject Military history/News/$next_date/Footer}}\n\n";
    }

    $editor->edit ({
        page => $newsletter,
        text => $text,
        summary => $summary,
        minor => 0,
    }) or
        error_exit ("unable to edit '$newsletter'");
}

sub step8 ($$) {
    $cred->showtime ("Step8: Tracking award eligibility\n");
    my ($coordinator, $summary) = @ARG;

    sub awards ($) {
        my ($nominator) = @ARG;
        my @archives = ('Wikipedia talk:WikiProject Military history/Awards',
                'Wikipedia talk:WikiProject Military history/Awards/ACR/Archive 2',
                'Wikipedia talk:WikiProject Military history/Awards/ACR/Archive 1');
       
        foreach my $archive (@archives) {   
            my $text = $editor->get_text ($archive) or
                error_exit ("unable to find '$archive'");

            my @lines = reverse split(/^/, $text);
            foreach (@lines) {   
                if (/$nominator \((\d+)\)/i) {
                    my $count = $1;
                    $cred->showtime ("$nominator has $count A class medals\n");
                    return $count;
                }   
            }
        }
        return 0;       
    }

    sub award ($) {
        my ($awards) = @ARG;
        my $award;
        my $articles_per_award;
        my $tracking;
        my $acm_tracking = 'Wikipedia:WikiProject Military history/Awards/ACM/Eligibility tracking';
        my $acc_tracking = 'Wikipedia:WikiProject Military history/Awards/ACC/Eligibility tracking';
   
        if ($awards < 5) {
            $award = 'A-Class medal';
            $articles_per_award = 3;
            $tracking = $acm_tracking;
        } elsif ($awards < 10) {
            $award = 'A-Class medal with Oak Leaves';
            $articles_per_award = 3;
            $tracking = $acm_tracking;
        } elsif ($awards < 20) {
            $award = 'A-Class medal with Swords';
            $articles_per_award = 3;
            $tracking = $acm_tracking;
        } elsif ($awards < 35) {
            $award = 'A-Class medal with Diamonds';   
            $articles_per_award = 3;
            $tracking = $acm_tracking;
        } elsif ($awards < 40) {
            $award = 'A-Class cross';
            $articles_per_award = 5;
            $tracking = $acc_tracking;
        } elsif ($awards < 46) {
            $award = 'A-Class cross with Oak Leaves';
            $articles_per_award = 5;
            $tracking = $acc_tracking;
        } elsif ($awards < 56) {
            $award = 'A-Class cross with Swords';
            $articles_per_award = 5;
            $tracking = $acc_tracking;
        } else {
            $award = 'A-Class cross with Diamonds';
            $articles_per_award = 5;
            $tracking = $acc_tracking;
        }
       
        return ($award, $articles_per_award, $tracking);       
    }

    sub nomination ($$$@) {
        my ($coordinator, $nominee, $award, $awards, @pages) = @ARG;
        my $nomination_page = 'Wikipedia_talk:WikiProject_Military_history/Awards';

        my $text = $editor->get_text ($nomination_page) or
            error_exit ("unable to find '$nomination_page'");

        my @a = reverse split(/^/, $text);
        my @b;
        my $inserted = 0;
        my $skipping = 1;
       
        foreach (@a) {
            push @b, $ARG;
            if ($award =~ /A-Class medal/) {
                if (/<!--/ && $skipping) {
                    $skipping = 0;
                    next;
                }
            }
            if (/<!--/ && !$inserted) {
                push @b, "*'''Support''' As nominator $coordinator via ~~~~\n\n";
                push @b, "{{WPMILHIST Award nomination|nominee=$nominee|citation=[[$pages[0]]], [[$pages[1]]], and [[$pagename]]|award=$award|status=nominated}}\n";
#                push @b, "''$award'': for [[$pages[0]]], [[$pages[1]]], and [[$pagename]]\n";
                push @b, "===$nominee ($awards)===\n";
                $inserted = 1;               
            }
        }
        $text = join '', reverse @b;
       
        $cred->showtime ("\tupdating nomination page $nomination_page\n");
        $editor->edit ({
            page => $nomination_page,
            text => $text,
            summary => "$nomineee ($awards)",
            minor => 0,
        }) or
            error_exit ("unable to edit $nomination_page");
    }
   
    # Find the nominators on the tracking pages
    my @nominators = nominators ();
    foreach my $nominator (@nominators) {
        my $awards = awards($nominator) + 1;
        my ($award, $articles_per_award, $tracking) = award ($awards);
        my $text = $editor->get_text ($tracking) or
            error_exit ("unable to find '$tracking'");

        foreach ($text) {
            if (/# '''$nominator:*'''(.*)/) {
                $cred->showtime ("\tFound nominator $nominator in tracking list\n");
                my $string = $1;
                my $count = 0;
                my @pages;
                while ($string =~ /\[\[File:Symbol a class.svg\|15px\|link=(.+?)\]\]/g) {
                        $count++;
                        push @pages, $1;
                }
                $cred->showtime ("\tfound $count nominations for $nominator\n");
                ++$count;
           
                if ($count < $articles_per_award) {
                    s/(# '''$nominator:*'''.*)/$1 [[File:Symbol a class.svg|15px|link=$pagename]]/;
                } else {
                    s/(# '''$nominator:*''')(.+)/$1/;
                    nomination ($coordinator, $nominator, $award, $awards, $pages[0], $pages[1], $pagename);
                }
            } else {
                $cred->showtime ("\tCould not find nominator $nominator in tracking list -- adding\n");
                my @a = split(/^/, $text);
                my @b;
                my $found = 0;
                my $inserted = 0;
                foreach (@a) {
                    if (!$inserted) {
                        if (/^# '''(.+):*'''/) {
                            $found++;
                            if ($1 gt $nominator) {
                                push @b, "# '''$nominator:''' [[File:Symbol a class.svg|15px|link=$pagename]]\n";
                                $inserted = 1;
                            }
                        }
                        if (/^$/ && $found) {
                            push @b, "# '''$nominator:''' [[File:Symbol a class.svg|15px|link=$pagename]]\n";
                            $inserted = 1;
                        }
                    }
                    push @b, $ARG;
                }
                $text = join '', @b;
            }
       
            $cred->showtime ("\tupdating tracking page $tracking\n");
            $editor->edit ({
                page => $tracking,
                text => $text,
                summary => $summary,
                minor => 0,
            }) or
                error_exit ("unable to edit $tracking");
        }
    }             
}

sub pass ($) {
    $cred->showtime ("Passing $pagename\n");
    my ($coordinator) = @ARG;
    my $comment = "Article '''promoted''' by $coordinator via";
    my $summary = "$pagename Passed A class review";

    step4a ($summary);
    step1 ($comment, $summary);
    step23 ('approved', $summary);
    step4b ('Promoted', $summary);
    step5 ($summary);
    step6 ($summary);
    step7 ($summary);
    step8 ($coordinator, $summary);
    $cred->showtime ("done\n");
}

sub failed ($) {
    $cred->showtime ("Failing $pagename\n");
    my ($coordinator) = @ARG;
    my $comment = "'''No consensus to promote''' at this time - $coordinator via";
    my $summary = "$pagename failed A class review";

    step4a ($summary);
    step1 ($comment, $summary);
    step23 ('not approved', $summary);
    step4b ('Failed', $summary);
    step5 ($summary);
    $cred->showtime ("done\n");
}

sub kept ($) {
    $cred->showtime ("Keeping $pagename\n");
    my ($coordinator) = @ARG;
    my $comment = "Article still meets A-Class criteria  - $coordinator via";
    my $summary = "$pagename kept after A class reappaisal";

    step4a ($summary);
    step1 ($comment, $summary);
    step23 ('kept', $summary);
    step4b ('Kept', $summary);
    step5 ($summary);
    $cred->showtime ("done\n");
}

sub demoted ($) {
    $cred->showtime ("Demoting $pagename\n");
    my ($coordinator) = @ARG;
    my $comment = "Article no longer meets A-Class criteria - $coordinator via";
    my $summary = "$pagename demoted after A class reappaisal";

    step4a ($summary);
    step1 ($comment, $summary);
    step23 ('demoted', $summary);
    step4b ('Demoted', $summary);
    step5 ($summary);
    step6 ($summary);
    $cred->showtime ("done\n");
}

sub find_pages () {
    my @pages;
    my $text = $editor->get_text($aclass_review) or
        error_exit "Unable to find '$aclass_review'\n";
   
#    print $text;
    my @lines = split/\n/, $text;
    foreach (@lines) {
        s/_/ /g;
        if (/ACR\/(Closing|Instructions)/) {
            next;
        }
        if (/{{Wikipedia:WikiProject Military history\/Assessment\/(.+)}}/) {
            push @pages, $1;
        }
    }
    return @pages;
}

sub iscoordinator ($) {
    my ($user) = @ARG;
    my $category = 'WikiProject Military history coordinators';
    my @coordinators = $editor->get_pages_in_category ($category);
    foreach my $coordinator (@coordinators) {
#        print $coordinator, "\n";
        return 1 if "User:$user" eq $coordinator;
    }
   
    # Try on meta
    my $meta = MediaWiki::Bot->new ({
#        assert        => 'bot',
        host        => 'meta.wikimedia.org',
        protocol     => 'https',
    }) or die "new MediaWiki::Bot failed";

    $meta->login ({
        username => $cred->user,
        password => $cred->password
    }) or die $meta->{error}->{code} . ': ' . $meta->{error}->{details};

    my @meta_coordinators = $meta->get_pages_in_category ($category);
    foreach my $meta_coordinator (@meta_coordinators) {
#        print $meta_coordinator, "\n";
        return 1 if "User:$user" eq $meta_coordinator;
    }

    return 0;
}

sub whodunnit ($) {
    my ($status) = @ARG;
    my $user;
    my @history = $editor->get_history ($talkpage) or
        error_exit ("unable to get history of $talkpage'");
       
    foreach my $history (@history) {
#        print "user=", $history->{user}, ", revid=", $history->{revid}, "\n";
        $user //= $history->{user};
        my $text = $editor->get_text ($talkpage, $history->{revid}) or
            error_exit ("unable to find '$talkpage' revid $history->{revid}");
        if ($text =~ /A-Class\s*=\s*(\w+)/i) {
#            print "status=$1\n";
            last if ($1 ne $status);
        } else {
            last;
        }
        $user = $history->{user};
    }
#    print "user=", $user, "\n";
    return $user;
}

sub outcome () {
    while (1) {
        my $text = $editor->get_text ($talkpage) or
            error_exit ("Unable to find '$talkpage'");

        if ($text !~ /A-Class\s*=\s*(\w+)/i) {
            $cred->showtime ("unable to find A-Class on $talkpage\n");
           
            # See if the assessment is a redirect
            my $t = $editor->get_text($assessment) or
                error_exit "Unable to find '$assessment'\n";

            if ($t =~ /REDIRECT \[\[(.+)\]\]/) {
                    $cred->showtime ("'$assessment' redirects to '$1'\n");
                    $redirect = $assessment;
                    $assessment = $1;
                    if ($assessment =~ /Wikipedia:WikiProject Military history\/Assessment\/(.+)/) {
                        $pagename = $1;
                        $talkpage = "Talk:$pagename";
                        redo;
                    }
            }
            return 'unknown';
        }
        return lc $1;
    }
}

sub clear_outcome () {
    while (1) {
        my $text = $editor->get_text ($talkpage) or
            error_exit ("Unable to find '$talkpage'");

        if ($text !~ /A-Class=(\w+)/i) {
            $cred->showtime ("unable to find A-Class on $talkpage\n");
           
            # See if the assessment is a redirect
            my $t = $editor->get_text($assessment) or
                error_exit "Unable to find '$assessment'\n";
            if ($t =~ /REDIRECT \[\[(.+)\]\]/) {
                    $cred->showtime ("'$assessment' redirects to '$1'\n");
                    $redirect = $assessment;
                    $assessment = $1;
                    if ($assessment =~ /Wikipedia:WikiProject Military history\/Assessment\/(.+)/) {
                        $pagename = $1;
                        $talkpage = "Talk:$pagename";
                        redo;
                    }
            }
        }
    }
}

sub process_pages () {
   
    set_date ();
    my @pages = find_pages ();
    foreach my $p (@pages) {
        $pagename = $p;

        $cred->showtime ("Checking $pagename...\n");
        $assessment = "Wikipedia:WikiProject Military history/Assessment/$pagename";
        $pagename =~ s/\/archive\d+//;
        $pagename =~ s/_/ /g;       
        $talkpage = "Talk:$pagename";
        $redirect = undef;               

        $outcome = outcome ();
        $cred->showtime ($outcome, "\n");

        if ($outcome eq 'current') {
            next;
        } elsif ($outcome eq 'unknown') {
            next;
        } else {
           
            my $user = whodunnit ($outcome);
            if (iscoordinator ($user)) {
                $cred->showtime ("$user is a ccoordinator\n");
            } else {
                $cred->warning ("$user is NOT a ccoordinator\n");
                next;
            }

            my $coordinator = "[[User:$user|$user]] ([[User talk:$user|talk]])";
            if ($outcome eq 'pass') {
                pass ($coordinator);
            } elsif ($outcome eq 'fail') {
                failed ($coordinator);
            } elsif ($outcome eq 'kept') {
                kept ($coordinator);
            } elsif ($outcome eq 'demoted') {
                demoted ($coordinator);
            } else {
                $cred->warning ("unknown outcome: '$outcome'\n");
            }
        }
    }
}

#       Main program
$editor->login ({
    username => $cred->user,
    password => $cred->password
}) or die $editor->{error}->{code} . ': ' . $editor->{error}->{details};

$cred->showtime ("begin\n");
process_pages ();
$cred->showtime ("end\n");

exit 0;

Content Disclaimer

Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.

  1. The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
  2. There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
  3. It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
  4. Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
  5. Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.