Compare commits

6 Commits

9 changed files with 124 additions and 74 deletions

View File

@@ -97,13 +97,12 @@ class PycordBot(LibPycordBot):
continue continue
if len(event.stage_ids) == 0: if len(event.stage_ids) == 0:
# TODO Make a nice message for management
logger.error("Could not start the event %s: no event stages are defined.", event._id) logger.error("Could not start the event %s: no event stages are defined.", event._id)
await self.notify_admins( await self.notify_admins(
guild, guild,
pycord_guild, pycord_guild,
f"Could not start the event **{event.name}**: no event stages are defined.", self.bot._("admin_event_no_stages_defined", "messages").format(event_name=event.name),
) )
await event.cancel(self.cache) await event.cancel(self.cache)
@@ -134,7 +133,9 @@ class PycordBot(LibPycordBot):
await self.notify_admins( await self.notify_admins(
guild, guild,
pycord_guild, pycord_guild,
f"Event channel could not be created for user with ID `{user.id}` (<@{user.id}>) and event **{event.name}**: user was not found on the server.", self.bot._("admin_channel_creation_failed_no_user", "messages").format(
user_id=user.id, event_name=event.name
),
) )
continue continue
@@ -152,7 +153,11 @@ class PycordBot(LibPycordBot):
await self.notify_admins( await self.notify_admins(
guild, guild,
pycord_guild, pycord_guild,
f"Event channel could not be created for user **{discord_user.display_name}** ({discord_user.mention}) and event **{event.name}**.", self.bot._("admin_channel_creation_failed", "messages").format(
display_name=discord_user.display_name,
mention=discord_user.mention,
event_name=event.name,
),
) )
continue continue
@@ -163,10 +168,8 @@ class PycordBot(LibPycordBot):
else File(Path(f"data/{event.thumbnail['id']}"), event.thumbnail["filename"]) else File(Path(f"data/{event.thumbnail['id']}"), event.thumbnail["filename"])
) )
# Send a notification about event start
# TODO Make a nice message
await user_channel.send( await user_channel.send(
f"Event **{event.name}** is starting!\n\nUse slash command `/guess` to suggest your answers to each event stage.", self.bot._("event_is_starting", "messages").format(event_name=event.name),
file=thumbnail, file=thumbnail,
) )
@@ -180,11 +183,10 @@ class PycordBot(LibPycordBot):
chunk, files=None if index != question_chunks_length - 1 else first_stage_files chunk, files=None if index != question_chunks_length - 1 else first_stage_files
) )
# TODO Make a nice message
await self.notify_admins( await self.notify_admins(
guild, guild,
pycord_guild, pycord_guild,
f"Event **{event.name}** has started! Users have gotten their channels and can already start submitting their answers.", self.bot._("admin_event_started", "messages").format(event_name=event.name),
) )
async def _process_events_end(self) -> None: async def _process_events_end(self) -> None:
@@ -218,9 +220,11 @@ class PycordBot(LibPycordBot):
) )
continue continue
# TODO Make a nice message
stages_string: str = "\n\n".join( stages_string: str = "\n\n".join(
f"**Stage {stage.sequence+1}**\nAnswer: ||{stage.answer}||" for stage in stages self.bot._("stage_entry", "messages").format(
sequence=stage.sequence + 1, answer=stage.answer
)
for stage in stages
) )
# Get list of participants # Get list of participants
@@ -238,9 +242,8 @@ class PycordBot(LibPycordBot):
# Send a notification about event start # Send a notification about event start
user_channel: TextChannel = guild.get_channel(user.event_channels[str(event._id)]) user_channel: TextChannel = guild.get_channel(user.event_channels[str(event._id)])
# TODO Make a nice message event_ended_string: str = self.bot._("event_ended", "messages").format(
event_ended_string: str = ( event_name=event.name, stages=stages_string
f"Event **{event.name}** has ended! Stages and respective answers are listed below.\n\n{stages_string}"
) )
chunk_size: int = 2000 chunk_size: int = 2000
@@ -256,11 +259,10 @@ class PycordBot(LibPycordBot):
# Lock each participant out # Lock each participant out
await user.lock_event_channel(guild, event._id, channel=user_channel) await user.lock_event_channel(guild, event._id, channel=user_channel)
# TODO Make a nice message
await self.notify_admins( await self.notify_admins(
guild, guild,
pycord_guild, pycord_guild,
f"Event **{event.name}** has ended! Users can no longer submit their answers.", self.bot._("admin_event_ended", "messages").format(event_name=event.name),
) )
await event.end(cache=self.cache) await event.end(cache=self.cache)

