User:MilHistBot/AutoCheck.cs

From Wikipedia, the free encyclopedia
using System;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
using NDesk.Options;

public class AutoCheck
{
    private Bot bot;

    private int unchanged;
    private int upgrade;
    private int newgrade;
    private int downgrade;

    private int  max     = 1;
    private bool debugs  = false;
    private bool force   = false;
    private bool help    = false;
    private bool verbose = false;
    private Dictionary<string, int> classes;

    private bool compareClass (string oldClass, string botClass)
    {
        if (null == classes)
        {
            classes = new Dictionary<string, int>()
            {
                { "Stub",  0 },
                { "Start", 1 },
                { "List",  1 },
                { "C",     2 },
                { "CL",    2 },
                { "B",     3 },
                { "BL",    3 },
            };
        }

        if (oldClass.Equals (""))
        {
            newgrade++;
            return true;
        }

        if (! classes.ContainsKey (oldClass))
        {
            throw new ApplicationException ("unknown class: '" + oldClass + "'");
        }

        int diff = classes[botClass] - classes[oldClass];
        if (0 > diff)
        {
            downgrade++;
        }
        else if (0 == diff)
        {
            unchanged++;
            return false;
        }
        else if (0 < diff)
        {
            upgrade++;
        }
        return true;
    }

    private void report ()
    {
        bot.Cred.Showtime (String.Format("{0} articles newly rated, {1} downgraded, {2} upgraded, {3} unchanged - total {4}",
                            newgrade, downgrade, upgrade, unchanged, newgrade + downgrade + upgrade + unchanged));
    }

    private void autoCheck (Page article, Page talk)
    {
        try
        {
            bot.Cred.Showtime (article.Title);
            article.Load ();
            talk.Load ();
            var template = talk.MilHist.ProjectTemplate;
            var oldClass = template.Class;
            var rating   = template.Rating;
            var botClass = rating.Class;

            template.RemoveAll (@"^class$|^importance$|^b\d$|^B-Class-\d$");
            template.Rating = rating;

            Debug.WriteLine ("\told rating = " + oldClass);
            Debug.WriteLine ("\tprediction = " + article.Prediction ());
            Debug.WriteLine ("\tbot rating = " + botClass);

            var changed = compareClass (oldClass, botClass);
            if (changed && force)
            {
                talk.Save ("Automatic MILHIST checklist assessment - " + botClass + " class");
                bot.Cred.Showtime ("\tChanged from " + oldClass + " to " + botClass);
            }
        }
        catch (ApplicationException ex)
        {
            string message = "Error in " + article.Title + ": " + ex.Message;
            bot.Cred.Showtime (message);
        }
        catch (Exception ex)
        {
            string message = "Error in " + article.Title + ":\n" + ex.Message + "\n" + ex.StackTrace;
            if (debugs)
            {
                Debug.WriteLine (message);
            }
            else
            {
                bot.Cred.Warning (message);
                bot.Close ();
            }
            Environment.Exit (1);
        }
    }

    private void autoCheck (List<Page> talkPages)
    {
        foreach (var talkPage in talkPages)
        {
            // Could be a subcategory
            if (talkPage.Namespace.Equals ("Talk"))
            {
                autoCheck (talkPage.Article, talkPage);
            }
        }
        report ();
    }

    private static void showHelp (OptionSet options)
    {
        Console.WriteLine ("Usage: mono AutoCheck [OPTIONS]+ <article>");
        Console.WriteLine ("Assess article and update the MilHist template on the talk page.");
        Console.WriteLine ();
        Console.WriteLine ("Options:");
        options.WriteOptionDescriptions (Console.Out);
        Environment.Exit (0);
    }

    List<string> options (string [] args)
    {
        var optionSet = new OptionSet () {
            { "d|debug",   "debugging",    v => debugs  = v != null },
            { "f|force",   "update page",  v => force   = v != null },
            { "h|?|help",  "display help", v => help    = v != null },
            { "n|max=",    "number of pages to process",  v => int.TryParse (v, out max) },
            { "v|verbose", "vebosity",     v => verbose = v != null },
        };

        List<string> extras = optionSet.Parse (args);

        if (help)
        {
            showHelp (optionSet);
        }

        return extras;
    }

    private AutoCheck (string [] args)
    {
        bot = new Bot ();
        var articles = options (args);
        Debug.On = debugs;
        Debug.Bot = bot;
        List<Page> talkPages;

        bot.Cred.Showtime ("started");
        if (articles.Count > 0)
        {
            var articlePage = new Page (bot, articles[0]);
            autoCheck (articlePage, articlePage.Talk);
        }
        else
        {
            var query = new Query ("Military history articles with missing B-Class checklists", max);
            talkPages = bot.Category (query);

            if (talkPages.Count < max)
            {
                query = new Query ("Military history articles with incomplete B-Class checklists", max - talkPages.Count);
                talkPages.AddRange (bot.Category (query));
            }

            if (talkPages.Count < max)
            {
                query = new Query ("Unassessed military history articles", max - talkPages.Count);
                talkPages.AddRange (bot.Category (query));
            }
            autoCheck (talkPages);
        }
        bot.Cred.Showtime ("done");
    }

    static public void Main (string [] args)
    {
        var autoCheck = new AutoCheck (args);
    }
}