diff --git a/README.md b/README.md new file mode 100644 index 0000000..c43c6d7 --- /dev/null +++ b/README.md @@ -0,0 +1,64 @@ +# Yaboli + +Yaboli (**Y**et **A**nother **Bo**t **Li**brary) is a Python library for +creating bots for [euphoria.io](https://euphoria.io). + +Soon, markdown files containing documentation and troubleshooting info will be +available. + +## Example echo bot + +A simple echo bot that conforms to the +[botrulez](https://github.com/jedevc/botrulez) can be written like so: + +```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__() + 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 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. + +## TODOs + +- [ ] implement !uptime for proper botrulez conformity +- [ ] implement !kill +- [ ] 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?) +- [ ] make it easier to enable log messages +- [ ] cookie support +- [ ] fancy argument parsing +- [ ] document new classes (docstrings, maybe comments) +- [ ] write project readme +- [ ] write examples diff --git a/examples/echobot.py b/examples/echobot.py new file mode 100644 index 0000000..c462b64 --- /dev/null +++ b/examples/echobot.py @@ -0,0 +1,29 @@ +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__() + 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() + await bot.run() + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/test.py b/test.py deleted file mode 100644 index d749473..0000000 --- a/test.py +++ /dev/null @@ -1,66 +0,0 @@ -# These tests are not intended as serious tests, just as small scenarios to -# give yaboli something to do. - -import asyncio -import logging - -import yaboli - -FORMAT = "{asctime} [{levelname:<7}] <{name}> {funcName}(): {message}" -LEVEL = logging.DEBUG -#FORMAT = "{asctime} [{levelname:<7}] <{name}>: {message}" -#LEVEL = logging.INFO - -DATE_FORMAT = "%F %T" -handler = logging.StreamHandler() -handler.setFormatter(logging.Formatter( - fmt=FORMAT, - datefmt=DATE_FORMAT, - style="{" -)) - -logger = logging.getLogger('yaboli') -logger.setLevel(LEVEL) -logger.addHandler(handler) - -class TestModule(yaboli.Module): - PING_REPLY = "ModulePong!" - DESCRIPTION = "ModuleDescription" - HELP_GENERAL = "ModuleGeneralHelp" - HELP_SPECIFIC = ["ModuleGeneralHelp"] - -class EchoModule(yaboli.Module): - DEFAULT_NICK = "echo" - DESCRIPTION = "echoes back the input arguments" - HELP_GENERAL = "/me " + DESCRIPTION - HELP_SPECIFIC = [ - "!echo – output the arguments, each in its own line" - #"!fancyecho – same as !echo, but different parser" - ] - - def __init__(self, standalone: bool) -> None: - super().__init__(standalone) - - self.register_general("echo", self.cmd_echo) - #self.register_general("fancyecho", self.cmd_fancyecho) - - async def cmd_echo(self, room, message, args): - if args.has_args(): - lines = [repr(arg) for arg in args.basic()] - await message.reply("\n".join(lines)) - else: - await message.reply("No arguments") - -class TestBot(yaboli.ModuleBot): - DEFAULT_NICK = "testbot" - - async def started(self): - await self.join("test") - -async def main(): - tb = TestBot() - tb.register_module("test", TestModule(standalone=False)) - tb.register_module("echo", EchoModule(standalone=False)) - await tb.run() - -asyncio.run(main()) diff --git a/todo.txt b/todo.txt deleted file mode 100644 index d752445..0000000 --- a/todo.txt +++ /dev/null @@ -1,12 +0,0 @@ -TODO -- 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") -- cookie support -- fancy argument parsing -- document new classes (docstrings, maybe comments) -- document yaboli (markdown files in a "docs" folder?) -- write project readme -- write examples - -DONE