summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNatrixAeria <upezu@student.kit.edu>2020-09-28 00:48:17 +0200
committerNatrixAeria <upezu@student.kit.edu>2020-09-28 00:48:17 +0200
commitee22753e9e82879363a3c9540166f51d4aa29988 (patch)
treeb0f86ebffb588aee80d191b917aeff65196a28b7
parente3a8453248c7ad8c09a33048b87d42593013563a (diff)
Add a command interface
-rw-r--r--bot.py48
-rw-r--r--command_utils.py73
-rw-r--r--config.py9
3 files changed, 110 insertions, 20 deletions
diff --git a/bot.py b/bot.py
index 7a794c6..d860397 100644
--- a/bot.py
+++ b/bot.py
@@ -1,20 +1,28 @@
-import discord
-from discord.ext import commands
-
-BOT_NAME = "Cupido"
-
-client = discord.Client()
-bot = commands.Bot(command_prefix='!<3')
-
-
-@client.event
-async def on_ready():
- print('{0} is logged in as {1.user}'.format(BOT_NAME, client))
-
-
-@bot.command()
-async def init(ctx):
- pass
-
-
-client.run('token')
+import config
+from command_utils import Command, CommandClient
+
+
+class Client(CommandClient):
+ async def on_ready(self):
+ print(f'the bot {config.NAME} is logged in as "{self.user}"')
+
+ @Command.help_command
+ @Command.names('help', 'hepl', 'h', '?')
+ @Command.description('display this help message')
+ async def help(self, ctx):
+ await ctx.answer(config.HELP_TEXT)
+
+ @Command.names('init', 'create', 'inti', 'craete', 'cretae', 'c', 'i', '+')
+ @Command.description('create a new lobby')
+ async def init(self, ctx):
+ await ctx.answer(f'NIY')
+
+
+if __name__ == '__main__':
+ from os import getenv
+ token = getenv(config.TOKEN_ENV_VAR)
+ if token is None:
+ print('error: no token was given')
+ exit(1)
+ bot = Client()
+ bot.run(token)
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
diff --git a/config.py b/config.py
new file mode 100644
index 0000000..85d009d
--- /dev/null
+++ b/config.py
@@ -0,0 +1,9 @@
+NAME = 'cupido'
+TOKEN_ENV_VAR = 'DISCORD_TOKEN'
+
+COMMAND_PREFIX = '!<3'
+
+HELP_TEXT = f'''{NAME.title()} - your partner for getting shuffled.
+{NAME.title()} is a discord bot to get to know your people.
+This software is open-source <https://git.kobert.dev/lovefinderrz.git/>!"
+'''