diff options
Diffstat (limited to 'command_utils.py')
-rw-r--r-- | command_utils.py | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/command_utils.py b/command_utils.py new file mode 100644 index 0000000..2dc84c8 --- /dev/null +++ b/command_utils.py @@ -0,0 +1,73 @@ +import discord + +import config + + +def istrue(value, key): + return hasattr(value, key) and getattr(value, key) + + +class Context: + def __init__(self, msg, args): + self.msg = msg + self.args = args + + async def answer(self, value): + await self.msg.channel.send(f'{self.msg.author.mention} {value}') + + +class CommandClientMeta(type): + def __new__(cls, name, bases, dct): + commands = [] + for item in dct.copy().values(): + if callable(item) and istrue(item, 'command'): + if istrue(item, 'help_command'): + dct['help_command'] = item + commands.append(item) + dct['commands'] = commands + return super().__new__(cls, name, bases, dct) + + +class CommandClient(discord.Client, metaclass=CommandClientMeta): + def get_commands(self): + return type(self).commands.copy() + + async def run_help(self, ctx): + return await type(self).help_command(self, ctx) + + async def on_message(self, msg): + text = msg.content.strip() + if not text.startswith(config.COMMAND_PREFIX): + return + try: + cmd, *args = [v for v in text[len(config.COMMAND_PREFIX):].split(' ') if v] + except ValueError: + return await self.run_help(Context(msg, [])) + ctx = Context(msg, args) + for command in self.get_commands(): + if cmd in command.names: + return await command(self, ctx) + return await self.run_help(ctx) + + +class Command: + @classmethod + def names(cls, *names): + def meta(f): + f.command = True + f.names = names + return f + return meta + + @classmethod + def description(cls, *names): + def meta(f): + f.command = True + f.names = names + return f + return meta + + @classmethod + def help_command(cls, f): + f.help_command = True + return f |