from datetime import datetime from logging import Logger from pathlib import Path from zoneinfo import ZoneInfo from bson.errors import InvalidId from discord import ApplicationContext, Cog, File, TextChannel, option, slash_command from discord.utils import basic_autocomplete from libbot.i18n import _, in_every_locale from classes import PycordEvent, PycordEventStage, PycordGuild, PycordUser from classes.errors import EventNotFoundError, GuildNotFoundError from classes.pycord_bot import PycordBot from modules.utils import autocomplete_active_events, get_logger, get_unix_timestamp logger: Logger = get_logger(__name__) class CogRegister(Cog): """Cog with the event registration command.""" def __init__(self, bot: PycordBot): self.bot: PycordBot = bot @slash_command( name="register", description=_("description", "commands", "register"), description_localizations=in_every_locale("description", "commands", "register"), ) @option( "event", description=_("description", "commands", "register", "options", "event"), description_localizations=in_every_locale( "description", "commands", "register", "options", "event" ), autocomplete=basic_autocomplete(autocomplete_active_events), ) async def command_register(self, ctx: ApplicationContext, event: str) -> None: try: guild: PycordGuild = await self.bot.find_guild(ctx.guild.id) except (InvalidId, GuildNotFoundError): await ctx.respond(self.bot._("unexpected_error", "messages", locale=ctx.locale), ephemeral=True) return try: pycord_event: PycordEvent = await self.bot.find_event(event_id=event) except (InvalidId, EventNotFoundError): await ctx.respond(self.bot._("event_not_found", "messages", locale=ctx.locale), ephemeral=True) return if not guild.is_configured(): await ctx.respond( self.bot._("guild_unconfigured", "messages", locale=ctx.locale), ephemeral=True ) return user: PycordUser = await self.bot.find_user(ctx.author, ctx.guild) if user.is_jailed: await ctx.respond(self.bot._("jailed_error", "messages", locale=ctx.locale), ephemeral=True) return if pycord_event._id in user.registered_event_ids: await ctx.respond( self.bot._("register_already_registered", "messages", locale=ctx.locale), ephemeral=True ) return await user.event_register(pycord_event._id, cache=self.bot.cache) event_ongoing: bool = pycord_event.starts.replace(tzinfo=ZoneInfo("UTC")) < datetime.now( tz=ZoneInfo("UTC") ) registered_message: str = ( self.bot._("register_success_ongoing", "messages", locale=ctx.locale).format( event_name=pycord_event.name ) if event_ongoing else self.bot._("register_success_scheduled", "messages", locale=ctx.locale).format( event_name=pycord_event.name, event_starts=get_unix_timestamp(pycord_event.starts, to_utc=True), ) ) await ctx.respond(registered_message) if event_ongoing: await user.set_event(pycord_event._id, cache=self.bot.cache) 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, self.bot._("admin_user_channel_creation_failed", "messages", locale=ctx.locale).format( display_name=ctx.author.display_name, mention=ctx.author.mention, event_name=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"]) ) await user_channel.send( self.bot._("notice_event_already_started", "messages", locale=ctx.locale).format( event_name=pycord_event.name ), file=thumbnail, ) first_stage: PycordEventStage = await self.bot.find_event_stage(pycord_event.stage_ids[0]) await user.set_event_stage(first_stage._id, cache=self.bot.cache) await self.bot.send_stage_question(user_channel, pycord_event, first_stage) def setup(bot: PycordBot) -> None: bot.add_cog(CogRegister(bot))