Introduced i18n for /event, /guess, /register and /unregister. Prepared other commands for i18n too

This commit is contained in:
2025-04-27 22:04:14 +02:00
parent 12a88d5a23
commit 9a5edbaa4d
6 changed files with 273 additions and 37 deletions

View File

@@ -11,6 +11,7 @@ from discord import (
) )
from discord.ext.commands import Cog from discord.ext.commands import Cog
from discord.utils import basic_autocomplete from discord.utils import basic_autocomplete
from libbot.i18n import in_every_locale, _
from classes import PycordEvent, PycordEventStage, PycordGuild from classes import PycordEvent, PycordEventStage, PycordGuild
from classes.pycord_bot import PycordBot from classes.pycord_bot import PycordBot
@@ -28,18 +29,49 @@ class CogEvent(Cog):
def __init__(self, bot: PycordBot): def __init__(self, bot: PycordBot):
self.bot: PycordBot = bot self.bot: PycordBot = bot
# TODO Introduce i18n command_group: SlashCommandGroup = SlashCommandGroup(
command_group: SlashCommandGroup = SlashCommandGroup("event", "Event management") "event",
description=_("description", "commands", "event"),
description_localizations=in_every_locale("description", "commands", "event"),
)
# TODO Introduce i18n
@command_group.command( @command_group.command(
name="create", name="create",
description="Create new event", description=_("description", "commands", "event_create"),
description_localizations=in_every_locale("description", "commands", "event_create"),
)
@option(
"name",
description=_("description", "commands", "event_create", "options", "name"),
description_localizations=in_every_locale(
"description", "commands", "event_create", "options", "name"
),
required=True,
)
@option(
"start",
description=_("description", "commands", "event_create", "options", "start"),
description_localizations=in_every_locale(
"description", "commands", "event_create", "options", "start"
),
required=True,
)
@option(
"end",
description=_("description", "commands", "event_create", "options", "end"),
description_localizations=in_every_locale(
"description", "commands", "event_create", "options", "end"
),
required=True,
)
@option(
"thumbnail",
description=_("description", "commands", "event_create", "options", "thumbnail"),
description_localizations=in_every_locale(
"description", "commands", "event_create", "options", "thumbnail"
),
required=False,
) )
@option("name", description="Name of the event", required=True)
@option("start", description="Date when the event starts (DD.MM.YYYY HH:MM)", required=True)
@option("end", description="Date when the event ends (DD.MM.YYYY HH:MM)", required=True)
@option("thumbnail", description="Thumbnail of the event", required=False)
async def command_event_create( async def command_event_create(
self, self,
ctx: ApplicationContext, ctx: ApplicationContext,
@@ -89,21 +121,52 @@ class CogEvent(Cog):
f"Event **{event.name}** has been created and will take place <t:{get_unix_timestamp(event.starts)}:R>." f"Event **{event.name}** has been created and will take place <t:{get_unix_timestamp(event.starts)}:R>."
) )
# TODO Introduce i18n
@command_group.command( @command_group.command(
name="edit", name="edit",
description="Edit event", description=_("description", "commands", "event_edit"),
description_localizations=in_every_locale("description", "commands", "event_edit"),
) )
@option( @option(
"event", "event",
description="Name of the event", description=_("description", "commands", "event_edit", "options", "event"),
description_localizations=in_every_locale(
"description", "commands", "event_edit", "options", "event"
),
autocomplete=basic_autocomplete(autocomplete_active_events), autocomplete=basic_autocomplete(autocomplete_active_events),
required=True, required=True,
) )
@option("name", description="New name of the event", required=False) @option(
@option("start", description="Date when the event starts (DD.MM.YYYY HH:MM)", required=False) "name",
@option("end", description="Date when the event ends (DD.MM.YYYY HH:MM)", required=False) description=_("description", "commands", "event_edit", "options", "name"),
@option("thumbnail", description="Thumbnail of the event", required=False) description_localizations=in_every_locale(
"description", "commands", "event_edit", "options", "name"
),
required=False,
)
@option(
"start",
description=_("description", "commands", "event_edit", "options", "start"),
description_localizations=in_every_locale(
"description", "commands", "event_edit", "options", "start"
),
required=False,
)
@option(
"end",
description=_("description", "commands", "event_edit", "options", "end"),
description_localizations=in_every_locale(
"description", "commands", "event_edit", "options", "end"
),
required=False,
)
@option(
"thumbnail",
description=_("description", "commands", "event_edit", "options", "thumbnail"),
description_localizations=in_every_locale(
"description", "commands", "event_edit", "options", "thumbnail"
),
required=False,
)
async def command_event_edit( async def command_event_edit(
self, self,
ctx: ApplicationContext, ctx: ApplicationContext,
@@ -139,7 +202,9 @@ class CogEvent(Cog):
return return
try: try:
end_date: datetime = pycord_event.ends if end is None else datetime.strptime(end, "%d.%m.%Y %H:%M") end_date: datetime = (
pycord_event.ends if end is None else datetime.strptime(end, "%d.%m.%Y %H:%M")
)
end_date = end_date.replace(tzinfo=guild_timezone) end_date = end_date.replace(tzinfo=guild_timezone)
except ValueError: except ValueError:
# TODO Make a nice message # TODO Make a nice message
@@ -167,18 +232,28 @@ class CogEvent(Cog):
f"Event **{pycord_event.name}** has been updated and will take place <t:{get_unix_timestamp(pycord_event.starts)}:R>." f"Event **{pycord_event.name}** has been updated and will take place <t:{get_unix_timestamp(pycord_event.starts)}:R>."
) )
# TODO Introduce i18n
@command_group.command( @command_group.command(
name="cancel", name="cancel",
description="Cancel event", description=_("description", "commands", "event_cancel"),
description_localizations=in_every_locale("description", "commands", "event_cancel"),
) )
@option( @option(
"event", "event",
description="Name of the event", description=_("description", "commands", "event_cancel", "options", "event"),
description_localizations=in_every_locale(
"description", "commands", "event_cancel", "options", "event"
),
autocomplete=basic_autocomplete(autocomplete_active_events), autocomplete=basic_autocomplete(autocomplete_active_events),
required=True, required=True,
) )
@option("confirm", description="Confirmation of the operation", required=False) @option(
"confirm",
description=_("description", "commands", "event_cancel", "options", "confirm"),
description_localizations=in_every_locale(
"description", "commands", "event_cancel", "options", "confirm"
),
required=False,
)
async def command_event_cancel( async def command_event_cancel(
self, self,
ctx: ApplicationContext, ctx: ApplicationContext,
@@ -221,14 +296,17 @@ class CogEvent(Cog):
# TODO Make a nice message # TODO Make a nice message
await ctx.respond(f"Event **{pycord_event.name}** was cancelled.") await ctx.respond(f"Event **{pycord_event.name}** was cancelled.")
# TODO Introduce i18n
@command_group.command( @command_group.command(
name="show", name="show",
description="Show the details about certain event", description=_("description", "commands", "event_show"),
description_localizations=in_every_locale("description", "commands", "event_show"),
) )
@option( @option(
"event", "event",
description="Name of the event", description=_("description", "commands", "event_show", "options", "event"),
description_localizations=in_every_locale(
"description", "commands", "event_show", "options", "event"
),
autocomplete=basic_autocomplete(autocomplete_active_events), autocomplete=basic_autocomplete(autocomplete_active_events),
required=True, required=True,
) )

View File

@@ -3,6 +3,7 @@ from typing import List
from bson import ObjectId from bson import ObjectId
from bson.errors import InvalidId from bson.errors import InvalidId
from discord import ApplicationContext, Cog, File, option, slash_command 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 import PycordEvent, PycordEventStage, PycordGuild, PycordUser
from classes.pycord_bot import PycordBot from classes.pycord_bot import PycordBot
@@ -14,12 +15,16 @@ class CogGuess(Cog):
def __init__(self, bot: PycordBot): def __init__(self, bot: PycordBot):
self.bot: PycordBot = bot self.bot: PycordBot = bot
# TODO Implement the command
@slash_command( @slash_command(
name="guess", name="guess",
description="Propose an answer to the current event stage", 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"),
) )
@option("answer", description="An answer to the current stage")
async def command_guess(self, ctx: ApplicationContext, answer: str) -> None: async def command_guess(self, ctx: ApplicationContext, answer: str) -> None:
guild: PycordGuild = await self.bot.find_guild(ctx.guild.id) guild: PycordGuild = await self.bot.find_guild(ctx.guild.id)
@@ -31,7 +36,9 @@ class CogGuess(Cog):
if user.is_jailed: if user.is_jailed:
# TODO Make a nice message # TODO Make a nice message
await ctx.respond("You are jailed and cannot interact with events. Please, contact the administrator.") await ctx.respond(
"You are jailed and cannot interact with events. Please, contact the administrator."
)
return return
if user.current_event_id is None or user.current_stage_id is None: if user.current_event_id is None or user.current_stage_id is None:
@@ -44,7 +51,9 @@ class CogGuess(Cog):
stage: PycordEventStage = await self.bot.find_event_stage(user.current_stage_id) stage: PycordEventStage = await self.bot.find_event_stage(user.current_stage_id)
except (InvalidId, RuntimeError): except (InvalidId, RuntimeError):
# TODO Make a nice message # TODO Make a nice message
await ctx.respond("Your event could not be found. Please, report this issue to the event's management.") await ctx.respond(
"Your event could not be found. Please, report this issue to the event's management."
)
return return
if ctx.channel_id != user.event_channels[str(event._id)]: if ctx.channel_id != user.event_channels[str(event._id)]:

View File

@@ -7,6 +7,7 @@ from zoneinfo import ZoneInfo
from bson.errors import InvalidId from bson.errors import InvalidId
from discord import ApplicationContext, Cog, option, slash_command, TextChannel, File from discord import ApplicationContext, Cog, option, slash_command, TextChannel, File
from discord.utils import basic_autocomplete from discord.utils import basic_autocomplete
from libbot.i18n import in_every_locale, _
from classes import PycordEvent, PycordGuild, PycordUser, PycordEventStage from classes import PycordEvent, PycordGuild, PycordUser, PycordEventStage
from classes.pycord_bot import PycordBot from classes.pycord_bot import PycordBot
@@ -24,11 +25,15 @@ class CogRegister(Cog):
# TODO Introduce i18n # TODO Introduce i18n
@slash_command( @slash_command(
name="register", name="register",
description="Enter the selected event", description=_("description", "commands", "register"),
description_localizations=in_every_locale("description", "commands", "register"),
) )
@option( @option(
"event", "event",
description="Name of the event", description=_("description", "commands", "register", "options", "event"),
description_localizations=in_every_locale(
"description", "commands", "register", "options", "event"
),
autocomplete=basic_autocomplete(autocomplete_active_events), autocomplete=basic_autocomplete(autocomplete_active_events),
) )
async def command_register(self, ctx: ApplicationContext, event: str) -> None: async def command_register(self, ctx: ApplicationContext, event: str) -> None:
@@ -49,7 +54,9 @@ class CogRegister(Cog):
if user.is_jailed: if user.is_jailed:
# TODO Make a nice message # TODO Make a nice message
await ctx.respond("You are jailed and cannot interact with events. Please, contact the administrator.") await ctx.respond(
"You are jailed and cannot interact with events. Please, contact the administrator."
)
return return
if pycord_event._id in user.registered_event_ids: if pycord_event._id in user.registered_event_ids:

View File

@@ -4,6 +4,7 @@ from bson.errors import InvalidId
from discord import ApplicationContext, Attachment, SlashCommandGroup, option from discord import ApplicationContext, Attachment, SlashCommandGroup, option
from discord.ext.commands import Cog from discord.ext.commands import Cog
from discord.utils import basic_autocomplete from discord.utils import basic_autocomplete
from libbot.i18n import in_every_locale, _
from classes import PycordEvent, PycordEventStage, PycordGuild from classes import PycordEvent, PycordEventStage, PycordGuild
from classes.pycord_bot import PycordBot from classes.pycord_bot import PycordBot
@@ -21,7 +22,11 @@ class CogStage(Cog):
def __init__(self, bot: PycordBot): def __init__(self, bot: PycordBot):
self.bot: PycordBot = bot self.bot: PycordBot = bot
command_group: SlashCommandGroup = SlashCommandGroup("stage", "Event stage management") command_group: SlashCommandGroup = SlashCommandGroup(
"stage",
description=_("description", "commands", "stage"),
description_localizations=in_every_locale("description", "commands", "stage"),
)
# TODO Introduce i18n # TODO Introduce i18n
# TODO Maybe add an option for order? # TODO Maybe add an option for order?

View File

@@ -1,6 +1,7 @@
from bson.errors import InvalidId from bson.errors import InvalidId
from discord import ApplicationContext, Cog, option, slash_command from discord import ApplicationContext, Cog, option, slash_command
from discord.utils import basic_autocomplete from discord.utils import basic_autocomplete
from libbot.i18n import in_every_locale, _
from classes import PycordEvent, PycordGuild, PycordUser from classes import PycordEvent, PycordGuild, PycordUser
from classes.pycord_bot import PycordBot from classes.pycord_bot import PycordBot
@@ -13,17 +14,27 @@ class CogUnregister(Cog):
def __init__(self, bot: PycordBot): def __init__(self, bot: PycordBot):
self.bot: PycordBot = bot self.bot: PycordBot = bot
# TODO Introduce i18n
@slash_command( @slash_command(
name="unregister", name="unregister",
description="Leave the selected event", description=_("description", "commands", "unregister"),
description_localizations=in_every_locale("description", "commands", "unregister"),
) )
@option( @option(
"event", "event",
description="Name of the event", description=_("description", "commands", "unregister", "options", "event"),
description_localizations=in_every_locale(
"description", "commands", "unregister", "options", "event"
),
autocomplete=basic_autocomplete(autocomplete_user_registered_events), autocomplete=basic_autocomplete(autocomplete_user_registered_events),
) )
@option("confirm", description="Confirmation of the operation", required=False) @option(
"confirm",
description=_("description", "commands", "unregister", "options", "confirm"),
description_localizations=in_every_locale(
"description", "commands", "unregister", "options", "confirm"
),
required=False,
)
async def command_unregister(self, ctx: ApplicationContext, event: str, confirm: bool = False) -> None: async def command_unregister(self, ctx: ApplicationContext, event: str, confirm: bool = False) -> None:
if not (await is_operation_confirmed(ctx, confirm)): if not (await is_operation_confirmed(ctx, confirm)):
return return
@@ -45,7 +56,9 @@ class CogUnregister(Cog):
if user.is_jailed: if user.is_jailed:
# TODO Make a nice message # TODO Make a nice message
await ctx.respond("You are jailed and cannot interact with events. Please, contact the administrator.") await ctx.respond(
"You are jailed and cannot interact with events. Please, contact the administrator."
)
return return
if pycord_event._id not in user.registered_event_ids: if pycord_event._id not in user.registered_event_ids:

View File

@@ -36,6 +36,130 @@
}, },
"config_show": { "config_show": {
"description": "Show the guild's configuration" "description": "Show the guild's configuration"
},
"event": {
"description": "Event management"
},
"event_create": {
"description": "Create new event",
"options": {
"name": {
"description": "Name of the event"
},
"start": {
"description": "Date when the event starts (DD.MM.YYYY HH:MM)"
},
"end": {
"description": "Date when the event ends (DD.MM.YYYY HH:MM)"
},
"thumbnail": {
"description": "Thumbnail of the event"
}
}
},
"event_edit": {
"description": "Edit the event",
"options": {
"event": {
"description": "Name of the event"
},
"name": {
"description": "New name of the event"
},
"start": {
"description": "Date when the event starts (DD.MM.YYYY HH:MM)"
},
"end": {
"description": "Date when the event ends (DD.MM.YYYY HH:MM)"
},
"thumbnail": {
"description": "Thumbnail of the event"
}
}
},
"event_cancel": {
"description": "Cancel the event",
"options": {
"event": {
"description": "Name of the event"
},
"confirm": {
"description": "Confirmation of the operation"
}
}
},
"event_show": {
"description": "Show details about the event",
"options": {
"event": {
"description": "Name of the event"
}
}
},
"guess": {
"description": "Provide an answer to the current event stage",
"options": {
"answer": {
"description": "Answer to the current stage"
}
}
},
"register": {
"description": "Register for the selected event",
"options": {
"event": {
"description": "Name of the event"
}
}
},
"stage": {
"description": "Event stage management"
},
"stage_add": {
"description": "",
"options": {}
},
"stage_edit": {
"description": "",
"options": {}
},
"stage_delete": {
"description": "",
"options": {}
},
"unregister": {
"description": "Leave the selected event",
"options": {
"event": {
"description": "Name of the event"
},
"confirm": {
"description": "Confirmation of the operation"
}
}
},
"user": {
"description": "User management"
},
"user_create_channel": {
"description": "",
"options": {}
},
"user_update_channel": {
"description": "",
"options": {}
},
"user_delete_channel": {
"description": "",
"options": {}
},
"user_jail": {
"description": "",
"options": {}
},
"user_unjail": {
"description": "",
"options": {}
} }
} }
} }