User:B-bot/source/Daily Page Creator

From Wikipedia, the free encyclopedia

This task will create daily pages if they do not exist. The list of pages is kept in a table at User:B-bot/Daily page creator pages.

    /// <summary>
    /// This task will create any daily pages that do not exist
    /// </summary>
    public class DailyPageCreator : BBotBase
    {
        #region Settings

        /// <summary>
        /// How many days in advance will the page be created?
        /// </summary>
        const int DaysInAdvance = 1;

        /// <summary>
        /// This page has the list of pages to be created
        /// </summary>
        const String ScriptPage = "User:B-bot/Daily page creator pages";

        /// <summary>
        /// Ignore anything in the file before this point
        /// </summary>
        const String PageListScriptStart = "==Page list==";

        #endregion

        /// <summary>
        /// Gets the name for this job
        /// </summary>
        /// <returns></returns>
        public override string GetJobName()
        {
            return "Daily Page Creator";
        }

        /// <summary>
        /// The master function to perform the job
        /// </summary>
        public void PerformTask()
        {
            try
            {
                // Connect to Wikipedia
                Site site = TryToConnect("https://en.wikipedia.org", Properties.Settings.Default.BotUserName, Properties.Settings.Default.BotPassword);

                SleepApiDelay();

                // Log the start
                if (UserspaceTest)
                {
                    LogToEventLog(ref site, MessageType.Start, "B-Bot \"Daily Page Creator\" process now commencing <font color='red'>'''IN TEST MODE'''</font>.", null);
                }
                else
                {
                    LogToEventLog(ref site, MessageType.Start, "B-Bot \"Daily Page Creator\" process now commencing.", null);
                }

                SleepApiDelay();

                // Load the script
                Page pgScript = new Page(site, ScriptPage);
                pgScript.LoadTextOnly();

                // We are looking for something formatted like this:

                //==Page list==

                //{| border=1 cellpadding=2 cellspacing=0 cellalign=top
                //|+
                //| '''Daily page format string''' || '''Template format string''' (omit the <nowiki>{{subst:</nowiki> and <nowiki>}}</nowiki>
                //|-
                //|| Category:Wikipedia files missing permission as of {0:d MMMM yyyy}
                //|| Files missing permission subcategory starter|1={0:dd}|2={0:MMMM}|4={0:yyyy}
                //|}

                int intPageListSectionStarts = pgScript.text.IndexOf(PageListScriptStart);

                if (0 > intPageListSectionStarts)
                {
                    LogToEventLog(ref site, MessageType.Error, "[[" + ScriptPage + "]] does not contain " + PageListScriptStart + ".  Aborting", null);
                    return;
                }

                String PageList = pgScript.text.Substring(intPageListSectionStarts);

                // Now, ignore anything before the first |-
                int intTableStart = PageList.IndexOf("|-");

                if (0 > intTableStart)
                {
                    LogToEventLog(ref site, MessageType.Error, "Cannot find the start of the table in [[" + ScriptPage + "]] - the data portion of the table (not the header) should start with |- (all content before |- is ignored).  Aborting", null);
                    return;
                }

                PageList = PageList.Substring(intTableStart);

                // Now, find |} and end there
                int intTableEnd = PageList.IndexOf("|}");

                if (0 > intTableEnd)
                {
                    LogToEventLog(ref site, MessageType.Error, "Cannot find the end of the table in [[" + ScriptPage + "]] - the data portion of the table should end with |} (all content after |} is ignored).  Aborting", null);
                    return;
                }

                PageList = PageList.Substring(0, intTableEnd);

                // Now, split up the commands
                String[] arrCommands = PageList.Split(new String[] { "|-" }, StringSplitOptions.RemoveEmptyEntries);

                int intPagesCreated = 0;

                // Loop through the commands
                foreach (String strCommand in arrCommands)
                {
                    String strTrimCommand = strCommand.Trim();

                    if ("" == strTrimCommand)
                    {
                        continue;
                    }

                    String[] arrData = strTrimCommand.Split(new String[] { "||" }, StringSplitOptions.RemoveEmptyEntries);

                    if (2 != arrData.Length)
                    {
                        LogToEventLog(ref site, MessageType.Error, "Error parsing command: <code><nowiki>" + strTrimCommand + "</nowiki></code>.  There appear to be more than two lines.  Aborting", null);
                        return;
                    }

                    // Loop through the days
                    for (int intDay = -1; intDay <= DaysInAdvance; intDay++)
                    {
                        DateTime dtm = DateTime.UtcNow.AddDays(intDay);

                        String strPageName = String.Format(arrData[0], dtm).Trim();
                        String strTemplate = "{{subst:" + String.Format(arrData[1].Trim(), dtm) + "}}";

                        // Does the page already exist?
                        Page pg = new Page(site, strPageName);
                        pg.Load();

                        SleepApiDelay();

                        if (!pg.Exists())
                        {
                            // Only create yesterday or today if the category is not empty
                            if ((intDay <= 0) && strPageName.ToLower().StartsWith("category:"))
                            {
                                CreateCatIfNeeded(ref site, null, strPageName, strTemplate);
                            }
                            else
                            {
                                if (UserspaceTest)
                                {
                                    LogToEventLog(ref site, MessageType.Informational, "TEST MODE: Would create [[:" + strPageName + "]] using <code><nowiki>" + strTemplate + "</nowiki></code>.", null);
                                }
                                else
                                {
                                    LogToEventLog(ref site, MessageType.Informational, "Now creating [[:" + strPageName + "]] using <code><nowiki>" + strTemplate + "</nowiki></code>.", null);
                                    SleepApiDelay();
                                    pg.text = strTemplate;
                                    pg.Save("Creating dated category using " + strTemplate, false);

                                    intPagesCreated++;
                                }
                            }

                            SleepTaggingDelay();
                        }
                        else if (UserspaceTest)
                        {
                            LogToEventLog(ref site, MessageType.Informational, "TEST MODE: [[:" + strPageName + "]] ALREADY EXISTS so in live mode, I would do nothing.  If it didn't exist, I would create it using <code><nowiki>" + strTemplate + "</nowiki></code>.", null);

                            SleepApiDelay();
                        }
                    }
                }

                LogToEventLog(ref site, MessageType.Finish, "Process complete.  Created " + intPagesCreated.ToString() + " pages.", null);
            }
            catch (Exception ex)
            {
                SleepApiDelay();

                // Use a separate connection for our less-important API calls
                Site site2 = TryToConnect("https://en.wikipedia.org", Properties.Settings.Default.BotUserName, Properties.Settings.Default.BotPassword);

                SleepApiDelay();

                LogToEventLog(ref site2, MessageType.Error, "Exception in DailyPageCreator.  Aborting task", ex);
            }
        }
    }