View File

@@ -17,7 +17,7 @@ logger: Logger = get_logger(__name__)
class PycordGuild: class PycordGuild:
"""Dataclass of DB entry of a guild""" """Dataclass of DB entry of a guild"""
__slots__ = ("_id", "id", "channel_id", "category_id", "timezone") __slots__ = ("_id", "id", "channel_id", "category_id", "timezone", "prefer_emojis")
__short_name__ = "guild" __short_name__ = "guild"
__collection__ = col_guilds __collection__ = col_guilds
@@ -26,6 +26,7 @@ class PycordGuild:
channel_id: int | None channel_id: int | None
category_id: int | None category_id: int | None
timezone: str timezone: str
prefer_emojis: bool
@classmethod @classmethod
async def from_id( async def from_id(
@@ -145,6 +146,7 @@ class PycordGuild:
"channel_id": self.channel_id, "channel_id": self.channel_id,
"category_id": self.category_id, "category_id": self.category_id,
"timezone": self.timezone, "timezone": self.timezone,
"prefer_emojis": self.prefer_emojis,
} }
# TODO Add documentation # TODO Add documentation
@@ -155,6 +157,7 @@ class PycordGuild:
"channel_id": None, "channel_id": None,
"category_id": None, "category_id": None,
"timezone": "UTC", "timezone": "UTC",
"prefer_emojis": False,
} }
@staticmethod @staticmethod

View File

@@ -43,7 +43,14 @@ class CogConfig(Cog):
), ),
required=True, required=True,
) )
@option("channel", description="Text channel for admin notifications", required=True) @option(
"channel",
description=_("description", "commands", "config_set", "options", "channel"),
description_localizations=in_every_locale(
"description", "commands", "config_set", "options", "channel"
),
required=True,
)
@option( @option(
"timezone", "timezone",
description=_("description", "commands", "config_set", "options", "timezone"), description=_("description", "commands", "config_set", "options", "timezone"),
@@ -53,12 +60,21 @@ class CogConfig(Cog):
autocomplete=basic_autocomplete(autocomplete_timezones), autocomplete=basic_autocomplete(autocomplete_timezones),
required=True, required=True,
) )
@option(
"prefer_emojis",
description=_("description", "commands", "config_set", "options", "prefer_emojis"),
description_localizations=in_every_locale(
"description", "commands", "config_set", "options", "prefer_emojis"
),
required=True,
)
async def command_config_set( async def command_config_set(
self, self,
ctx: ApplicationContext, ctx: ApplicationContext,
category: CategoryChannel, category: CategoryChannel,
channel: TextChannel, channel: TextChannel,
timezone: str, timezone: str,
prefer_emojis: bool,
) -> None: ) -> None:
try: try:
guild: PycordGuild = await self.bot.find_guild(ctx.guild.id) guild: PycordGuild = await self.bot.find_guild(ctx.guild.id)
@@ -79,6 +95,7 @@ class CogConfig(Cog):
channel_id=channel.id, channel_id=channel.id,
category_id=category.id, category_id=category.id,
timezone=str(timezone_parsed), timezone=str(timezone_parsed),
prefer_emojis=prefer_emojis,
) )
await ctx.respond(self.bot._("config_set", "messages", locale=ctx.locale)) await ctx.respond(self.bot._("config_set", "messages", locale=ctx.locale))
@@ -131,6 +148,7 @@ class CogConfig(Cog):
channel_id=guild.channel_id, channel_id=guild.channel_id,
category_id=guild.category_id, category_id=guild.category_id,
timezone=guild.timezone, timezone=guild.timezone,
prefer_emojis=guild.prefer_emojis,
) )
) )

View File

