Jump to content

User:AnomieBOT/source/tasks/DatedCategoryDeleterTest.pm

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

=pod

=begin metadata

Bot:      AnomieBOT III
Task:     DatedCategoryDeleterTest
BRFA:     N/A
Status:   On hold
Created:  2017-01-31
Exclusion: false

Investigation for whether a bot to [[WP:CSD#G6|G6]] emptied dated maintenance
categories would be useful. It will log to a subpage and we'll see how often it
actually finds anything.

=end metadata

=cut

use utf8;
use strict;

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

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

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

=pod

=for info
Per [[WP:BOTUSERSPACE]], any bot or automated editing process that affects only
the operator's or their own userspace, and which are not otherwise disruptive,
may be run without prior approval.

=for info
As of 2019-02-10, there doesn't seem to be any need for this.

=cut

sub approved {
    return -500;
}

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

    $api->task('DatedCategoryDeleterTest', 0, 10, qw/d::Timestamp d::IWNS/);

    # Easier to use the DB for category intersection
    my ($dbh);
    eval {
        ($dbh) = $api->connectToReplica( 'enwiki' );
    };
    if ( $@ ) {
        $api->warn( "Error connecting to replica: $@\n" );
        return 300;
    }
    my @rows;
    eval {
        @rows = @{ $dbh->selectall_arrayref( qq{
        SELECT page_namespace, page_title
        FROM page JOIN categorylinks AS c1 ON(c1.cl_from=page_id) JOIN categorylinks AS c2 ON(c2.cl_from=page_id)
        WHERE c1.cl_to = 'Candidates_for_uncontroversial_speedy_deletion' AND c2.cl_to = 'Monthly_clean-up_category_counter'
        }, { Slice => {} } ) };
    };
    if ( $@ ) {
        $api->warn( "Error fetching page list from replica: $@\n" );
        return 300;
    }
    return 3600 unless @rows;

    my @woulddelete = ();
    for my $row (@rows) {
        return 0 if $api->halting;

        next if $row->{'page_namespace'} != 14;
        utf8::decode( $row->{'page_title'} ); # Data from database is binary
        my $title = $row->{'page_title'};
        $title =~ s/_/ /g;

        my $res = $api->query(
            titles => "Category talk:$title",
            formatversion => 2,
        );
        if($res->{'code'} ne 'success') {
            $api->warn("Failed to get existence for Category talk:$title: " . $res->{'error'} . "\n");
            next;
        }
        unless ( $res->{'query'}{'pages'}[0]{'missing'} // 0 ) {
            $api->log( "Skipping [[Category:$title]], talk page exists" );
            next;
        }

        my $tok = $api->gettoken( 'csrf', Title => "Category:$title", NoExclusion => 1, categoryinfo => {} );
        if($tok->{'code'} eq 'shutoff') {
            $api->warn("Task disabled: " . $tok->{'content'} . "\n");
            return 300;
        }
        if($tok->{'code'} ne 'success') {
            $api->warn("Failed to get token for Category:$title: " . $tok->{'error'} . "\n");
            next;
        }

        if ( ( $tok->{'categoryinfo'}{'size'} // 0 ) != 0 ) {
            $api->log( "Skipping [[Category:$title]], not actually empty" );
            next;
        }

        my $txt = $tok->{'revisions'}[0]{'slots'}{'main'}{'*'} // '';
        unless ( $txt =~ /\s*\{\{Monthly clean[ -]up category(?:\s*\|[^\}]*)?\}\}\s*$/ ) {
            $api->log( "Skipping [[Category:$title]], content isn't as expected" );
            next;
        }

        push @woulddelete, "Category:$title";
    }

    if ( @woulddelete ) {
        my $tok = $api->edittoken( 'User:AnomieBOT III/DatedCategoryDeleter test' );
        if($tok->{'code'} eq 'shutoff') {
            $api->warn("Task disabled: " . $tok->{'content'} . "\n");
            return 300;
        }
        if($tok->{'code'} ne 'success') {
            $api->warn("Failed to get token for testing log: " . $tok->{'error'} . "\n");
            next;
        }
        my $txt = $tok->{'revisions'}[0]{'slots'}{'main'}{'*'};
        $txt=~s/\s*$/\n/s;
        my $time = strftime( '%Y-%m-%d %H:%M:%S', gmtime );
        my $count = 0;
        for my $title (@woulddelete) {
            next if $txt =~ /Would delete \[\[:\Q$title\E\]\]/;
            $txt .= "* [$time] Would delete [[:$title]]\n";
            $count++;
        }
        if ( $count > 0 ) {
            my $res = $api->edit($tok, $txt, "Updating testing log, +$count", 0, 1);
            if ( $res->{'code'} ne 'success' ) {
                $api->warn("Failed to post testing log: " . $res->{'error'} . "\n");
            }
        }
    }

    return 3600;
}

1;