Files
QuizBot/cogs/cog_guess.py

130 lines
4.7 KiB
Python

from typing import List
from bson import ObjectId
from bson.errors import InvalidId
from discord import ApplicationContext, Cog, File, option, slash_command
from libbot.i18n import _, in_every_locale
from classes import PycordEvent, PycordEventStage, PycordGuild, PycordUser
from classes.errors import (
EventNotFoundError,
EventStageNotFoundError,
GuildNotFoundError,
)
from classes.pycord_bot import PycordBot
class CogGuess(Cog):
"""Cog with the guessing command."""
def __init__(self, bot: PycordBot):
self.bot: PycordBot = bot
@slash_command(
name="guess",
description=_("description", "commands", "guess"),
description_localizations=in_every_locale("description", "commands", "guess"),
)
@option(
"answer",
description=_("description", "commands", "guess", "options", "answer"),
description_localizations=in_every_locale("description", "commands", "guess", "options", "answer"),
)
async def command_guess(self, ctx: ApplicationContext, answer: 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
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))
return
if user.current_event_id is None or user.current_stage_id is None:
await ctx.respond(self.bot._("guess_unregistered", "messages", locale=ctx.locale))
return
try:
event: PycordEvent = await self.bot.find_event(event_id=user.current_event_id)
stage: PycordEventStage = await self.bot.find_event_stage(user.current_stage_id)
except (InvalidId, EventNotFoundError, EventStageNotFoundError):
await ctx.respond(self.bot._("guess_incorrect_event", "messages", locale=ctx.locale))
return
if ctx.channel_id != user.event_channels[str(event._id)]:
await ctx.respond(
self.bot._("guess_incorrect_channel", "messages", locale=ctx.locale), ephemeral=True
)
return
if answer.lower() != stage.answer.lower():
await ctx.respond(
self.bot.config["emojis"]["guess_wrong"]
if guild.prefer_emojis
else self.bot._("guess_incorrect", "messages", locale=ctx.locale)
)
return
next_stage_index = stage.sequence + 1
next_stage_id: ObjectId | None = (
None if len(event.stage_ids) < next_stage_index + 1 else event.stage_ids[next_stage_index]
)
if next_stage_id is None:
user.completed_event_ids.append(event._id)
await user._set(
self.bot.cache,
current_event_id=None,
current_stage_id=None,
completed_event_ids=user.completed_event_ids,
)
await ctx.respond(self.bot._("guess_completed_event", "messages", locale=ctx.locale))
await self.bot.notify_admins(
ctx.guild,
guild,
self.bot._("admin_user_completed_event", "messages", locale=ctx.locale).format(
display_name=ctx.author.display_name, mention=ctx.author.mention, event_name=event.name
),
)
return
next_stage: PycordEventStage = await self.bot.find_event_stage(next_stage_id)
files: List[File] | None = next_stage.get_media_files()
next_question_chunks: List[str] = next_stage.get_question_chunked(2000)
next_question_chunks_length: int = len(next_question_chunks)
for index, chunk in enumerate(next_question_chunks):
await ctx.respond(chunk, files=None if index != next_question_chunks_length - 1 else files)
await user.set_event_stage(next_stage._id, cache=self.bot.cache)
await self.bot.notify_admins(
ctx.guild,
guild,
self.bot._("admin_user_completed_stage", "messages", locale=ctx.locale).format(
display_name=ctx.author.display_name,
mention=ctx.author.mention,
stage_sequence=stage.sequence + 1,
event_name=event.name,
),
)
def setup(bot: PycordBot) -> None:
bot.add_cog(CogGuess(bot))