User:SandBot

From Brickipedia, the LEGO Wiki

SandBot is a bot that automatically clears the sandbox every hour. SandBot is maintained by ToaMeiko.

Administrators[edit | edit source]

If this bot is performing tasks it should not, shut it down immediately by changing the value of User:SandBot/Shutoff to false. If that does not stop the bot, block it.

Stop x nuvola.svg
Emergency robot shutdown button.

Source[edit | edit source]

SandBot is programmed in Python using a modified version of lowercase sigmabot II's source.

#!/home/sigma/.local/bin/python3
# -*- coding: utf-8 -*-
# LGPLv2+ license, look it up
 
import datetime
import time
import os
import sys
import threading
 
import ceterach
from ceterach import passwords
 
reset_text = "{{Please don't edit this line. Thanks!}}" 
def main():
    global api
    api = ceterach.api.MediaWiki("http://en.brickimedia.org/api.php")
    api.login("SandBot", passwords.sandbot)
    api.set_token("edit")
    bot = SandBot2(api)
    bot.run()
 
class SandBot2:
    SANDBOXES = ("Brickipedia:Sandbox",)
 
    def __init__(self, api, shutoff="User:SandBot/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("SandBot", ceterach.passwords.sandbot)
        self.api.set_token("edit")
        self.api.page(box.title).edit(reset_text, "Robot: Clearing sandbox", 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=6)#0 * 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 ("SandBot",) or\
		box.content == reset_text:
                continue
            if self.box_needs_reset(box):
                print("Clearing {!r}".format(sandbox))
                print(self.api.page(sandbox).edit(reset_text, "Robot: Clearing sandbox", 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()

Further information[edit | edit source]