User:MilHistBot/announcements.pl

{{syntaxhighlight|lang=perl|code=
 * 1) !/usr/bin/perl -w


 * 1) announcements.pl -- Update the MilHist announcements page
 * 2) Usage: announcements.pl
 * 3)     3 Oct 14 Created
 * 4)    14 Oct 14 Sort entries in chronological order
 * 5)    17 Oct 14 Handle GA2 etc

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

use Carp; use File::Basename qw(dirname); use Data::Dumper; use IO::File; use MediaWiki::Bot; use POSIX; use Time::Local; use XML::Simple;

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

my $dirname = dirname (__FILE__, '.pl'); push @INC, $dirname; require Cred; my $cred = new Cred ; my $log = $cred->log ;

my %timestamp; my %month = ('January' => 0, 'February' => 1, 'March' => 2, 'April' => 3, 'May' => 4, 'June' => 5,   'July' => 6, 'August' => 7, 'September' => 8, 'October' => 9, 'November' => 10, 'December' => 11);

my $editor = MediaWiki::Bot->new ({       assert        => 'bot',        host        => 'en.wikipedia.org',        protocol     => 'https', }) or die "new failed";

sub allow_bots ($$;$) { my($text, $user, $opt) = @ARG; return 0 if $text =~ /{{[nN]obots}}/; return 1 if $text =~ /{{[bB]ots}}/; if ($text =~ /{{[bB]ots\s*\|\s*allow\s*=\s*(.*?)\s*}}/s){ return 1 if $1 eq 'all'; return 0 if $1 eq 'none'; my @bots = split(/\s*,\s*/, $1); return (grep $ARG eq $user, @bots)?1:0; }   if ($text =~ /{{[bB]ots\s*\|\s*deny\s*=\s*(.*?)\s*}}/s){ return 0 if $1 eq 'all'; return 1 if $1 eq 'none'; my @bots = split(/\s*,\s*/, $1); return (grep $ARG eq $user, @bots)?0:1; }   if (defined($opt) && $text =~ /{{[bB]ots\s*\|\s*optout\s*=\s*(.*?)\s*}}/s){ return 0 if $1 eq 'all'; my @opt = split(/\s*,\s*/, $1); return (grep $ARG eq $opt, @opt)?0:1; }   return 1; }

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

