User:MilHistBot/membership.pl


 * 1) !/usr/bin/perl -w
 * 2) membership.pl -- Check for inactive members of the MilHist Project
 * 3) Usage: membership.pl
 * 4)   11 Jan 18 Created
 * 5)    24 Jan 18 Process inactive list as well as active list
 * 1)    24 Jan 18 Process inactive list as well as active list

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

use DateTime; use DateTime::Duration; use File::Basename; use MediaWiki::Bot;

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

my $milhist = 'Wikipedia:WikiProject Military history'; my $active_members = "$milhist/Members/Active"; my $inactive_members = "$milhist/Members/Inactive";

my $today = DateTime->today;

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

my $editor = MediaWiki::Bot->new({       assert        => 'bot',        host        => 'en.wikipedia.org',        protocol     => 'https',        operator     => 'Hawekeye7',    }) or die "new MediaWiki::Bot failed"; $editor->login ({   username => $cred->user,    password => $cred->password }) or die $editor->{error}->{code}. ': ' . $editor->{error}->{details};
 * 1) log in to the wiki

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

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

sub redirect ($) { my $user = shift; my $user_talk = "User talk:". $user; my $user_talk_text = $editor->get_text ($user_talk) or do { error_warning ("Unable to find talk page for '$user')");       return undef;    };    if ($user_talk_text =~ /#REDIRECT \[\[User talk:(.+?)\]\]/) {        my $redirect = $1;        return $redirect;        }    $cred->warning ("Unable to find redirect for '$user')"); return undef; }
 * 1)        $cred->showtime ("$user redirects to $redirect\n");

sub last_active ($) { my $member = shift; my $last_active; MEMBER:while (1) { $last_active = $editor->last_active ($member) or do { $member = redirect ($member); if (defined $member) { redo MEMBER; } else { return undef; }       };        last; }   return $last_active; }

sub days_ago ($) { my $latest_timestamp = shift; $latest_timestamp =~ /(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})Z/; my $active = DateTime->new (year => $1, month => $2, day => $3, hour => $4, minute => $5, second => $6, time_zone => 'UTC'); my $delta = $active->delta_days ($today); return $delta->in_units ('days'); }

my %active; my %inactive; my $active_count = 0; my $inactive_count = 0;

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

my @inactive_lines = split /\n/, $inactive_members_text; my @inactive_header = grep { ! /^#/ } @inactive_lines; my @inactive_members = grep { /^#/ } @inactive_lines; INACTIVE_LINE:foreach my $inactive_line (@inactive_members) { my $member; if ($inactive_line =~ /\{\{\#target:User talk:(.+?)\}\}/) { $member = $1; } else { $cred->warning ("irregular line: $inactive_line\n"); next INACTIVE_LINE; }

my $last_active = last_active ($member) or       next INACTIVE_LINE; my $days_ago = days_ago ($last_active); if ($days_ago < 365) { $cred->showtime ("$member last active $last_active ($days_ago days ago)\n"); $active{$inactive_line} = 1; ++$active_count; } else { $inactive{$inactive_line} = 1; } }

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

my @active_lines = split /\n/, $active_members_text; my @active_header = grep { ! /^#/ } @active_lines; my @active_members = grep { /^#/ } @active_lines; ACTIVE_LINE:foreach my $active_line (@active_members) { my $member; if ($active_line =~ /\{\{\#target:User talk:(.+?)\}\}/) { $member = $1; } else { $cred->warning ("irregular line: $active_line\n"); next ACTIVE_LINE; }

my $last_active = last_active ($member) or       next ACTIVE_LINE; my $days_ago = days_ago ($last_active); if ($days_ago >= 365) { $cred->showtime ("$member last active $last_active ($days_ago days ago)\n"); $inactive{$active_line} = 1; ++$inactive_count; } else { $active{$active_line} = 1; } }

$cred->showtime ("$active_count active members found\n"); $cred->showtime ("$inactive_count inactive members found\n"); exit 0 unless ($active_count > 0 or $inactive_count > 0);

$cred->showtime ("updating active list\n"); $active_members_text = join "\n", @active_header, sort keys %active;

$editor->edit ({       page => $active_members,        text => $active_members_text,        summary => 'update to remove members inactive for > 365 days',        minor => 0,    }) or        error_exit ("unable to edit '$active_members'");

$cred->showtime ("updating inactive list\n"); $inactive_members_text = join "\n", @inactive_header, sort keys %inactive;

$editor->edit ({       page => $inactive_members,        text => $inactive_members_text,        summary => 'update to add members inactive for > 365 days',        minor => 0,    }) or        error_exit ("unable to edit '$active_members'");

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