User:B-bot/source/OTRS Dated Filer
This task will create monthly categories for {{tl|OTRS pending}} and {{tl|OTRS received}}. It will check for templates missing a date and add it to them.
public class OtrsDatedFiler : BBotBase
{
///
/// Gets the name for this job
///
///
public override string GetJobName()
{
return "OTRS dated filer";
}
///
/// Both tasks will do this many. (If you want 50 edits, make this 25.)
///
public int MaximumImagesToProcess = 1000;
///
/// This function creates the requested category if it does not already exist
///
///
///
///
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 + " || ~~~~~ ||
" + cat.text.Substring(0, Math.Min(300, cat.text.Length)) + "\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
.", null);
}
SleepApiDelay();
return true;
}
catch (Exception ex)
{
LogToEventLog(ref site, MessageType.Informational, "Error creating category :" + CategoryName + " using
.", ex);
return false;
}
}
///
/// This function will add the date to the requested
///
///
///
///
/// "OTRS Pending", "OTRS received", etc
/// If this is a userspace test, the page on which that is being conducted
/// Format string to be used if we need to create the category
/// Starter template, if we need to create the category
///
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 " + strTagName + " tag.";
if (UserspaceTest)
{
pgUserspaceTest.text += "|-\r\n| :" + pg.title + " || ~~~~~ ||
" +||pg.text.Substring(0, Math.Min(1500, pg.text.Length)) +
"
" + strNewText.Substring(0, Math.Min(1500, strNewText.Length)) + "\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;
}
///
/// This function will perform the task
///
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 IN TEST MODE. 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 += " |
pgUserspaceTest.Save();
}
}