Use config files for bots
This commit is contained in:
parent
a78f57db7a
commit
8cd2c8d125
6 changed files with 36 additions and 29 deletions
16
README.md
16
README.md
|
|
@ -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
5
examples/echo/bot.conf
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
[basic]
|
||||||
|
name = EchoBot
|
||||||
|
|
||||||
|
[rooms]
|
||||||
|
test
|
||||||
|
|
@ -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__":
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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",
|
||||||
|
|
|
||||||
|
|
@ -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] = {}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue