User:B-bot/source/OTRS Dated Filer - Wikipedia
Article Images
This task will create monthly categories for {{OTRS pending}} and {{OTRS received}}. It will check for templates missing a date and add it to them.
public class OtrsDatedFiler : BBotBase { /// <summary> /// Gets the name for this job /// </summary> /// <returns></returns> public override string GetJobName() { return "OTRS dated filer"; } /// <summary> /// Both tasks will do this many. (If you want 50 edits, make this 25.) /// </summary> public int MaximumImagesToProcess = 1000; /// <summary> /// This function creates the requested category if it does not already exist /// </summary> /// <param name="CategoryName"></param> /// <param name="StarterTemplate"></param> /// <returns></returns> public bool CreateCatIfNeeded(ref Site site, Page pgUserspaceTest, String CategoryName, String StarterTemplate) { try { // Make sure that this month's and next month's dated categories exist Page cat = new Page(site, CategoryName); cat.Load(); SleepApiDelay(); if (!cat.Exists()) { cat.text = StarterTemplate; if (UserspaceTest) { pgUserspaceTest.text += "|-\r\n| [[:" + cat.title + "]] || ~~~~~ || <pre>" + cat.text.Substring(0, Math.Min(300, cat.text.Length)) + "</pre>\r\n"; pgUserspaceTest.Save("Creating monthly category", false); } else { cat.Save(cat.text, "Creating monthly category", false); } SleepApiDelay(); LogToEventLog(ref site, MessageType.Informational, "Created category [[:" + CategoryName + "]] using <code><nowiki>" + StarterTemplate + "</nowiki></code>.", null); } SleepApiDelay(); return true; } catch (Exception ex) { LogToEventLog(ref site, MessageType.Informational, "Error creating category [[:" + CategoryName + "]] using <code><nowiki>" + StarterTemplate + "</nowiki></code>.", ex); return false; } } /// <summary> /// This function will add the date to the requested /// </summary> /// <param name="site"></param> /// <param name="pg"></param> /// <param name="strRegex"></param> /// <param name="strTagName">"OTRS Pending", "OTRS received", etc</param> /// <param name="pgUserspaceTest">If this is a userspace test, the page on which that is being conducted</param> /// <param name="strCategoryFormatString">Format string to be used if we need to create the category</param> /// <param name="StarterTemplate">Starter template, if we need to create the category</param> /// <returns>True if the tag was modified, false otherwise</returns> public bool DateTag(Site site, Page pg, String strRegex, String strTagName, Page pgUserspaceTest, String strCategoryFormatString, String StarterTemplate) { try { // If this is a user talk base page, then {{OTRS pending}} has probably been added to the wrong place if (pg.title.ToLower().StartsWith("user talk:") && !pg.title.Contains("/")) { LogToEventLog(ref site, MessageType.Error, "Error: [[" + pg.title + "]] has a {{tl|" + strTagName + "}} tag. " + "This tag should only be placed on file pages or article talk pages (including talk pages of draft articles). " + "It should not be placed directly on user talk pages.", null); return false; } pg.Load(); // Find the OTRS pending tag Match match = Regex.Match(pg.text, strRegex, RegexOptions.IgnoreCase); if (null != match && 0 < match.Length) { // Remove the tag from the string String strNewText = ""; if (0 < match.Index) { strNewText = pg.text.Substring(0, match.Index); } // This is the tag, without the close String strTag = pg.text.Substring(match.Index, match.Length).Replace("}}", ""); // If the tag appears to already have a date, then move on if (strTag.Contains("date") || strTag.Contains("year") || strTag.Contains("month") || strTag.Contains("day")) { LogToEventLog(ref site, MessageType.Error, "Wanted to add a date to the " + strTagName + " tag of [[:" + pg.title + "]], but it seems to already have one. Maybe the page has multiple tags?", null); return false; } // Grab the timestamp (it gets blown away once we save) DateTime dtmTimestamp = pg.timestamp; // Add the date strTag += "|year=" + dtmTimestamp.Year.ToString() + "|month=" + dtmTimestamp.Month.ToString("00") + "|day=" + dtmTimestamp.Day.ToString("00") + "}}"; strNewText += strTag; // Add everything after the tag if (match.Index + match.Length < pg.text.Length - 1) { strNewText += pg.text.Substring(match.Index + match.Length); } // Trim whitespace strNewText = strNewText.Trim(); String strEditSummary = "Adding date to [[Template:" + strTagName + "|" + strTagName + "]] tag."; if (UserspaceTest) { pgUserspaceTest.text += "|-\r\n| [[:" + pg.title + "]] || ~~~~~ || <pre>" + pg.text.Substring(0, Math.Min(1500, pg.text.Length)) + "</pre> || <pre>" + strNewText.Substring(0, Math.Min(1500, strNewText.Length)) + "</pre>\r\n"; pgUserspaceTest.Save(strEditSummary, false); } else { pg.Save(strNewText, strEditSummary, false); } // Now, if that tag is more than a month ago, we need to check the category name to see if it exists if ((DateTime.Now - dtmTimestamp).TotalDays > 30) { CreateCatIfNeeded(ref site, pgUserspaceTest, String.Format(strCategoryFormatString, dtmTimestamp), String.Format(StarterTemplate, dtmTimestamp)); } return true; } else { LogToEventLog(ref site, MessageType.Error, "Error: though [[:" + pg.title + "]] is categorized as having an undated {{tl|" + strTagName + "}} tag, the tag could not be located.", null); } } catch (Exception ex) { LogToEventLog(ref site, MessageType.Error, "Error dating " + strTagName + " tag for page [[:" + pg.title + "]].", ex); } return false; } /// <summary> /// This function will perform the task /// </summary> public void PerformTask() { // OTRS pending categories const String csOtrsPendingUnknownDateCategoryName = "Category:Items pending OTRS confirmation of permission as of unknown date"; const String csDatedOtrsPendingCategoryFormatString = "Category:Items pending OTRS confirmation of permission as of {0:MMMM yyyy}"; String strDatedOtrsPendingCategoryThisMonth = String.Format(csDatedOtrsPendingCategoryFormatString, DateTime.Now); String strDatedOtrsPendingCategoryNextMonth = String.Format(csDatedOtrsPendingCategoryFormatString, DateTime.Now.AddMonths(1)); const String csDatedOtrsPendingCategoryStarterString = "{{{{subst:OTRS pending subcat starter|date={0:yyyy-MM-dd}}}}}"; String strDatedOtrsPendingCategoryStarterThisMonth = String.Format(csDatedOtrsPendingCategoryStarterString, DateTime.Parse(DateTime.Now.AddMonths(1).ToString("MM-01-yyyy")).AddDays(-1)); String strDatedOtrsPendingCategoryStarterNextMonth = String.Format(csDatedOtrsPendingCategoryStarterString, DateTime.Parse(DateTime.Now.AddMonths(2).ToString("MM-01-yyyy")).AddDays(-1)); // OTRS received categories (files) const String csOtrsReceivedFilesUnknownDateCategoryName = "Category:Wikipedia files with unconfirmed permission received by OTRS as of unknown date"; const String csDatedOtrsReceivedFilesCategoryFormatString = "Category:Wikipedia files with unconfirmed permission received by OTRS as of {0:MMMM yyyy}"; String strDatedOtrsReceivedFilesCategoryThisMonth = String.Format(csDatedOtrsReceivedFilesCategoryFormatString, DateTime.Now); String strDatedOtrsReceivedFilesCategoryNextMonth = String.Format(csDatedOtrsReceivedFilesCategoryFormatString, DateTime.Now.AddMonths(1)); const String csDatedOtrsReceivedFilesCategoryStarterString = "{{{{subst:OTRS received subcat starter|date={0:yyyy-MM-dd}|type=files}}}}"; String strDatedOtrsReceivedFilesCategoryStarterThisMonth = String.Format(csDatedOtrsReceivedFilesCategoryStarterString, DateTime.Parse(DateTime.Now.AddMonths(1).ToString("MM-01-yyyy")).AddDays(-1)); String strDatedOtrsReceivedFilesCategoryStarterNextMonth = String.Format(csDatedOtrsReceivedFilesCategoryStarterString, DateTime.Parse(DateTime.Now.AddMonths(2).ToString("MM-01-yyyy")).AddDays(-1)); // OTRS received categories (pages) const String csOtrsReceivedPagesUnknownDateCategoryName = "Category:Wikipedia pages with unconfirmed permission received by OTRS as of unknown date"; const String csDatedOtrsReceivedPagesCategoryFormatString = "Category:Wikipedia pages with unconfirmed permission received by OTRS as of {0:MMMM yyyy}"; String strDatedOtrsReceivedPagesCategoryThisMonth = String.Format(csDatedOtrsReceivedPagesCategoryFormatString, DateTime.Now); String strDatedOtrsReceivedPagesCategoryNextMonth = String.Format(csDatedOtrsReceivedPagesCategoryFormatString, DateTime.Now.AddMonths(1)); const String csDatedOtrsReceivedPagesCategoryStarterString = "{{{{subst:OTRS received subcat starter|date={0:yyyy-MM-dd}|type=pages}}}}"; String strDatedOtrsReceivedPagesCategoryStarterThisMonth = String.Format(csDatedOtrsReceivedPagesCategoryStarterString, DateTime.Parse(DateTime.Now.AddMonths(1).ToString("MM-01-yyyy")).AddDays(-1)); String strDatedOtrsReceivedPagesCategoryStarterNextMonth = String.Format(csDatedOtrsReceivedPagesCategoryStarterString, DateTime.Parse(DateTime.Now.AddMonths(2).ToString("MM-01-yyyy")).AddDays(-1)); // Connect to Wikipedia Site site = TryToConnect("https://en.wikipedia.org", Properties.Settings.Default.BotUserName, Properties.Settings.Default.BotPassword); // Use a separate connection for our API calls - this seems to time out less frequently Site site2 = TryToConnect("https://en.wikipedia.org", Properties.Settings.Default.BotUserName, Properties.Settings.Default.BotPassword); // Grab the list of pages in the category PageList pl = new PageList(site); pl.FillAllFromCategory(csOtrsPendingUnknownDateCategoryName); SleepApiDelay(); if (UserspaceTest) { LogToEventLog(ref site, MessageType.Start, "B-Bot \"OTRS Dated Filer\" process now commencing <font color='red'>'''IN TEST MODE'''</font>. This process checks pages from [[:" + csOtrsPendingUnknownDateCategoryName + "]] to add the date stamp where it is missing.", null); } else { LogToEventLog(ref site, MessageType.Start, "B-Bot \"OTRS Dated Filer\" process now commencing. This process checks pages from [[:" + csOtrsPendingUnknownDateCategoryName + "]] to add the date stamp where it is missing.", null); } int intPagesTagged = 0; Page pgUserspaceTest = new Page(site, Properties.Settings.Default.UserspaceTestPage); // Add the userspace test header if (UserspaceTest) { pgUserspaceTest.text = "Now beginning OTRS Dated Filer task on " + DateTime.Now.ToString() + " (local time) ...\r\n\r\n"; pgUserspaceTest.text += "{| class=\"wikitable sortable\"\r\n|-\r\n! Page !! Timestamp !! Former text !! Proposed text\r\n"; pgUserspaceTest.Save(); } SleepApiDelay(); // Make sure that this month's and next month's dated categories exist CreateCatIfNeeded(ref site, pgUserspaceTest, strDatedOtrsPendingCategoryThisMonth, strDatedOtrsPendingCategoryStarterThisMonth); SleepApiDelay(); CreateCatIfNeeded(ref site, pgUserspaceTest, strDatedOtrsPendingCategoryNextMonth, strDatedOtrsPendingCategoryStarterNextMonth); SleepApiDelay(); // Loop through each page foreach (Page pgCurrentImagePage in pl) { // Ignore things that are not in a valid namespace if (pgCurrentImagePage.GetNamespace() != 6 && // file pgCurrentImagePage.GetNamespace() != 119 && // draft talk pgCurrentImagePage.GetNamespace() != 118 && // draft pgCurrentImagePage.GetNamespace() != 3 && // user talk pgCurrentImagePage.GetNamespace() != 5) // WP: talk { continue; } // Find the OTRS pending tag DateTag(site, pgCurrentImagePage, @"\{\{\s*(template\:|)otrs(\s|-|)pending([^\{^\}]*|)\}\}", "OTRS pending", pgUserspaceTest, csDatedOtrsPendingCategoryFormatString, csDatedOtrsPendingCategoryStarterString); SleepApiDelay(); if (BotStop(site)) { LogToEventLog(ref site, MessageType.Error, "I was ordered to abort.", null); return; } intPagesTagged++; SleepApiDelay(); if (intPagesTagged >= MaximumImagesToProcess) { break; } } LogToEventLog(ref site2, MessageType.Informational, "B-Bot finished adding OTRS pending dates. " + intPagesTagged.ToString() + " pages were edited. Will now check category [[:" + csOtrsReceivedFilesUnknownDateCategoryName + "]]", null); // Now, do OTRS received (files) // Grab the list of pages in the category pl = new PageList(site); pl.FillAllFromCategory(csOtrsReceivedFilesUnknownDateCategoryName); SleepApiDelay(); intPagesTagged = 0; SleepApiDelay(); // Make sure that this month's and next month's dated categories exist CreateCatIfNeeded(ref site, pgUserspaceTest, strDatedOtrsReceivedFilesCategoryThisMonth, strDatedOtrsReceivedFilesCategoryStarterThisMonth); SleepApiDelay(); CreateCatIfNeeded(ref site, pgUserspaceTest, strDatedOtrsReceivedFilesCategoryNextMonth, strDatedOtrsReceivedFilesCategoryStarterNextMonth); SleepApiDelay(); // Loop through each page foreach (Page pgCurrentImagePage in pl) { // Find the OTRS pending tag DateTag(site, pgCurrentImagePage, @"\{\{\s*(template\:|)otrs(\s|-|)(received|insufficient)([^\{^\}]*|)\}\}", "OTRS received", pgUserspaceTest, csDatedOtrsReceivedFilesCategoryFormatString, csDatedOtrsReceivedFilesCategoryStarterString); SleepApiDelay(); if (BotStop(site)) { LogToEventLog(ref site, MessageType.Error, "I was ordered to abort.", null); return; } intPagesTagged++; SleepApiDelay(); if (intPagesTagged >= MaximumImagesToProcess) { break; } } LogToEventLog(ref site2, MessageType.Informational, "B-Bot finished adding OTRS received dates to files. " + intPagesTagged.ToString() + " files were edited. Will now check category [[:" + csOtrsReceivedPagesUnknownDateCategoryName + "]]", null); intPagesTagged = 0; // Now OTRS received pages // Grab the list of pages in the category pl = new PageList(site); pl.FillAllFromCategory(csOtrsReceivedPagesUnknownDateCategoryName); SleepApiDelay(); // Make sure that this month's and next month's dated categories exist CreateCatIfNeeded(ref site, pgUserspaceTest, strDatedOtrsReceivedPagesCategoryThisMonth, strDatedOtrsReceivedPagesCategoryStarterThisMonth); SleepApiDelay(); CreateCatIfNeeded(ref site, pgUserspaceTest, strDatedOtrsReceivedPagesCategoryNextMonth, strDatedOtrsReceivedPagesCategoryStarterNextMonth); SleepApiDelay(); // Loop through each page foreach (Page pgCurrentImagePage in pl) { // Find the OTRS pending tag DateTag(site, pgCurrentImagePage, @"\{\{\s*(template\:|)otrs(\s|-|)(received|insufficient)([^\{^\}]*|)\}\}", "OTRS received", pgUserspaceTest, csDatedOtrsReceivedPagesCategoryFormatString, csDatedOtrsReceivedPagesCategoryStarterString); SleepApiDelay(); if (BotStop(site)) { LogToEventLog(ref site, MessageType.Error, "I was ordered to abort.", null); return; } intPagesTagged++; SleepApiDelay(); if (intPagesTagged >= MaximumImagesToProcess) { break; } } LogToEventLog(ref site2, MessageType.Informational, "B-Bot finished adding OTRS received dates to pages. " + intPagesTagged.ToString() + " pages were edited.", null); LogToEventLog(ref site2, MessageType.Finish, "B-Bot OTRS Dated Filer process completed.", null); if (UserspaceTest) { pgUserspaceTest.text += "|}\r\n"; pgUserspaceTest.Save(); } }