Jump to content

User:Lowercase sigmabot II/Source.py

From Wikipedia, the free encyclopedia
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

Source as of 09:37, 28 December 2014 (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.

#!/home/sigma/.local/bin/python3
# -*- coding: utf-8 -*-
# LGPLv2+ license, look it up

import sys
import os
import builtins

import ceterach
import passwords

import mwparserfromhell as mwparser

builtins.print = lambda *args, **kwargs: None

def main():
    global api
    api = ceterach.api.MediaWiki("https://en.wikipedia.org/w/api.php")
    api.login("Lowercase sigmabot II", passwords.lcsb2)
    api.set_token("edit")
    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)",
                 "Template:Sandbox heading"
    }

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

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

    def check_if_heading_is_gone(self, box):
        tl = self.api.iterator(500, prop="templates", tlnamespace=10, tllimit=500, titles=box.title)
        res = {x['title'] for x in next(tl).get("templates", "")}
        return not res & self.TEMPLATES

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

if __name__ == "__main__":
    main()

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     *
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■-->
#!/home/sigma/.local/bin/python3
# -*- coding: utf-8 -*-
# LGPLv2+ license, look it up

import time
import os
import sys
import pickle
import threading

import arrow

import ceterach
import passwords

reset_text = "{{subst:Sandbox reset}}"
tpl_reset_text = "{{subst:Template sandbox reset}}"
 
def main():
    global api
    api = ceterach.api.MediaWiki("https://en.wikipedia.org/w/api.php")
    with open("opener.pkl", 'rb') as fp:
        api.opener = pickle.load(fp)
    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"
    )
    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",
                 "Wikipedia talk:Sandbox",
                 "Wikipedia talk:Tutorial/Editing/sandbox",
                 "Wikipedia talk:Tutorial/Formatting/sandbox",
                 "Wikipedia talk:Tutorial/Wikipedia links/sandbox",
                 "Wikipedia talk:Tutorial/Citing sources/sandbox",
                 "Wikipedia talk:Tutorial/Keep in mind/sandbox",
                 "User:Sandbox",
                 "Template:Template sandbox",
    }

    def __init__(self, api, shutoff="User:Lowercase sigmabot II/Shutoff"):
        self.api = api
        self.shutoff_page = api.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.
        print("Done with sleeping, clearing {!r}".format(box.title))
        self.api.login("Lowercase sigmabot II", passwords.lcsb2)
        self.api.set_token("edit")
        text = tpl_reset_text if box.namespace == 10 else reset_text
        box.edit(text, "Clearing sandbox) (bot", bot=True, force=True)

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

    def box_needs_reset(self, box):
        now = arrow.utcnow()
        three_min = arrow.util.timedelta(seconds=60 * 3)
        # there's probably a way to use MediaWiki.iterator(), but too lazy
        res = self.api.call(action="query", prop="revisions", titles=box.title, rvprop="timestamp", limit="2")
        str_stamp = next(iter(res["query"]["pages"].values()))["revisions"][0]["timestamp"]
        box_stamp = self.parse_date(str_stamp)
        if box_stamp < (now - three_min):
            return True
        return False

    def run(self):
        if not self.is_allowed:
            print("Check the shutoff page")
            return
        for sandbox in self.SANDBOXES:
            box = self.api.page(sandbox)
            if box.revision_user.name in ("Lowercase sigmabot II", "Hazard-Bot") or\
               box.content == reset_text:
                continue
            if self.box_needs_reset(box):
                print("Clearing {!r}".format(sandbox))
                print(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
                threading.Thread(target=self.wait, args=(box,)).start()

if __name__ == "__main__":
    main()