summaryrefslogtreecommitdiff
path: root/bot.py
diff options
context:
space:
mode:
Diffstat (limited to 'bot.py')
-rw-r--r--bot.py167
1 files changed, 39 insertions, 128 deletions
diff --git a/bot.py b/bot.py
index 88153cc..75f8aea 100644
--- a/bot.py
+++ b/bot.py
@@ -1,19 +1,13 @@
-import asyncio
-import discord
-import config
-from command_utils import command, CommandClient
-from random import shuffle, choice
-from time import sleep
+from os import getenv
+from commands import answer, await_n, bot_commands
+import config
-async def await_n(lst):
- lst = list(asyncio.create_task(task) for task in lst)
- if lst:
- done, _ = await asyncio.wait(lst)
- return list(task.result() for task in done)
+import discord
+from discord.ext import commands
-class Client(CommandClient):
+class Cupido(commands.Bot):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.meta_channel = None
@@ -23,45 +17,38 @@ class Client(CommandClient):
async def on_ready(self):
print(f'the bot {config.NAME} is logged in as "{self.user}"')
- @command(
- names = ('help', 'hepl', 'h', '?'),
- description = 'display this help message',
- is_help = True
- )
- async def help(self, ctx):
- command_doc = '\n'.join(
- f' * {config.COMMAND_PREFIX.strip()} {c.names[0]:15} - {c.description}'
- for c in self.get_commands())
- await ctx.answer(f'''```
-{config.HELP_TEXT}\nThese are all available commands:\n{command_doc}```''')
-
async def create_category(self, ctx):
category = await ctx.guild.create_category(config.CATEGORY_CHANNEL_NAME)
- await ctx.answer(f'info: category created "{category}" ({category.id})')
+ await answer(ctx, f'info: category created "{category}" ({category.id})')
return category
async def create_lobby(self, ctx):
- lobby = await ctx.guild.create_voice_channel(config.LOBBY_CHANNEL_NAME, topic=config.LOBBY_CHANNEL_TOPIC, category=self.meta_channel)
- await ctx.answer(f'info: voice channel created "{lobby}" ({lobby.id})')
+ lobby = await ctx.guild.create_voice_channel(
+ config.LOBBY_CHANNEL_NAME,
+ topic=config.LOBBY_CHANNEL_TOPIC,
+ category=self.meta_channel,
+ )
+ await answer(ctx, f'info: voice channel created "{lobby}" ({lobby.id})')
return lobby
def get_meta_channel(self, ctx):
- return (self.meta_channel
- or discord.utils.get(ctx.guild.categories,
- name=config.CATEGORY_CHANNEL_NAME))
+ return self.meta_channel or discord.utils.get(ctx.guild.categories, name=config.CATEGORY_CHANNEL_NAME)
def get_lobby_channel(self, ctx, meta_channel):
return (self.lobby_channel
- or discord.utils.get(ctx.guild.voice_channels,
- name=config.LOBBY_CHANNEL_NAME,
- category=meta_channel))
+ or discord.utils.get(
+ ctx.guild.voice_channels,
+ name=config.LOBBY_CHANNEL_NAME,
+ category=meta_channel
+ ))
def get_pair_channels(self, ctx, meta_channel):
return (self.pair_channels
or sorted((channel for channel in ctx.guild.voice_channels
if channel.category == meta_channel
and channel.name.isdigit()),
- key=lambda c: c.name))
+ key=lambda c: c.name,
+ ))
async def destroy_pair_channels(self, ctx, meta_channel):
await await_n(channel.delete() for channel in self.get_pair_channels(ctx, meta_channel))
@@ -74,110 +61,34 @@ class Client(CommandClient):
futures.append(ctx.guild.create_voice_channel(str(i), category=meta_channel))
return await await_n(futures)
- @command(
- names = ('init', 'create', 'inti', 'craete', 'cretae', 'c', 'i', '+'),
- description = 'create a new lobby'
- )
- async def init(self, ctx):
- self.meta_channel = (
- self.get_meta_channel(ctx)
- or await self.create_category(ctx)
- )
- self.lobby_channel = (
- self.get_lobby_channel(ctx, self.meta_channel)
- or await self.create_lobby(ctx)
- )
-
- @command(
- names = ('destroy', 'kill', 'desctruction', 'genocide', '-'),
- description = f'destruct all {config.NAME} channels'
- )
- async def destroy(self, ctx):
- futures = []
- meta_channel = self.get_meta_channel(ctx)
- for channel in (self.get_lobby_channel(ctx, meta_channel), meta_channel):
- if channel:
- futures.append(channel.delete())
- await await_n(futures)
- self.lobby_channel = None
- self.meta_channel = None
- self.pair_channels = []
-
async def get_channels(self, ctx):
meta_channel = self.get_meta_channel(ctx)
lobby_channel = self.get_lobby_channel(ctx, meta_channel)
if meta_channel is None or lobby_channel is None:
- await ctx.answer('error: cannot start shuffling, you need to initialize channels')
- await self.help(ctx)
+ await answer(ctx, 'error: cannot start shuffling, you need to initialize channels')
return None
return meta_channel, lobby_channel
- @command(
- names = ('shuffle', 'start', 'run', 'strat', 'rnu'),
- description = 'start shuffling'
- )
- async def shuffle(self, ctx):
- channels = await self.get_channels(ctx)
- if not channels: return
- meta_channel, lobby_channel = channels
- members = lobby_channel.members[:]
- slots = len(members) >> 1
- self.pair_channels = await self.create_pair_channels(ctx, meta_channel, slots)
- slots = []
- for i, _ in enumerate(self.pair_channels):
- slots.append(i)
- slots.append(i)
- shuffle(slots)
- futures = []
- for slot in slots:
- member = members.pop()
- if member is None: break
- futures.append(member.move_to(self.pair_channels[slot]))
- if members:
- futures.append(members.pop().move_to(choice(self.pair_channels)))
- await await_n(futures)
-
- @command(
- names = ('stop', 'quit', 'exit', 'abort', 'back', 'return'),
- description = 'move everyone back to lobby'
- )
- async def stop(self, ctx):
- channels = await self.get_channels(ctx)
- if not channels: return
- meta_channel, lobby_channel = channels
- pair_channels = self.get_pair_channels(ctx, meta_channel)
- futures = []
- for channel in pair_channels:
- for member in channel.members:
- futures.append(member.move_to(lobby_channel))
- await await_n(futures)
- await self.destroy_pair_channels(ctx, meta_channel)
-
- @command(
- names = ('loop',),
- description = 'repeat "shuffle" and "stop" <n> (default: 3) times and <t> (default: 120) seconds'
- )
- async def loop(self, ctx):
- if len(ctx.args) >= 1 and ctx.args[0].isdigit():
- n = int(ctx.args[0])
- else:
- n = 3
- if len(ctx.args) >= 2 and ctx.args[1].isdigit():
- t = int(ctx.args[1])
- else:
- t = 120
- await ctx.answer(f'repeat shuffling {n} times and each {t} seconds')
- for _ in range(n):
- await self.shuffle(ctx)
- sleep(t)
- await self.stop(ctx)
-
-if __name__ == '__main__':
- from os import getenv
+def main():
token = getenv(config.TOKEN_ENV_VAR)
if token is None:
print('error: no token was given')
exit(1)
- bot = Client(activity=discord.Game(name=config.GAME_STATUS))
+ bot = Cupido(activity=discord.Game(name=config.GAME_STATUS), command_prefix=config.COMMAND_PREFIX)
+ bot.remove_command('help')
+ for cmd in bot_commands:
+ bot.add_command(cmd)
bot.run(token)
+
+
+if __name__ == '__main__':
+ while True:
+ try:
+ main()
+ except Exception as e:
+ print(f'[DEBUG] encountered exception: {type(e)}: {e}')
+ if e.args == ('Event loop is closed',):
+ print('[DEBUG] quit...')
+ break
+ print('[DEBUG] restarting...')