User:FACBot/tfa stats.pl

From Wikipedia, the free encyclopedia
#!/usr/bin/perl -w
# Handle the recent list in TFAs
#

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

use Carp;
use Date::Parse;
use DateTime;
use DateTime::Duration;
use Data::Dumper;

use Cred;
use MilHist::ArticleHistory;
use MilHist::Bot;
use MilHist::PageViews;
use MilHist::Parser;
use MilHist::Table;

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

my $cred = new Cred ();

my $editor = MilHist::Bot->new ($cred) or
    die "new MediaWiki::Bot failed";

sub age ($$) {
    my ($date, $promoted) = @ARG;
    my $age = sprintf '{{age in years and days|%4d|%02d|%02d|%4d|%02d|%02d}}',
        $promoted->year (), $promoted->month (), $promoted->day (),
        $date->year (), $date->month (), $date->day ();
    return $age;
}

sub article ($) {
    my ($day) = @ARG;
    my $date = $day->strftime ("%B %d, %Y");
    $date =~ s/ 0/ /;
    my $tfa = "Wikipedia:Today's featured article/$date";
#   print $tfa, "\n";
    my $text = $editor->fetch ($tfa);
    my $article;
    foreach ($text) {
        s/<div.+div>//;
        s/{{TFAIMAGE.+?}}//;
        if (/\[\[\s*(.+?)[\]\|]/) {   
            $article = $1;
        }
    }
    $article or
        die "unable to find article in '$tfa'";
    return ucfirst $article;   
}

sub categories () {
    my $fa = "Wikipedia:Featured articles";
    my $text = $editor->fetch ($fa);
    my @lines = split/\n/, $text;
    my %fa;
    my $category;
    foreach (@lines) {
        if (/=+(.+?)=/) {
            $category = $1;
        } elsif ($category) {
            if (/^\*.+\[\[(.+?)(\]|\|)/) {
                my $article = $1;
#                print $article, "\n";
                $fa{$article} = $category;
            }           
        }
    }
    return \%fa;
}

sub day (@) {
    my ($month, $year) = @ARG;
    my $today = DateTime->now ();
    if ($month) {
        $year //= $today->year ();
        my ($ss, $mm, $hh, $day, $m, $y, $zone) = strptime ("1 $month $year");
        $month = $m + 1;
    } else {
        $today->subtract ('months' => 1);
        $month = $today->month ();
        $year  = $today->year ();
    }
    my $day = DateTime->new ('day' => 1, 'month' => $month, 'year' => $year); 
    return $day;
}

sub dts ($) {
    my ($date) = @ARG;
    my $dts = sprintf '{{dts|%4d|%02d|%02d|format=dmy}}', $date->year (), $date->month (), $date->day ();
    return $dts;
}

sub nts ($) {
    my ($number) = @ARG;
    return "{{nts|$number}}";
}

sub promoted ($) {
    my ($article) = @ARG;
    my $talk = 'Talk:' . $article;
    my $text;
   
    while (1) {
        $text = $editor->get_text ($talk) or
            error_exit ("unable to read '$talk'\n");
   
        if ($text =~ /#REDIRECT \[\[(.+)\]\]/) {
            $talk = $1;
            print "\tREDIRECT to '$talk'\n";
            redo;
        }
        last;
    }

    my $parser = new MilHist::Parser ('text' => $text);
    my $article_history = new MilHist::ArticleHistory ('parser' => $parser);
    my $date = $article_history->find_action ('FAC', 'date') or
        die ("unable to find FAC in '$talk' article history: $text");   
    my $epoch = str2time ($date);
    my $promoted = DateTime->from_epoch ('epoch' => $epoch);
    return $promoted;
}

sub report ($$) {
    my ($day, $rows) = @ARG;
    my $date = $day->subtract ('days' => 1)->strftime ("%B %Y");
    my $report = "Wikipedia:Today's featured article/recent TFAs/$date";
    my $table = new MilHist::Table ();
    my $heading = ['Date', 'Name', 'FA category', 'Country', 'Promoted', 'TFA wait', 'Page views', 'How chosen'];
    $table->options ({'align' => ['left', 'left', 'left', 'left', 'left', 'right', 'right', 'left']});
    my $text = $table->tabulate ($heading, $rows);

    $editor->edit ({
        page => $report,
        text => $text,
        summary => "TFA report for $date",
        minor => 0,
    }) or
        $editor->error ("unable to edit '$report'");       

}

my $day = day (@ARGV);
my @rows;
my $page = new MilHist::PageViews ();
my $categories = categories ();

for (my $month = $day->month (); $day->month () eq $month; $day->add ('days' => 1)) {
    my $article = article ($day);
    $cred->showtime ($day->strftime ("%d %B %Y"), " article was '$article'\n");
    my $category = $categories->{$article} // '';
    my $promoted = promoted ($article);   
    my $views = $page->views ($article, $day);    
    my $row = [dts ($day), $article,  $category, '', dts ($promoted), age ($day, $promoted), nts ($views), '', ];      
    push @rows, $row;    
}
report ($day, \@rows);

$cred->showtime ("finished\n");
exit 0;