Jump to content

User:AnomieBOT/source/tasks/PeerReviewTranscluder.pm

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

=pod

=begin metadata

Bot:     AnomieBOT
Task:    PeerReviewTranscluder
BRFA:    Wikipedia:Bots/Requests for approval/AnomieBOT 83
Status:  Approved 2025-02-02
Created: 2025-01-24

Transclude current Peer Reviews onto the corresponding article's talk page.

=end metadata

=cut

use utf8;
use strict;

use AnomieBOT::Task;
use vars qw/@ISA/;
@ISA=qw/AnomieBOT::Task/;

use POSIX qw/strftime/;
use Data::Dumper;

sub new {
    my $class = shift;
    my $self = $class->SUPER::new;
    bless $self, $class;
    return $self;
}

=pod

=for info
BRFA approved 2025-02-02<br />[[Wikipedia:Bots/Requests for approval/AnomieBOT 83]]

=cut

sub approved {
    return 3;
}

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

    my $screwup = ' ([[Wikipedia:Bots/Requests for approval/AnomieBOT 83|BRFA]]) Errors? [[User:' . $api->user . '/shutoff/PeerReviewTranscluder]]';

    $api->task( 'PeerReviewTranscluder', 0, 10, qw(d::Templates d::Timestamp d::Redirects) );

    my $endtime = time() + 300;
    my $err = 0;

    # This category holds peer review pages.
    my $iter = $api->iterator(
        list => 'categorymembers',
        cmtitle => 'Category:Current peer reviews',
        cmnamespace => 4,
        cmtype => 'page',
        cmlimit => 'max',
        formatversion => 2,
    );
    while ( my $p = $iter->next ) {
        return 0 if $api->halting;

        if ( ! $p->{'_ok_'} ) {
            $api->warn( "Failed to retrieve pages in [[Category:Current peer reviews]]: " . $p->{'error'} . "\n" );
            return 300;
        }

        my $pr = $p->{'title'};

        unless ( $pr =~ /^Wikipedia:Peer review\/(.+)\/archive(\d+)$/ ) {
            $api->warn( "Ignoring unexpected title $pr\n" );
            next;
        }

        my ( $page, $idx ) = ( $1, $2 );
        my $talk = "Talk:$page";

        my $res = $api->query( 'titles' => "$page", 'formatversion' => 2 );
        if ( $res->{'code'} ne 'success' ) {
            $api->warn( "Failed to fetch existence for $page: " . $res->{'error'} . "\n" );
            $err = 1;
            next;
        }
        if ( $res->{'query'}{'pages'}[0]{'missing'} // 0 ) {
            $api->log( "Ignoring $pr, page to be reviewed does not exist." );
            next;
        }

        my $tok = $api->edittoken( $talk, templates => { templates => "$pr" } );
        if ( $tok->{'code'} eq 'shutoff' ) {
            $api->warn( "Task disabled: " . $tok->{'content'} . "\n" );
            return 300;
        }
        if ( $tok->{'code'} ne 'success' ) {
            $api->warn( "Failed to retrieve edit token for $talk: " . $tok->{'error'} . "\n" );
            $err = 1;
            next;
        }

        my $talk2 = $tok->{'title'};

        if ( defined( $api->store->{"$pr#$talk2"} ) ) {
            # Already posted.
            $api->store->{"$pr#$talk2"} = time if $api->store->{"$pr#$talk2"} < time - 86400;
            next;
        }

        if ( @{ $tok->{'templates'} // [] } ) {
            $api->warn( "Skipping transclusion of $pr into $talk2 as it's already there." );
            $api->store->{"$pr#$talk2"} = time;
            next;
        }

        my $txt = $tok->{'revisions'}[0]{'slots'}{'main'}{'*'} // '';
        $txt =~ s/\s*$/\n\n/ if $txt ne '';
        $txt .= "== Peer review ==\n{{$pr}}\n<!-- Please comment in the transcluded page, thanks! [[User:" . $api->user . "]] " . strftime( "%H:%M, %-d %B %Y", gmtime ) . " (UTC) -->\n";

        $res = $api->edit( $tok, $txt, "Transclude peer review [[$pr]].$screwup", 0, 0 );
        if ( $res->{'code'} ne 'success' ) {
            $api->warn( "Write for $talk2 failed: " . $res->{'error'} . "\n" );
            $err = 1;
            next;
        } else {
            $api->log( "Transcluded peer review $pr onto $talk2" );
            $api->store->{"$pr#$talk2"} = time;
        }
    }

    return $err ? 300 : 43200;
}

1;