Files
QuizBot/cogs/cog_register.py

137 lines
5.0 KiB
Python

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))