@@ -24,7 +24,6 @@ from modules.utils import (
) )
# noinspection Mypy
class CogEvent(Cog): class CogEvent(Cog):
"""Cog with event management commands.""" """Cog with event management commands."""
@@ -98,10 +97,7 @@ class CogEvent(Cog):
start_date: datetime = datetime.strptime(start, "%d.%m.%Y %H:%M").replace(tzinfo=guild_timezone) start_date: datetime = datetime.strptime(start, "%d.%m.%Y %H:%M").replace(tzinfo=guild_timezone)
end_date: datetime = datetime.strptime(end, "%d.%m.%Y %H:%M").replace(tzinfo=guild_timezone) end_date: datetime = datetime.strptime(end, "%d.%m.%Y %H:%M").replace(tzinfo=guild_timezone)
except ValueError: except ValueError:
# TODO Introduce i18n await ctx.respond(self.bot._("event_dates_parsing_failed", "messages", locale=ctx.locale))
await ctx.respond(
"Could not parse start and end dates. Please, make sure these are provided in `DD.MM.YYYY HH:MM` format."
)
return return
if not await validate_event_validity(ctx, name, start_date, end_date, to_utc=True): if not await validate_event_validity(ctx, name, start_date, end_date, to_utc=True):
@@ -120,9 +116,10 @@ class CogEvent(Cog):
thumbnail=processed_media[0] if thumbnail else None, thumbnail=processed_media[0] if thumbnail else None,
) )
# TODO Introduce i18n
await ctx.respond( await ctx.respond(
f"Event **{event.name}** has been created and will take place <t:{get_unix_timestamp(event.starts, to_utc=True)}:R>." self.bot._("event_created", "messages", locale=ctx.locale).format(
event_name=event.name, start_time=get_unix_timestamp(event.starts, to_utc=True)
)
) )
@command_group.command( @command_group.command(
@@ -205,10 +202,7 @@ class CogEvent(Cog):
else datetime.strptime(start, "%d.%m.%Y %H:%M").replace(tzinfo=guild_timezone) else datetime.strptime(start, "%d.%m.%Y %H:%M").replace(tzinfo=guild_timezone)
) )
except ValueError: except ValueError:
# TODO Make a nice message await ctx.respond(self.bot._("event_start_date_parsing_failed", "messages", locale=ctx.locale))
await ctx.respond(
"Could not parse the start date. Please, make sure it is provided in `DD.MM.YYYY HH:MM` format."
)
return return
try: try:
@@ -218,10 +212,7 @@ class CogEvent(Cog):
else datetime.strptime(end, "%d.%m.%Y %H:%M").replace(tzinfo=guild_timezone) else datetime.strptime(end, "%d.%m.%Y %H:%M").replace(tzinfo=guild_timezone)
) )
except ValueError: except ValueError:
# TODO Make a nice message await ctx.respond(self.bot._("event_end_date_parsing_failed", "messages", locale=ctx.locale))
await ctx.respond(
"Could not parse the end date. Please, make sure it is provided in `DD.MM.YYYY HH:MM` format."
)
return return
if not await validate_event_validity( if not await validate_event_validity(
@@ -248,9 +239,11 @@ class CogEvent(Cog):
# TODO Notify participants about time changes # TODO Notify participants about time changes
# TODO Make a nice message
await ctx.respond( await ctx.respond(
f"Event **{pycord_event.name}** has been updated and will take place <t:{get_unix_timestamp(pycord_event.starts, to_utc=True)}:R>." self.bot._("event_updated", "messages", locale=ctx.locale).format(
event_name=pycord_event.name,
start_time=get_unix_timestamp(pycord_event.starts, to_utc=True),
)
) )
@command_group.command( @command_group.command(
@@ -309,16 +302,22 @@ class CogEvent(Cog):
or end_date <= datetime.now(tz=ZoneInfo("UTC")) or end_date <= datetime.now(tz=ZoneInfo("UTC"))
or start_date <= datetime.now(tz=ZoneInfo("UTC")) or start_date <= datetime.now(tz=ZoneInfo("UTC"))
): ):
# TODO Make a nice message await ctx.respond(
await ctx.respond("Finished or ongoing events cannot be cancelled.") self.bot._("event_not_editable", "messages", locale=ctx.locale).format(
event_name=pycord_event.name
)
)
return return
await pycord_event.cancel() await pycord_event.cancel()
# TODO Notify participants about cancellation # TODO Notify participants about cancellation
# TODO Make a nice message await ctx.respond(
await ctx.respond(f"Event **{pycord_event.name}** was cancelled.") self.bot._("event_cancelled", "messages", locale=ctx.locale).format(
event_name=pycord_event.name
)
)
@command_group.command( @command_group.command(
name="show", name="show",
@@ -346,16 +345,20 @@ class CogEvent(Cog):
stages: List[PycordEventStage] = await self.bot.get_event_stages(pycord_event) stages: List[PycordEventStage] = await self.bot.get_event_stages(pycord_event)
# TODO Make a nice message
stages_string: str = "\n\n".join( stages_string: str = "\n\n".join(
f"**Stage {stage.sequence+1}**\nAnswer: ||{stage.answer}||" for stage in stages self.bot._("stage_entry", "messages", locale=ctx.locale).format(
sequence=stage.sequence + 1, answer=stage.answer
)
for stage in stages
) )
# TODO Show users registered for the event # TODO Show users registered for the event
# TODO Introduce i18n event_info_string: str = self.bot._("event_details", "messages", locale=ctx.locale).format(
event_info_string: str = ( event_name=pycord_event.name,
f"**Event details**\n\nName: {pycord_event.name}\nStarts: <t:{get_unix_timestamp(starts_date)}>\nEnds: <t:{get_unix_timestamp(ends_date)}>\n\nStages:\n{stages_string}" start_time=get_unix_timestamp(starts_date),
end_time=get_unix_timestamp(ends_date),
stages=stages_string,
) )
chunk_size: int = 2000 chunk_size: int = 2000

View File

@@ -65,9 +65,11 @@ class CogGuess(Cog):
return return
if answer.lower() != stage.answer.lower(): if answer.lower() != stage.answer.lower():
# TODO Make a nice message await ctx.respond(
# await ctx.respond("Provided answer is wrong.") self.bot.config["emojis"]["guess_wrong"]
await ctx.respond(self.bot.config["emojis"]["guess_wrong"]) if guild.prefer_emojis
else self.bot._("guess_incorrect", "messages", locale=ctx.locale)
)
return return
next_stage_index = stage.sequence + 1 next_stage_index = stage.sequence + 1

