Files
QuizBot/cogs/cog_register.py

109 lines
4.0 KiB
Python

from datetime import datetime
from logging import Logger
from pathlib import Path
from typing import List
from zoneinfo import ZoneInfo
from bson.errors import InvalidId
from discord import ApplicationContext, Cog, option, slash_command, TextChannel, File
from discord.utils import basic_autocomplete
from classes import PycordEvent, PycordGuild, PycordUser, PycordEventStage
from classes.pycord_bot import PycordBot
from modules.utils import autocomplete_active_events, get_unix_timestamp, get_logger
logger: Logger = get_logger(__name__)
class CogRegister(Cog):
"""Cog with the event registration command."""
def __init__(self, bot: PycordBot):
self.bot: PycordBot = bot
# TODO Introduce i18n
@slash_command(
name="register",
description="Enter the selected event",
)
@option(
"event",
description="Name of the event",
autocomplete=basic_autocomplete(autocomplete_active_events),
)
async def command_register(self, ctx: ApplicationContext, event: str) -> None:
guild: PycordGuild = await self.bot.find_guild(ctx.guild.id)
try:
pycord_event: PycordEvent = await self.bot.find_event(event_id=event)
except (InvalidId, RuntimeError):
# TODO Make a nice message
await ctx.respond("Event was not found.")
return
if not guild.is_configured():
await ctx.respond(self.bot._("guild_unconfigured", "messages", locale=ctx.locale))
return
user: PycordUser = await self.bot.find_user(ctx.author, ctx.guild)
if user.is_jailed:
# TODO Make a nice message
await ctx.respond("You are jailed and cannot interact with events. Please, contact the administrator.")
return
if pycord_event._id in user.registered_event_ids:
# TODO Make a nice message
await ctx.respond("You are already registered for this event.")
return
await user.event_register(pycord_event._id, cache=self.bot.cache)
# TODO Make a nice message
await ctx.respond(
f"You are now registered for the event **{pycord_event.name}**.\n\nNew channel will be created for you and further instructions will be provided as soon as the event starts <t:{get_unix_timestamp(pycord_event.starts)}:R>. Good luck!"
)
if pycord_event.starts.replace(tzinfo=ZoneInfo("UTC")) < datetime.now(tz=ZoneInfo("UTC")):
user_channel: TextChannel = await user.setup_event_channel(
self.bot, ctx.guild, guild, pycord_event, cache=self.bot.cache
)
if user_channel is None:
logger.error(
"Event channel was not created for user %s from guild %s and event %s after registration.",
ctx.author.id,
guild.id,
pycord_event._id,
)
await self.bot.notify_admins(
ctx.guild,
guild,
f"Event channel could not be created for user **{ctx.author.display_name}** ({ctx.author.mention}) and event **{pycord_event.name}**.",
)
return
thumbnail: File | None = (
None
if pycord_event.thumbnail is None
else File(Path(f"data/{pycord_event.thumbnail['id']}"), pycord_event.thumbnail["filename"])
)
# TODO Make a nice message
await user_channel.send(
f"Event **{pycord_event.name}** has already started!\n\nUse slash command `/guess` to suggest your answers to each event stage.",
file=thumbnail,
)
first_stage: PycordEventStage = await self.bot.find_event_stage(pycord_event.stage_ids[0])
first_stage_files: List[File] | None = first_stage.get_media_files()
await user_channel.send(f"First stage...\n\n{first_stage.question}", files=first_stage_files)
def setup(bot: PycordBot) -> None:
bot.add_cog(CogRegister(bot))