sub is_milhist ($) { my ($page) = @ARG; my $talkpage = "Talk:$page"; my $text = $editor->get_text ($talkpage) or do { $cred->showtime ("Unable to find '$talkpage'\n"); return 0; };   return $text =~ /{{WikiProject Military history|{{MILHIST|{{WPMILHIST/i; }

sub timestamp ($) { my ($candidate) = @ARG; my @history = $editor->get_history ($candidate) or       error_exit "Unable get history of '$candidate'"; my $created = pop @history; my ($hour, $min, $sec) = $created->{timestamp_time} =~ /(\d+):(\d+):(\d+)/; my ($year, $mon, $day) = $created->{timestamp_date} =~ /(\d+)-(\d+)-(\d+)/; return timegm ($sec, $min, $hour, $day, $mon-1, $year); }

sub aclass { my $candidates = 'Wikipedia:WikiProject Military history/Assessment/A-Class review'; my %candidates; my $text = $editor->get_text ($candidates) or       error_exit "Unable to find '$candidates'"; my @candidates = $text =~ /(Wikipedia:WikiProject Military history\/Assessment\/[^}]+)/g; foreach my $candidate (@candidates) { if ($candidate =~ /Wikipedia:WikiProject Military history\/Assessment\/([^}]+)/) { my $page = $1; next if $page =~ /^ACR/; $cred->showtime ("\t$page\n"); $candidates{$page} = $candidate; $timestamp{$page} = timestamp ($candidate); }        }    return %candidates; }

sub featured ($) { my ($candidates) = @ARG; my %candidates; my $text = $editor->get_text ($candidates) or       error_exit "Unable to find '$candidates'"; my @candidates = $text =~ /($candidates\/.+\/archive\d+)/g; foreach my $candidate (@candidates) { if ($candidate =~ /$candidates\/(.+)\/archive\d+/) { my $page = $1; if (is_milhist ($page)) { $cred->showtime ("\t$page\n"); $candidates{$page} = $candidate; $timestamp{$page} = timestamp ($candidate); }       }         }    return %candidates; }

sub good_article_timestamp ($) { my ($candidate) = @ARG; my $text = $editor->get_text ($candidate) or       error_exit "Unable to find '$candidate'"; if ($text =~ /GA nominee\|(\d+):(\d+), (\d+) (\w+) (\d+)/) { my ($hour, $min, $day, $month, $year) = ($1, $2, $3, $4, $5); my $sec = 0; my $mon = $month{$month}; return timegm ($sec, $min, $hour, $day, $mon, $year); } else { error_exit "Unable to find GA nominee in '$candidate'"; }       }

sub parse_template ($@) { my ($text, @args) = @ARG; my %p; while ($text =~ s/\|(\w+)\s*=\s*([^}|]+)//is) { $p{$1}=$2; }   my @p = split '\|', $text; param:foreach my $p (@p) { next param unless $p; foreach my $arg (@args) { if (!defined $p{$arg}) { $p{$arg} = $p; next param; }       }    }    return %p; }
 * 1)    foreach my $p (keys %p) {
 * 2)        print "$p => $p{$p}\n";
 * 3)    }

sub good_article_entry ($) { my ($page) = @ARG; my $entry = "\{\{WPMHA\/GAN\|$ARG\}\}"; my $talk = "Talk:$page"; my $text = $editor->get_text ($talk) or       error_exit "Unable to find '$talk'"; if ($text =~ s/{{GA nominee(.+?)}}//is) { my %h = parse_template ($1, 'temestamp', 'nominator', 'page', 'topic', 'status', 'note'); my $number = $h{page}; $entry = "{{WPMHA/GAN|$page|$number}}"; }   return $entry; }

sub good_article_nominees { my $candidates = 'Good article nominees'; my @milhist; my @candidates = $editor->get_pages_in_category ($candidates) or        error_exit "Unable to find '$candidates'"; foreach my $candidate (@candidates) { if ($candidate =~ /Talk:(.+)/) { my $page = $1; if (is_milhist ($page)) { $cred->showtime ("\t$page\n"); $timestamp{$page} = good_article_timestamp ($candidate); push @milhist, $page; }       }    }    return join '  &bull; ', map { good_article_entry ($ARG) } sort { $timestamp{$a} <=> $timestamp{$b} } @milhist; }

sub peer_reviews { my $candidates = 'Current peer reviews'; my %candidates; my @candidates = $editor->get_pages_in_category ($candidates) or        error_exit "Unable to find '$candidates'"; foreach my $candidate (@candidates) { if ($candidate =~ /Wikipedia:Peer review\/(.+)\/archive\d+/) { my $page = $1; if (is_milhist ($page)) { $cred->showtime ("\t$page\n"); $candidates{$page} = $candidate; $timestamp{$page} = timestamp ($candidate); }       }         }    return %candidates; }

sub format_up (%) { my %pages = (@ARG); return join ' &bull; ', map { "$ARG" } sort { $timestamp{$a} <=> $timestamp{$b} } keys %pages; }

$cred->showtime (": started\n"); $editor->login ({   username => $cred->user,    password => $cred->password }) or error_exit "unable to login"; my $announcements = 'Template:WPMILHIST Announcements'; my $text = $editor->get_text ($announcements) or       die "Unable to find '$announcements'\n"; $cred->error ("no bots allowed on '$announcements'") unless allow_bots ($text, $cred->user);

my $bot = " ";

$cred->showtime ("A class reviews:\n"); my %acr = aclass ; my $acr = format_up (%acr); $text =~ s/A-Class_reviews=.*/A-Class_reviews=$acr $bot/;

$cred->showtime ("Featured article candidates:\n"); my %fac = featured ('Wikipedia:Featured article candidates'); my $fac = format_up (%fac); $text =~ s/featured_article_candidates=.*/featured_article_candidates=$fac/;

$cred->showtime ("Featured article reviews:\n"); my %far = featured ('Wikipedia:Featured article review'); my $far = format_up (%far); $text =~ s/featured_article_reviews=.*/featured_article_reviews=$far $bot/;

$cred->showtime ("Featured list candidates\n"); my %flc = featured ('Wikipedia:Featured list candidates'); my $flc = format_up (%flc); $text =~ s/featured_list_candidates=.*/featured_list_candidates=$flc $bot/;

$cred->showtime ("Featured list removal candidates\n"); my %flr = featured ('Wikipedia:Featured list removal candidates'); my $flr = format_up (%flr); $text =~ s/featured_list_removal_candidates=.*/featured_list_removal_candidates=$flr $bot/;

$cred->showtime ("Peer review:\n"); my %pr = peer_reviews ; my $pr = format_up (%pr); $text =~ s/peer_reviews=.*/peer_reviews=$pr $bot/;

$cred->showtime ("Good article nominees:\n"); my $gan = good_article_nominees ; $text =~ s/good_article_nominees=.*/good_article_nominees=$gan $bot/; $editor->edit ({   page => $announcements,    text => $text,    summary => "Updating announcements page",    bot => 1,    minor => 0, }) or    error_exit ("unable to edit '$announcements'"); $cred->showtime (": finished\n"); $log->close ;

exit 0; }}