Use config files for bots

This commit is contained in:
Joscha 2019-04-12 12:53:34 +00:00
parent a78f57db7a
commit 8cd2c8d125
6 changed files with 36 additions and 29 deletions

View file

@ -13,36 +13,28 @@ A simple echo bot that conforms to the
```python ```python
class EchoBot(yaboli.Bot): class EchoBot(yaboli.Bot):
DEFAULT_NICK = "EchoBot"
HELP_GENERAL = "/me echoes back what you said" HELP_GENERAL = "/me echoes back what you said"
HELP_SPECIFIC = [ HELP_SPECIFIC = [
"This bot only has one command:", "This bot only has one command:",
"!echo <text> reply with exactly <text>", "!echo <text> reply with exactly <text>",
] ]
def __init__(self): def __init__(self, config_file):
super().__init__() super().__init__(config_file)
self.register_botrulez() self.register_botrulez()
self.register_general("echo", self.cmd_echo) self.register_general("echo", self.cmd_echo)
async def started(self):
await self.join("test")
async def cmd_echo(self, room, message, args): async def cmd_echo(self, room, message, args):
await message.reply(args.raw) 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` The help command from the botrulez uses the `HELP_GENERAL` and `HELP_SPECIFIC`
fields. fields.
In the `__init__` function, the bot's commands are registered. 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 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, 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. 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 ## TODOs
- [ ] implement !restart and add an easier way to run bots - [ ] 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 - [ ] package in a distutils-compatible way (users should be able to install
yaboli using `pip install git+https://github.com/Garmelon/yaboli`) yaboli using `pip install git+https://github.com/Garmelon/yaboli`)
- [ ] document yaboli (markdown files in a "docs" folder?) - [ ] 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 !uptime for proper botrulez conformity
- [x] implement !kill - [x] implement !kill
- [x] untruncate LiveMessage-s - [x] untruncate LiveMessage-s
- [x] config file support for bots, used by default

5
examples/echo/bot.conf Normal file
View file

@ -0,0 +1,5 @@
[basic]
name = EchoBot
[rooms]
test

View file

@ -2,27 +2,24 @@ import asyncio
import yaboli import yaboli
class EchoBot(yaboli.Bot): class EchoBot(yaboli.Bot):
DEFAULT_NICK = "EchoBot"
HELP_GENERAL = "/me echoes back what you said" HELP_GENERAL = "/me echoes back what you said"
HELP_SPECIFIC = [ HELP_SPECIFIC = [
"This bot only has one command:", "This bot only has one command:",
"!echo <text> reply with exactly <text>", "!echo <text> reply with exactly <text>",
] ]
def __init__(self): def __init__(self, config_file):
super().__init__() super().__init__(config_file)
self.register_botrulez() self.register_botrulez()
self.register_general("echo", self.cmd_echo) self.register_general("echo", self.cmd_echo)
async def started(self):
await self.join("test")
async def cmd_echo(self, room, message, args): async def cmd_echo(self, room, message, args):
await message.reply(args.raw) await message.reply(args.raw)
async def main(): async def main():
bot = EchoBot() bot = EchoBot("bot.conf")
await bot.run() await bot.run()
if __name__ == "__main__": if __name__ == "__main__":

View file

@ -1,3 +1,4 @@
import configparser
import datetime import datetime
import logging import logging
from typing import List, Optional from typing import List, Optional
@ -18,13 +19,26 @@ class Bot(Client):
HELP_SPECIFIC: Optional[List[str]] = None HELP_SPECIFIC: Optional[List[str]] = None
KILL_REPLY: str = "/me dies" KILL_REPLY: str = "/me dies"
def __init__(self) -> None: BASIC_SECTION = "basic"
super().__init__() 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._commands: List[Command] = []
self.start_time = datetime.datetime.now() 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 # Registering commands
def register(self, command: Command) -> None: def register(self, command: Command) -> None:

View file

@ -12,9 +12,8 @@ logger = logging.getLogger(__name__)
__all__ = ["Client"] __all__ = ["Client"]
class Client: class Client:
DEFAULT_NICK = "" def __init__(self, default_nick: str) -> None:
self._default_nick = default_nick
def __init__(self) -> None:
self._rooms: Dict[str, List[Room]] = {} self._rooms: Dict[str, List[Room]] = {}
self._stop = asyncio.Event() self._stop = asyncio.Event()
@ -54,7 +53,7 @@ class Client:
logger.info(f"Joining &{room_name}") logger.info(f"Joining &{room_name}")
if nick is None: if nick is None:
nick = self.DEFAULT_NICK nick = self._default_nick
room = Room(room_name, password=password, target_nick=nick) room = Room(room_name, password=password, target_nick=nick)
room.register_event("snapshot", room.register_event("snapshot",

View file

@ -15,8 +15,8 @@ __all__ = ["Module", "ModuleBot"]
class Module(Bot): class Module(Bot):
DESCRIPTION: Optional[str] = None DESCRIPTION: Optional[str] = None
def __init__(self, standalone: bool) -> None: def __init__(self, config_file: str, standalone: bool) -> None:
super().__init__() super().__init__(config_file)
self.standalone = standalone self.standalone = standalone
@ -31,8 +31,8 @@ class ModuleBot(Bot):
] ]
MODULE_HELP_LIMIT = 5 MODULE_HELP_LIMIT = 5
def __init__(self) -> None: def __init__(self, config_file: str) -> None:
super().__init__() super().__init__(config_file)
self.modules: Dict[str, Module] = {} self.modules: Dict[str, Module] = {}