User:B-bot/source

The source code for User:B-bot uses the DotNetWikiBot framework. For the sake of brevity, I have omitted the things like my test functions or routine utility functions. (If a BAG member needs the whole thing, please let me know and perhaps I can email you the entire solution.)

Source code for individual tasks

Each task has its own class and they are all derived from a common class that has some shared functions that do things like checking for {{bots}} tags, unescaping strings (which oddly, though I tried to find a built-in method, there didn't seem to be one), managing connections and delay times, and other miscellanea.

The source code for tasks of this bot can be found at these pages:

Bot edit permitted

This is the code used by any bot I create to check to see if a bot is permitted to edit a user page to leave a notification. It handles some possibilities that the examples at {{bots}} do not.

/// <summary>
/// This function will remove commented uses of the {{nobots}} or {{bots}} template so that they are 
/// not considered in the BotEditPermitted() function.
/// </summary>
/// <param name="PageText"></param>
/// <param name="CommentStart"></param>
/// <param name="CommentEnd"></param>
/// <returns></returns>
private static String RemoveComment(String PageText, String CommentStart, String CommentEnd)
{
    // Remove anything that is inside of <nowiki> ... <nowiki> or <!-- ... -->
    for (int nowiki = PageText.IndexOf(CommentStart, StringComparison.CurrentCultureIgnoreCase); 0 <= nowiki; nowiki = PageText.IndexOf(CommentStart, StringComparison.CurrentCultureIgnoreCase))
    {
        int endnowiki = PageText.IndexOf(CommentEnd, nowiki, StringComparison.CurrentCultureIgnoreCase);

        if (0 <= endnowiki)
        {
            String NewText = "";
            if (0 < nowiki)
            {
                NewText = PageText.Substring(0, nowiki);
            }

            if (endnowiki + CommentEnd.Length < PageText.Length)
            {
                NewText += PageText.Substring(endnowiki + CommentEnd.Length);
            }

            PageText = NewText;
        }
        else
        {
            // If the comment doesn't end, then we're done
            return PageText;
        }
    }

    return PageText;
}

/// <summary>
/// This function attempts to parse the page text for the {{bots}} and {{nobots}} templates.
/// 
/// {{nobots}} will be checked for allow=BotUserName or optin=BotNotificationType
/// {{nobots}} can also be superseded by a {{bots|allow=BotUserName}} or {{bots|optin=BotNotificationType}}
/// 
/// {{bots|allow=Bot1,Bot2}} is interpreted as disallowing everything but Bot1 and Bot2 unless another {{bots}} statement is found
/// </summary>
/// <param name="PageText">The page text to be parsed.</param>
/// <param name="BotUserName">This bot's username, this function will check for it in "allow" or "deny".  IMPORTANT: </param>
/// <param name="BotNotificationType">The type of notification this bot is sending, e.g. nosource, nolicense, orfud.</param>
/// <returns>Returns true if this bot is permitted to edit the page and false if it is not.</returns>
public static bool BotEditPermitted(string PageText, string BotUserName, string BotNotificationType)
{
    try
    {
        // Remove comments from consideration
        PageText = RemoveComment(PageText, "<nowiki>", "</nowiki>");
        PageText = RemoveComment(PageText, "<code>", "</code>");
        PageText = RemoveComment(PageText, "<pre>", "</pre>");
        PageText = RemoveComment(PageText, "<!--", "-->");

        // Find all of the bots or nobots tags
        MatchCollection matches = Regex.Matches(PageText, @"\{\{\s*(nobots|bots|deceased wikipedian)[^\}\{]*\}\}", RegexOptions.IgnoreCase);

        if (null != matches && matches.Count > 0)
        {
            List<string> commands = new List<string>();

            foreach (Match m in matches)
            {
                if (0 < m.Length)
                {
                    // This is an individual bots tag to process
                    commands.Add(PageText.Substring(m.Index, m.Length).Trim());
                }
            }
                
            // Rule #1: if any command denies this bot by name, then disallow the edit
            if (!String.IsNullOrWhiteSpace(BotUserName))
            {
                foreach (String str in commands)
                {
                    if (Regex.IsMatch(str, @"\{\{\s*(nobots|bots).*deny\s*\=\s*([^\|]*\,|)\s*" + Regex.Escape(BotUserName) + @"\s*(\,[^\|]*|)(\|.*|)\s*\}\}", RegexOptions.IgnoreCase))
                    {
                        return false;
                    }
                }
            }

            // Rule #2 - if any command opts out of this notification type by name, then disallow the edit
            if (!String.IsNullOrWhiteSpace(BotNotificationType))
            {
                foreach (String str in commands)
                {
                    if (Regex.IsMatch(str, @"\{\{\s*(nobots|bots).*optout\s*\=\s*([^\|]*\,|)\s*" + Regex.Escape(BotNotificationType) + @"\s*(\,[^\|]*|)(\|.*|)\s*\}\}", RegexOptions.IgnoreCase))
                    {
                        return false;
                    }
                }
            }

            // Rule #3 - if any command allows this bot by name, then allow the edit
            if (!String.IsNullOrWhiteSpace(BotUserName))
            {
                foreach (String str in commands)
                {
                    if (Regex.IsMatch(str, @"\{\{\s*(nobots|bots).*allow\s*\=\s*([^\|]*\,|)\s*" + Regex.Escape(BotUserName) + @"\s*(\,[^\|]*|)(\|.*|)\s*\}\}", RegexOptions.IgnoreCase))
                    {
                        return true;
                    }
                }
            }

            // Rule #4 - if any command opts in to this notification type by name, then allow the edit
            if (!String.IsNullOrWhiteSpace(BotNotificationType))
            {
                foreach (String str in commands)
                {
                    if (Regex.IsMatch(str, @"\{\{\s*(nobots|bots).*optin\s*\=\s*([^\|]*\,|)\s*" + Regex.Escape(BotNotificationType) + @"\s*(\,[^\|]*|)(\|.*|)\s*\}\}", RegexOptions.IgnoreCase))
                    {
                        return true;
                    }
                }
            }

            // Rule #5 - if we have a {{bots|allow=all}} or {{nobots|allow=all}}, then allow the edit (does anyone do this?)
            foreach (String str in commands)
            {
                if (Regex.IsMatch(str, @"\{\{\s*(nobots|bots).*allow\s*\=\s*([^\|]*\,|)\s*all\s*(\,[^\|]*|)(\|.*|)\s*\}\}", RegexOptions.IgnoreCase))
                {
                    return true;
                }
            }

            // Rule #6 - if we have a {{(no)bots|allow=none}} or {{(no)bots|deny=all}}, then disallow the edit
            foreach (String str in commands)
            {
                if (Regex.IsMatch(str, @"\{\{\s*(nobots|bots).*(allow\s*\=\s*([^\|]*\,|)\s*none|deny\s*\=\s*([^\|]*\,|)\s*all)\s*(\,[^\|]*|)(\|.*|)\s*\}\}", RegexOptions.IgnoreCase))
                {
                    return false;
                }
            }

            // Rule #7 - if we have a {{nobots}} of any sort or a {{deceased wikipedian}} and we haven't found one of the exemptions above, then disallow the edit
            foreach (String str in commands)
            {
                if (Regex.IsMatch(str, @"\{\{\s*(nobots|deceased wikipedian).*\}\}", RegexOptions.IgnoreCase))
                {
                    return false;
                }
            }

            // Rule #8 - if we have a {{bots|allow=anything}} and we are not mentioned by name, then disallow the edit
            foreach (String str in commands)
            {
                if (Regex.IsMatch(str, @"\{\{\s*(nobots|bots).*allow\s*\=\s*.*\}\}", RegexOptions.IgnoreCase))
                {
                    return false;
                }
            }
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.ToString());
    }

    return true;
}

Content Disclaimer

Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.

  1. The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
  2. There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
  3. It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
  4. Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
  5. Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.