View File

@@ -115,8 +115,7 @@ class CogStage(Cog):
media=[] if media is None else processed_media, media=[] if media is None else processed_media,
) )
# TODO Make a nice message await ctx.respond(self.bot._("stage_created", "messages", locale=ctx.locale))
await ctx.respond("Event stage has been created.")
@command_group.command( @command_group.command(
name="edit", name="edit",
@@ -216,13 +215,11 @@ class CogStage(Cog):
try: try:
event_stage: PycordEventStage = await self.bot.find_event_stage(stage) event_stage: PycordEventStage = await self.bot.find_event_stage(stage)
except (InvalidId, EventStageNotFoundError): except (InvalidId, EventStageNotFoundError):
# TODO Make a nice message await ctx.respond(self.bot._("stage_not_found", "messages", locale=ctx.locale))
await ctx.respond("Event stage was not found.")
return return
if order is not None and order > len(pycord_event.stage_ids): if order is not None and order > len(pycord_event.stage_ids):
# TODO Make a nice message await ctx.respond(self.bot._("stage_sequence_out_of_range", "messages", locale=ctx.locale))
await ctx.respond("Stage sequence out of range.")
return return
processed_media: List[Dict[str, Any]] = ( processed_media: List[Dict[str, Any]] = (
@@ -239,7 +236,7 @@ class CogStage(Cog):
if order is not None and order - 1 != event_stage.sequence: if order is not None and order - 1 != event_stage.sequence:
await pycord_event.reorder_stage(self.bot, event_stage._id, order - 1, cache=self.bot.cache) await pycord_event.reorder_stage(self.bot, event_stage._id, order - 1, cache=self.bot.cache)
await ctx.respond("Event stage has been updated.") await ctx.respond(self.bot._("stage_updated", "messages", locale=ctx.locale))
@command_group.command( @command_group.command(
name="delete", name="delete",
@@ -300,15 +297,13 @@ class CogStage(Cog):
try: try:
event_stage: PycordEventStage = await self.bot.find_event_stage(stage) event_stage: PycordEventStage = await self.bot.find_event_stage(stage)
except (InvalidId, EventStageNotFoundError): except (InvalidId, EventStageNotFoundError):
# TODO Make a nice message await ctx.respond(self.bot._("stage_not_found", "messages", locale=ctx.locale))
await ctx.respond("Event stage was not found.")
return return
await pycord_event.remove_stage(self.bot, event_stage._id, cache=self.bot.cache) await pycord_event.remove_stage(self.bot, event_stage._id, cache=self.bot.cache)
await event_stage.purge(cache=self.bot.cache) await event_stage.purge(cache=self.bot.cache)
# TODO Make a nice message await ctx.respond(self.bot._("stage_deleted", "messages", locale=ctx.locale))
await ctx.respond("Event stage has been deleted.")
def setup(bot: PycordBot) -> None: def setup(bot: PycordBot) -> None:

View File

@@ -1,14 +1,36 @@
{ {
"messages": { "messages": {
"admin_channel_creation_failed": "Event channel could not be created for user **{display_name}** ({mention}) and event **{event_name}**.",
"admin_channel_creation_failed_no_user": "Event channel could not be created for user with ID `{user_id}` (<@{user_id}>) and event **{event_name}**: user was not found on the server.",
"admin_event_ended": "Event **{event_name}** has ended! Users can no longer submit their answers.",
"admin_event_no_stages_defined": "Could not start the event **{event_name}**: no event stages are defined.",
"admin_event_started": "Event **{event_name}** has started! Users have gotten their channels and can already start submitting their answers.",
"admin_user_channel_creation_failed": "Event channel could not be created for user **{display_name}** ({mention}) and event **{event_name}**.", "admin_user_channel_creation_failed": "Event channel could not be created for user **{display_name}** ({mention}) and event **{event_name}**.",
"admin_user_channel_fixed": "Fixed event channel of user **{display_name}** ({mention}) for the event **{event_name}**.",
"admin_user_completed_event": "User **{display_name}** ({mention}) has completed the event **{event_name}**", "admin_user_completed_event": "User **{display_name}** ({mention}) has completed the event **{event_name}**",
"admin_user_completed_stage": "User **{display_name}** ({mention}) has completed the stage {stage_sequence} of the event **{event_name}**.", "admin_user_completed_stage": "User **{display_name}** ({mention}) has completed the stage {stage_sequence} of the event **{event_name}**.",
"admin_user_channel_fixed": "Fixed event channel of user **{display_name}** ({mention}) for the event **{event_name}**.",
"config_reset": "Configuration has been reset. You can update it using `/config set`, otherwise no events can be held.", "config_reset": "Configuration has been reset. You can update it using `/config set`, otherwise no events can be held.",
"config_set": "Configuration has been updated. You can review it anytime using `/config show`.", "config_set": "Configuration has been updated. You can review it anytime using `/config show`.",
"config_show": "**Guild config**\n\nChannel: <#{channel_id}>\nCategory: <#{category_id}>\nTimezone: `{timezone}`", "config_show": "**Guild config**\n\nChannel: <#{channel_id}>\nCategory: <#{category_id}>\nTimezone: `{timezone}`\nPrefer emojis: `{prefer_emojis}`",
"event_cancelled": "Event **{event_name}** was cancelled.",
"event_created": "Event **{event_name}** has been created and will take place <t:{start_time}:R>.",
"event_dates_parsing_failed": "Could not parse start and end dates. Please, make sure these are provided in `DD.MM.YYYY HH:MM` format.",
"event_details": "**Event details**\n\nName: {event_name}\nStarts: <t:{start_time}>\nEnds: <t:{end_time}>\n\nStages:\n{stages}",
"event_end_before_start": "Start date must be before end date",
"event_end_date_parsing_failed": "Could not parse the end date. Please, make sure it is provided in `DD.MM.YYYY HH:MM` format.",
"event_end_past": "End date must not be in the past",
"event_ended": "Event **{event_name}** has ended! Stages and respective answers are listed below.\n\n{stages}",
"event_is_cancelled": "This event was cancelled.",
"event_is_starting": "Event **{event_name}** is starting!\n\nUse slash command `/guess` to suggest your answers to each event stage.",
"event_name_duplicate": "There can only be one active event with the same name",
"event_not_editable": "Finished or ongoing events cannot be cancelled.",
"event_not_found": "Event was not found.", "event_not_found": "Event was not found.",
"event_ongoing_not_editable": "Ongoing events cannot be modified.",
"event_start_date_parsing_failed": "Could not parse the start date. Please, make sure it is provided in `DD.MM.YYYY HH:MM` format.",
"event_start_past": "Start date must not be in the past",
"event_updated": "Event **{event_name}** has been updated and will take place <t:{start_time}:R>.",
"guess_completed_event": "Congratulations! You have completed the event!", "guess_completed_event": "Congratulations! You have completed the event!",
"guess_incorrect": "Provided answer is wrong.",
"guess_incorrect_channel": "Usage outside own event channel is not allowed.", "guess_incorrect_channel": "Usage outside own event channel is not allowed.",
"guess_incorrect_event": "Your event could not be found. Please, contact the administrator.", "guess_incorrect_event": "Your event could not be found. Please, contact the administrator.",
"guess_unregistered": "You have no ongoing events. You can register for events using the `/register` command.", "guess_unregistered": "You have no ongoing events. You can register for events using the `/register` command.",
@@ -20,17 +42,23 @@
"register_already_registered": "You are already registered for this event.", "register_already_registered": "You are already registered for this event.",
"register_success_ongoing": "You are now registered for the event **{event_name}**.\n\nNew channel has been created for you and further instructions will are provided in it. Good luck!", "register_success_ongoing": "You are now registered for the event **{event_name}**.\n\nNew channel has been created for you and further instructions will are provided in it. Good luck!",
"register_success_scheduled": "You are now registered for the event **{event_name}**.\n\nNew channel will be created for you and further instructions will be provided as soon as the event starts <t:{event_starts}:R>. Good luck!", "register_success_scheduled": "You are now registered for the event **{event_name}**.\n\nNew channel will be created for you and further instructions will be provided as soon as the event starts <t:{event_starts}:R>. Good luck!",
"stage_created": "Event stage has been created.",
"stage_deleted": "Event stage has been deleted.",
"stage_entry": "**Stage {sequence}**\nAnswer: ||{answer}||",
"stage_not_found": "Event stage was not found.",
"stage_sequence_out_of_range": "Stage sequence out of range.",
"stage_updated": "Event stage has been updated.",
"status": "**QuizBot** v{version}\n\nUptime: since <t:{start_time}>", "status": "**QuizBot** v{version}\n\nUptime: since <t:{start_time}>",
"status_git": "**QuizBot** v{version} (`{commit}`)\n\nUptime: up since <t:{start_time}>", "status_git": "**QuizBot** v{version} (`{commit}`)\n\nUptime: up since <t:{start_time}>",
"timezone_invalid": "Timezone **{timezone}** was not found. Please, select one of the timezones provided by the autocompletion.", "timezone_invalid": "Timezone **{timezone}** was not found. Please, select one of the timezones provided by the autocompletion.",
"unexpected_error": "An unexpected error has occurred. Please, contact the administrator.", "unexpected_error": "An unexpected error has occurred. Please, contact the administrator.",
"unregister_not_registered": "You are not registered for this event.", "unregister_not_registered": "You are not registered for this event.",
"unregister_unregistered": "You are no longer registered for this event.", "unregister_unregistered": "You are no longer registered for this event.",
"user_channels_updated": "Event channels of the user **{display_name}** were updated.",
"user_jail_already_jailed": "User **{display_name}** is already jailed.", "user_jail_already_jailed": "User **{display_name}** is already jailed.",
"user_jail_successful": "User **{display_name}** has been jailed and cannot interact with events anymore.", "user_jail_successful": "User **{display_name}** has been jailed and cannot interact with events anymore.",
"user_unjail_not_jailed": "User **{display_name}** is not jailed.", "user_unjail_not_jailed": "User **{display_name}** is not jailed.",
"user_unjail_successful": "User **{display_name}** has been unjailed and can interact with events again.", "user_unjail_successful": "User **{display_name}** has been unjailed and can interact with events again."
"user_channels_updated": "Event channels of the user **{display_name}** were updated."
}, },
"commands": { "commands": {
"config": { "config": {
@@ -47,6 +75,9 @@
}, },
"timezone": { "timezone": {
"description": "Timezone in which events take place" "description": "Timezone in which events take place"
},
"prefer_emojis": {
"description": "Prefer emojis over text messages where available"
} }
} }
}, },

View File

@@ -6,6 +6,7 @@ from bson import ObjectId
from discord import ( from discord import (
ApplicationContext, ApplicationContext,
) )
from libbot.i18n import _
from modules.database import col_events from modules.database import col_events
@@ -22,18 +23,15 @@ async def validate_event_validity(
end_date_internal: datetime = end_date.astimezone(ZoneInfo("UTC")) if to_utc else end_date end_date_internal: datetime = end_date.astimezone(ZoneInfo("UTC")) if to_utc else end_date
if start_date_internal < datetime.now(tz=ZoneInfo("UTC")): if start_date_internal < datetime.now(tz=ZoneInfo("UTC")):
# TODO Make a nice message await ctx.respond(_("event_start_past", "messages", locale=ctx.locale))
await ctx.respond("Start date must not be in the past")
return False return False
if end_date_internal < datetime.now(tz=ZoneInfo("UTC")): if end_date_internal < datetime.now(tz=ZoneInfo("UTC")):
# TODO Make a nice message await ctx.respond(_("event_end_past", "messages", locale=ctx.locale))
await ctx.respond("End date must not be in the past")
return False return False
if start_date_internal >= end_date_internal: if start_date_internal >= end_date_internal:
# TODO Make a nice message await ctx.respond(_("event_end_before_start", "messages", locale=ctx.locale))
await ctx.respond("Start date must be before end date")
return False return False
# TODO Add validation for concurrent events. # TODO Add validation for concurrent events.
@@ -49,8 +47,7 @@ async def validate_event_validity(
query["_id"] = {"$ne": event_id} query["_id"] = {"$ne": event_id}
if (await col_events.find_one(query)) is not None: if (await col_events.find_one(query)) is not None:
# TODO Make a nice message await ctx.respond(_("event_name_duplicate", "messages", locale=ctx.locale))
await ctx.respond("There can only be one active event with the same name")
return False return False
return True return True

View File

@@ -2,6 +2,7 @@ from datetime import datetime
from zoneinfo import ZoneInfo from zoneinfo import ZoneInfo
from discord import ApplicationContext from discord import ApplicationContext
from libbot.i18n import _
async def is_operation_confirmed(ctx: ApplicationContext, confirm: bool) -> bool: async def is_operation_confirmed(ctx: ApplicationContext, confirm: bool) -> bool:
@@ -17,8 +18,7 @@ async def is_event_status_valid(
event: "PycordEvent", event: "PycordEvent",
) -> bool: ) -> bool:
if event.is_cancelled: if event.is_cancelled:
# TODO Make a nice message await ctx.respond(_("event_is_cancelled", "messages", locale=ctx.locale))
await ctx.respond("This event was cancelled.")
return False return False
if ( if (
@@ -26,8 +26,7 @@ async def is_event_status_valid(
<= datetime.now(tz=ZoneInfo("UTC")) <= datetime.now(tz=ZoneInfo("UTC"))
<= event.ends.replace(tzinfo=ZoneInfo("UTC")) <= event.ends.replace(tzinfo=ZoneInfo("UTC"))
): ):
# TODO Make a nice message await ctx.respond(_("event_ongoing_not_editable", "messages", locale=ctx.locale))
await ctx.respond("Ongoing events cannot be modified.")
return False return False
return True return True