From 8cd2c8d125dedef7938ab5e6c91796b1aa2295b0 Mon Sep 17 00:00:00 2001 From: Joscha Date: Fri, 12 Apr 2019 12:53:34 +0000 Subject: [PATCH] Use config files for bots --- README.md | 16 ++++------------ examples/echo/bot.conf | 5 +++++ examples/{ => echo}/echobot.py | 11 ++++------- yaboli/bot.py | 18 ++++++++++++++++-- yaboli/client.py | 7 +++---- yaboli/module.py | 8 ++++---- 6 files changed, 36 insertions(+), 29 deletions(-) create mode 100644 examples/echo/bot.conf rename examples/{ => echo}/echobot.py (76%) diff --git a/README.md b/README.md index 941d270..ee4dddc 100644 --- a/README.md +++ b/README.md @@ -13,36 +13,28 @@ A simple echo bot that conforms to the ```python class EchoBot(yaboli.Bot): - DEFAULT_NICK = "EchoBot" HELP_GENERAL = "/me echoes back what you said" HELP_SPECIFIC = [ "This bot only has one command:", "!echo – reply with exactly ", ] - def __init__(self): - super().__init__() + def __init__(self, config_file): + super().__init__(config_file) self.register_botrulez() self.register_general("echo", self.cmd_echo) - async def started(self): - await self.join("test") - async def cmd_echo(self, room, message, args): await message.reply(args.raw) ``` -When joining a room, the bot sets its nick to the value in `DEFAULT_NICK`. +The bot's nick and default rooms are specified in a config file. The help command from the botrulez uses the `HELP_GENERAL` and `HELP_SPECIFIC` fields. In the `__init__` function, the bot's commands are registered. -The `started` function is called when the bot has been started and is ready to -connect to rooms and do other bot stuff. It can be used to load config files or -directly connect to rooms. - In the `cmd_echo` function, the echo command is implemented. In this case, the bot replies to the message containing the command with the raw argument string, i. e. the text between the end of the "!echo" and the end of the whole message. @@ -50,7 +42,6 @@ i. e. the text between the end of the "!echo" and the end of the whole message. ## TODOs - [ ] implement !restart and add an easier way to run bots -- [ ] config file support for bots, used by default - [ ] package in a distutils-compatible way (users should be able to install yaboli using `pip install git+https://github.com/Garmelon/yaboli`) - [ ] document yaboli (markdown files in a "docs" folder?) @@ -63,3 +54,4 @@ i. e. the text between the end of the "!echo" and the end of the whole message. - [x] implement !uptime for proper botrulez conformity - [x] implement !kill - [x] untruncate LiveMessage-s +- [x] config file support for bots, used by default diff --git a/examples/echo/bot.conf b/examples/echo/bot.conf new file mode 100644 index 0000000..87719ea --- /dev/null +++ b/examples/echo/bot.conf @@ -0,0 +1,5 @@ +[basic] +name = EchoBot + +[rooms] +test diff --git a/examples/echobot.py b/examples/echo/echobot.py similarity index 76% rename from examples/echobot.py rename to examples/echo/echobot.py index c462b64..7f5b103 100644 --- a/examples/echobot.py +++ b/examples/echo/echobot.py @@ -2,27 +2,24 @@ import asyncio import yaboli + class EchoBot(yaboli.Bot): - DEFAULT_NICK = "EchoBot" HELP_GENERAL = "/me echoes back what you said" HELP_SPECIFIC = [ "This bot only has one command:", "!echo – reply with exactly ", ] - def __init__(self): - super().__init__() + def __init__(self, config_file): + super().__init__(config_file) self.register_botrulez() self.register_general("echo", self.cmd_echo) - async def started(self): - await self.join("test") - async def cmd_echo(self, room, message, args): await message.reply(args.raw) async def main(): - bot = EchoBot() + bot = EchoBot("bot.conf") await bot.run() if __name__ == "__main__": diff --git a/yaboli/bot.py b/yaboli/bot.py index 92e55ab..3ca7171 100644 --- a/yaboli/bot.py +++ b/yaboli/bot.py @@ -1,3 +1,4 @@ +import configparser import datetime import logging from typing import List, Optional @@ -18,13 +19,26 @@ class Bot(Client): HELP_SPECIFIC: Optional[List[str]] = None KILL_REPLY: str = "/me dies" - def __init__(self) -> None: - super().__init__() + BASIC_SECTION = "basic" + ROOMS_SECTION = "rooms" + + def __init__(self, config_file: str) -> None: + self.config = configparser.ConfigParser(allow_no_value=True) + self.config.read(config_file) + + super().__init__(self.config[self.BASIC_SECTION].get("name", "")) self._commands: List[Command] = [] self.start_time = datetime.datetime.now() + async def started(self) -> None: + for room, password in self.config[self.ROOMS_SECTION].items(): + if password is None: + await self.join(room) + else: + await self.join(room, password=password) + # Registering commands def register(self, command: Command) -> None: diff --git a/yaboli/client.py b/yaboli/client.py index c1f19ff..e937a82 100644 --- a/yaboli/client.py +++ b/yaboli/client.py @@ -12,9 +12,8 @@ logger = logging.getLogger(__name__) __all__ = ["Client"] class Client: - DEFAULT_NICK = "" - - def __init__(self) -> None: + def __init__(self, default_nick: str) -> None: + self._default_nick = default_nick self._rooms: Dict[str, List[Room]] = {} self._stop = asyncio.Event() @@ -54,7 +53,7 @@ class Client: logger.info(f"Joining &{room_name}") if nick is None: - nick = self.DEFAULT_NICK + nick = self._default_nick room = Room(room_name, password=password, target_nick=nick) room.register_event("snapshot", diff --git a/yaboli/module.py b/yaboli/module.py index 3fe1baf..2dc9b0f 100644 --- a/yaboli/module.py +++ b/yaboli/module.py @@ -15,8 +15,8 @@ __all__ = ["Module", "ModuleBot"] class Module(Bot): DESCRIPTION: Optional[str] = None - def __init__(self, standalone: bool) -> None: - super().__init__() + def __init__(self, config_file: str, standalone: bool) -> None: + super().__init__(config_file) self.standalone = standalone @@ -31,8 +31,8 @@ class ModuleBot(Bot): ] MODULE_HELP_LIMIT = 5 - def __init__(self) -> None: - super().__init__() + def __init__(self, config_file: str) -> None: + super().__init__(config_file) self.modules: Dict[str, Module] = {}