Allow for bots to be restarted and fix botrulez commands

This commit is contained in:
Joscha 2017-09-05 19:37:14 +00:00
parent 3d12b070e8
commit 3945c6ae45
3 changed files with 77 additions and 14 deletions

View file

@ -3,12 +3,12 @@ from yaboli.utils import *
#class TestBot(Bot):
class TestBot(yaboli.Bot):
def __init__(self, nick):
super().__init__(nick=nick)
self.register_callback("tree", self.command_tree, specific=False)
self.register_callback("stree", self.command_simple_tree, specific=False)
#async def on_send(self, message):
#if message.content == "!spawnevil":
@ -36,13 +36,20 @@ class TestBot(yaboli.Bot):
messages = [message]
newmessages = []
for i in range(2):
for m in messages:
for msg in messages:
for j in range(2):
newm = await self.room.send(f"{message.content}.{j}", m.message_id)
newm = await self.room.send(f"{msg.content}.{j}", msg.message_id)
newmessages.append(newm)
messages = newmessages
newmessages = []
async def command_simple_tree(self, message, args):
root = await self.room.send("root message", message.message_id)
branch1 = await self.room.send("branch 1", root.message_id)
branch2 = await self.room.send("branch 2", root.message_id)
await self.room.send("branch 1.1", branch1.message_id)
await self.room.send("branch 2.1", branch2.message_id)
await self.room.send("branch 1.2", branch1.message_id)
if __name__ == "__main__":
bot = TestBot("TestSummoner")
run_controller(bot, "test")
run_bot(TestBot, "test", "TestSummoner")

View file

@ -19,6 +19,7 @@ class Bot(Controller):
def __init__(self, nick):
super().__init__(nick)
self.restarting = False # whoever runs the bot can check if a restart is necessary
self.start_time = time.time()
self._callbacks = Callbacks()
@ -26,12 +27,26 @@ class Bot(Controller):
# settings (modify in your bot's __init__)
self.general_help = None # None -> does not respond to general help
self.specific_help = "No help available"
self.killable = True
self.kill_message = "/me *poof*" # how to respond to !kill, whether killable or not
self.restartable = True
self.restart_message = "/me temporary *poof*" # how to respond to !restart, whether restartable or not
def register_callback(self, event, callback, specific=True):
self._callbacks.add((event, specific), callback)
async def restart(self):
# After calling this, the bot is stopped, not yet restarted.
self.restarting = True
await self.stop()
def noargs(func):
async def wrapper(self, message, args):
if not args:
return await func(self, message)
return wrapper
async def on_send(self, message):
parsed = self.parse_message(message.content)
if not parsed:
@ -138,7 +153,7 @@ class Bot(Controller):
# BOTRULEZ COMMANDS
# BOTRULEZ AND YABOLI-SPECIFIC COMMANDS
def register_default_callbacks(self):
self.register_callback("ping", self.command_ping)
@ -147,19 +162,24 @@ class Bot(Controller):
self.register_callback("help", self.command_help_general, specific=False)
self.register_callback("uptime", self.command_uptime)
self.register_callback("kill", self.command_kill)
# TODO: maybe !restart command
self.register_callback("restart", self.command_restart)
async def command_ping(self, message, args):
@noargs
async def command_ping(self, message):
await self.room.send("Pong!", message.message_id)
async def command_help(self, message, args):
await self.room.send("<placeholder help>", message.message_id)
@noargs # TODO: specific command help (!help @bot ping)
async def command_help(self, message):
if self.specific_help:
await self.room.send(self.specific_help, message.message_id)
async def command_help_general(self, message, args):
@noargs
async def command_help_general(self, message):
if self.general_help is not None:
await self.room.send(self.general_help, message.message_id)
async def command_uptime(self, message, args):
@noargs
async def command_uptime(self, message):
now = time.time()
startformat = format_time(self.start_time)
deltaformat = format_time_delta(now - self.start_time)
@ -167,10 +187,19 @@ class Bot(Controller):
await self.room.send(text, message.message_id)
async def command_kill(self, message, args):
logging.warn(f"Kill attempt in &{self.room.roomname}: {message.content!r}")
logging.warn(f"Kill attempt by @{mention(message.sender.nick)} in &{self.room.roomname}: {message.content!r}")
if self.kill_message is not None:
await self.room.send(self.kill_message, message.message_id)
if self.killable:
await self.stop()
async def command_restart(self, message, args):
logging.warn(f"Restart attempt by @{mention(message.sender.nick)} in &{self.room.roomname}: {message.content!r}")
if self.restart_message is not None:
await self.room.send(self.restart_message, message.message_id)
if self.restartable:
await self.restart()

View file

@ -1,8 +1,10 @@
import asyncio
import logging
import time
logger = logging.getLogger(__name__)
__all__ = [
"run_controller",
"run_controller", "run_bot",
"mention", "mention_reduced", "similar",
"format_time", "format_time_delta",
"Session", "Listing",
@ -21,6 +23,31 @@ def run_controller(controller, room):
task, reason = await controller.connect(room)
if task:
await task
else:
logger.warn(f"Could not connect to &{room}: {reason!r}")
asyncio.get_event_loop().run_until_complete(run())
def run_bot(bot_class, room, *args, **kwargs):
"""
Helper function to run a bot. To run Multibots, use the MultibotKeeper.
This restarts the bot when it is explicitly restarted through Bot.restart().
"""
async def run():
while True:
logger.info(f"Creating new instance and connecting to &{room}")
bot = bot_class(*args, **kwargs)
task, reason = await bot.connect(room)
if task:
await task
else:
logger.warn(f"Could not connect to &{room}: {reason!r}")
if bot.restarting:
logger.info(f"Restarting in &{room}")
else:
break
asyncio.get_event_loop().run_until_complete(run())