summaryrefslogtreecommitdiff
path: root/command_utils.py
diff options
context:
space:
mode:
Diffstat (limited to 'command_utils.py')
-rw-r--r--command_utils.py73
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