Jump to content

User:Lowercase sigmabot II/Source.py

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Lowercase sigmabot II (talk | contribs) at 06:03, 26 August 2012 (Updating source) (bot). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

Source as of 06:03, 26 August 2012 (UTC).

Sandbot1.py

This task runs every minute. It checks if the following sandboxes have the {{Sandbox heading}} template;

If the template is not present on the sandbox, it prepends {{Sandbox heading}} <!-- Please leave this line alone! -->

to the page.

If the template is present, it does nothing.

#!/usr/bin/python3
# -*- coding: utf-8 -*-

import sys
import os

import ceterach

import mwparserfromhell as mwparser

def main():
    global api
    api = ceterach.api.MediaWiki("http://en.wikipedia.org/w/api.php")
    api.login("Lowercase sigmabot II", ceterach.passwords.lcsb2)
    bot = SandBot1(api)
    bot.run()

class SandBot1:
    REINSERT = "{{Please leave this line alone (SB)}}\n\n"
    SANDBOXES = ("Wikipedia:Sandbox",
                 "Wikipedia:Tutorial/Editing/sandbox",
                 "Wikipedia:Tutorial/Formatting/sandbox",
                 "Wikipedia:Tutorial/Wikipedia links/sandbox",
                 "Wikipedia:Tutorial/Citing sources/sandbox",
                 "Wikipedia:Tutorial/Keep in mind/sandbox"
    )
    TEMPLATES = ("Template:Please leave this line alone (Sandbox heading)",
                 "Template:Sandbox heading/noedit",
                 "Template:Sandbox header (do not remove)",
                 "Template:PLTLA (SH)",
                 "Template:Please leave this line alone (sandbox heading)"
    )

    def __init__(self, api, shutoff="User:Lowercase sigmabot/Shutoff"):
        self.api = api
        self.shutoff_page = api.page(shutoff)

    @property
    def is_allowed(self):
        return self.shutoff_page.content.lower() == "true"

    def get_templates_on(self, page):
        tl = tuple(self.api.prop(500, "templates", tlnamespace=10, titles=page))
        if not tl[0].get("templates", None):
            return
        for x in tl[0]["templates"]:
            yield self.api.page(x["title"])

    def check_if_heading_is_gone(self, box):
        templates_in_box = self.get_templates_on(box)
        return not ("Template:Sandbox heading" in [x.title for x in templates_in_box])

    def run(self):
        if not self.is_allowed:
            return
        for sandbox in self.SANDBOXES:
            print(sandbox)
            box = self.api.page(sandbox)
            if box.revision_user == "Lowercase sigmabot II":
                continue
            if self.check_if_heading_is_gone(box.title):
                box.prepend(self.REINSERT, summary="Reinserting sandbox header) (bot", bot=True)
                print("\thad a header reinserted!")

if __name__ == "__main__":
    main()
    api.logout()

Sandbot2.py

This task runs once per hour. It clears the sandboxes by replacing the content with the sandbox header, which looks like this:

{{Please leave this line alone (sandbox heading)}}<!--
*               Welcome to the sandbox!              *
*            Please leave this part alone            *
*           The page is cleared regularly            *
*     Feel free to try your editing skills below     *
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■-->
#!/usr/bin/python3
# -*- coding: utf-8 -*-

import datetime
import time
import os
import sys

import ceterach

reset_text = """{{Please leave this line alone (sandbox heading)}}<!--
*               Welcome to the sandbox!              *
*            Please leave this part alone            *
*           The page is cleared regularly            *
*     Feel free to try your editing skills below     *
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■-->
"""

def main():
    global api
    api = ceterach.api.MediaWiki("http://en.wikipedia.org/w/api.php")
    api.login("Lowercase sigmabot II", ceterach.passwords.lcsb2)
    bot = SandBot2(api)
    bot.run()

class SandBot2:
    SANDBOXES = ("Wikipedia:Sandbox",
                 "Wikipedia:Tutorial/Editing/sandbox",
                 "Wikipedia:Tutorial/Formatting/sandbox",
                 "Wikipedia:Tutorial/Wikipedia links/sandbox",
                 "Wikipedia:Tutorial/Citing sources/sandbox",
                 "Wikipedia:Tutorial/Keep in mind/sandbox"
    )

    def __init__(self, api, shutoff="User:Lowercase sigmabot II/Shutoff"):
        self.api = api
        self.shutoff_page = shutoff

    @property
    def is_allowed(self):
        return self.shutoff_page.content.lower() == "true"

    def wait(self, box):
        for __ in range(3):
            # Sleep for 3 minutes
            print("3 minute sleep on {!r}".format(box.title))
            time.sleep(60 * 3)
            if self.box_needs_reset(box):
                break
        # After the bot sleeps on this box for 9 minutes, it
        # will clear the box regardless.
        box.edit(reset_text, "Clearing sandbox) (bot", bot=True, force=True)

    def parse_date(self, date):
        return datetime.datetime.strptime(date, '%Y-%m-%dT%H:%M:%SZ')

    def box_needs_reset(self, box):
        now = datetime.datetime.utcnow()
        three_min = datetime.timedelta(seconds=60 * 3)
        res = tuple(api.prop(2, "revisions", titles=box.title, rvprop="timestamp"))
        box_stamp = self.parse_date(res[0]["revisions"][0]["timestamp"])
        return (box_stamp < now - three_min)

    def run(self):
        for sandbox in self.SANDBOXES:
            box = self.api.page(sandbox)
            if box.revision_user == "Lowercase sigmabot II":
                continue
            if self.box_needs_reset(box):
                print("Clearing {!r}".format(sandbox))
                box.edit(reset_text, "Clearing sandbox) (bot", bot=True, force=True)
            else:
                # The bot will fork, and continue on to the next sandbox
                # while the child process waits 3 to 9 minutes
                if os.fork() == 0: # Child process
                    self.wait(box) # Wait takes place in the child process
                    os._exit(0) # Exit the child process

if __name__ == "__main__":
    main()
    api.logout()