Improved some messages and prepared them for i18n
This commit is contained in:
@@ -1,17 +1,17 @@
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from logging import Logger
|
from logging import Logger
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any, override, List, Dict
|
from typing import Any, Dict, List, override
|
||||||
from zoneinfo import ZoneInfo
|
from zoneinfo import ZoneInfo
|
||||||
|
|
||||||
from bson import ObjectId
|
from bson import ObjectId
|
||||||
from discord import Guild, User, TextChannel, Attachment, File
|
from discord import Attachment, File, Guild, TextChannel, User
|
||||||
from libbot.cache.classes import CacheMemcached, CacheRedis
|
from libbot.cache.classes import CacheMemcached, CacheRedis
|
||||||
from libbot.cache.manager import create_cache_client
|
from libbot.cache.manager import create_cache_client
|
||||||
from libbot.pycord.classes import PycordBot as LibPycordBot
|
from libbot.pycord.classes import PycordBot as LibPycordBot
|
||||||
|
|
||||||
from classes import PycordEvent, PycordEventStage, PycordGuild, PycordUser
|
from classes import PycordEvent, PycordEventStage, PycordGuild, PycordUser
|
||||||
from modules.database import col_users, col_events
|
from modules.database import col_events, col_users
|
||||||
from modules.utils import get_logger
|
from modules.utils import get_logger
|
||||||
|
|
||||||
logger: Logger = get_logger(__name__)
|
logger: Logger = get_logger(__name__)
|
||||||
@@ -53,9 +53,7 @@ class PycordBot(LibPycordBot):
|
|||||||
await super().close(**kwargs)
|
await super().close(**kwargs)
|
||||||
|
|
||||||
async def _schedule_tasks(self) -> None:
|
async def _schedule_tasks(self) -> None:
|
||||||
self.scheduler.add_job(
|
self.scheduler.add_job(self._execute_event_controller, trigger="cron", minute="*/1", id="event_controller")
|
||||||
self._execute_event_controller, trigger="cron", minute="*/1", id="event_controller"
|
|
||||||
)
|
|
||||||
|
|
||||||
async def _execute_event_controller(self) -> None:
|
async def _execute_event_controller(self) -> None:
|
||||||
await self._process_events_start()
|
await self._process_events_start()
|
||||||
@@ -105,9 +103,7 @@ class PycordBot(LibPycordBot):
|
|||||||
|
|
||||||
first_stage_files: List[File] | None = first_stage.get_media_files()
|
first_stage_files: List[File] | None = first_stage.get_media_files()
|
||||||
|
|
||||||
await user_channel.send(
|
await user_channel.send(f"First stage...\n\n{first_stage.question}", files=first_stage_files)
|
||||||
f"First stage...\n\n{first_stage.question}", files=first_stage_files
|
|
||||||
)
|
|
||||||
|
|
||||||
# TODO Make a nice message
|
# TODO Make a nice message
|
||||||
await self.notify_admins(
|
await self.notify_admins(
|
||||||
@@ -126,7 +122,7 @@ class PycordBot(LibPycordBot):
|
|||||||
for event in events:
|
for event in events:
|
||||||
guild: Guild = self.get_guild(event.guild_id)
|
guild: Guild = self.get_guild(event.guild_id)
|
||||||
pycord_guild: PycordGuild = await self.find_guild(guild)
|
pycord_guild: PycordGuild = await self.find_guild(guild)
|
||||||
stages: List[PycordEventStage] = await self._get_event_stages(event)
|
stages: List[PycordEventStage] = await self.get_event_stages(event)
|
||||||
|
|
||||||
# TODO Make a nice message
|
# TODO Make a nice message
|
||||||
stages_string: str = "\n\n".join(
|
stages_string: str = "\n\n".join(
|
||||||
@@ -174,7 +170,8 @@ class PycordBot(LibPycordBot):
|
|||||||
|
|
||||||
return users
|
return users
|
||||||
|
|
||||||
async def _get_event_stages(self, event: PycordEvent) -> List[PycordEventStage]:
|
# TODO Add documentation
|
||||||
|
async def get_event_stages(self, event: PycordEvent) -> List[PycordEventStage]:
|
||||||
return [(await self.find_event_stage(stage_id)) for stage_id in event.stage_ids]
|
return [(await self.find_event_stage(stage_id)) for stage_id in event.stage_ids]
|
||||||
|
|
||||||
# TODO Add documentation
|
# TODO Add documentation
|
||||||
@@ -254,9 +251,7 @@ class PycordBot(LibPycordBot):
|
|||||||
return event_stage
|
return event_stage
|
||||||
|
|
||||||
# TODO Document this method
|
# TODO Document this method
|
||||||
async def find_event(
|
async def find_event(self, event_id: str | ObjectId | None = None, event_name: str | None = None) -> PycordEvent:
|
||||||
self, event_id: str | ObjectId | None = None, event_name: str | None = None
|
|
||||||
) -> PycordEvent:
|
|
||||||
if event_id is None and event_name is None:
|
if event_id is None and event_name is None:
|
||||||
raise AttributeError("Either event's ID or name must be provided!")
|
raise AttributeError("Either event's ID or name must be provided!")
|
||||||
|
|
||||||
|
@@ -286,9 +286,7 @@ class PycordEvent:
|
|||||||
stage_index: int = self.stage_ids.index(event_stage_id)
|
stage_index: int = self.stage_ids.index(event_stage_id)
|
||||||
old_stage_index: int = old_stage_ids.index(event_stage_id)
|
old_stage_index: int = old_stage_ids.index(event_stage_id)
|
||||||
|
|
||||||
logger.debug(
|
logger.debug("Indexes for %s: was %s and is now %s", event_stage_id, old_stage_index, stage_index)
|
||||||
"Indexes for %s: was %s and is now %s", event_stage_id, old_stage_index, stage_index
|
|
||||||
)
|
|
||||||
|
|
||||||
if stage_index != old_stage_index:
|
if stage_index != old_stage_index:
|
||||||
await (await bot.find_event_stage(event_stage_id)).update(cache, sequence=stage_index)
|
await (await bot.find_event_stage(event_stage_id)).update(cache, sequence=stage_index)
|
||||||
|
@@ -4,7 +4,15 @@ from logging import Logger
|
|||||||
from typing import Any, Dict, List, Optional
|
from typing import Any, Dict, List, Optional
|
||||||
|
|
||||||
from bson import ObjectId
|
from bson import ObjectId
|
||||||
from discord import Bot, Guild, Member, PermissionOverwrite, TextChannel, Forbidden, Role
|
from discord import (
|
||||||
|
Bot,
|
||||||
|
Forbidden,
|
||||||
|
Guild,
|
||||||
|
Member,
|
||||||
|
PermissionOverwrite,
|
||||||
|
Role,
|
||||||
|
TextChannel,
|
||||||
|
)
|
||||||
from discord.abc import GuildChannel
|
from discord.abc import GuildChannel
|
||||||
from libbot.cache.classes import Cache
|
from libbot.cache.classes import Cache
|
||||||
from pymongo.results import InsertOneResult
|
from pymongo.results import InsertOneResult
|
||||||
@@ -106,12 +114,8 @@ class PycordUser:
|
|||||||
"guild_id": self.guild_id,
|
"guild_id": self.guild_id,
|
||||||
"event_channels": self.event_channels,
|
"event_channels": self.event_channels,
|
||||||
"is_jailed": self.is_jailed,
|
"is_jailed": self.is_jailed,
|
||||||
"current_event_id": (
|
"current_event_id": (self.current_event_id if not json_compatible else str(self.current_event_id)),
|
||||||
self.current_event_id if not json_compatible else str(self.current_event_id)
|
"current_stage_id": (self.current_stage_id if not json_compatible else str(self.current_stage_id)),
|
||||||
),
|
|
||||||
"current_stage_id": (
|
|
||||||
self.current_stage_id if not json_compatible else str(self.current_stage_id)
|
|
||||||
),
|
|
||||||
"registered_event_ids": (
|
"registered_event_ids": (
|
||||||
self.registered_event_ids
|
self.registered_event_ids
|
||||||
if not json_compatible
|
if not json_compatible
|
||||||
@@ -367,9 +371,7 @@ class PycordUser:
|
|||||||
|
|
||||||
# TODO Add documentation
|
# TODO Add documentation
|
||||||
async def set_event_stage(self, stage_id: str | ObjectId | None, cache: Optional[Cache] = None) -> None:
|
async def set_event_stage(self, stage_id: str | ObjectId | None, cache: Optional[Cache] = None) -> None:
|
||||||
await self._set(
|
await self._set(cache, current_stage_id=stage_id if isinstance(stage_id, str) else ObjectId(stage_id))
|
||||||
cache, current_stage_id=stage_id if isinstance(stage_id, str) else ObjectId(stage_id)
|
|
||||||
)
|
|
||||||
|
|
||||||
async def jail(self, cache: Optional[Cache] = None) -> None:
|
async def jail(self, cache: Optional[Cache] = None) -> None:
|
||||||
await self._set(cache, is_jailed=True)
|
await self._set(cache, is_jailed=True)
|
||||||
|
@@ -9,14 +9,14 @@ 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 libbot.i18n import _, in_every_locale
|
||||||
|
|
||||||
from classes import PycordGuild
|
from classes import PycordGuild
|
||||||
from classes.pycord_bot import PycordBot
|
from classes.pycord_bot import PycordBot
|
||||||
from modules.utils import autocomplete_timezones
|
from modules.utils import autocomplete_timezones, is_operation_confirmed
|
||||||
|
|
||||||
|
|
||||||
class Config(Cog):
|
class CogConfig(Cog):
|
||||||
"""Cog with guild configuration commands."""
|
"""Cog with guild configuration commands."""
|
||||||
|
|
||||||
def __init__(self, bot: PycordBot):
|
def __init__(self, bot: PycordBot):
|
||||||
@@ -36,18 +36,14 @@ class Config(Cog):
|
|||||||
@option(
|
@option(
|
||||||
"category",
|
"category",
|
||||||
description=_("description", "commands", "config_set", "options", "category"),
|
description=_("description", "commands", "config_set", "options", "category"),
|
||||||
description_localizations=in_every_locale(
|
description_localizations=in_every_locale("description", "commands", "config_set", "options", "category"),
|
||||||
"description", "commands", "config_set", "options", "category"
|
|
||||||
),
|
|
||||||
required=True,
|
required=True,
|
||||||
)
|
)
|
||||||
@option("channel", description="Text channel for admin notifications", required=True)
|
@option("channel", description="Text channel for admin notifications", required=True)
|
||||||
@option(
|
@option(
|
||||||
"timezone",
|
"timezone",
|
||||||
description=_("description", "commands", "config_set", "options", "timezone"),
|
description=_("description", "commands", "config_set", "options", "timezone"),
|
||||||
description_localizations=in_every_locale(
|
description_localizations=in_every_locale("description", "commands", "config_set", "options", "timezone"),
|
||||||
"description", "commands", "config_set", "options", "timezone"
|
|
||||||
),
|
|
||||||
autocomplete=basic_autocomplete(autocomplete_timezones),
|
autocomplete=basic_autocomplete(autocomplete_timezones),
|
||||||
required=True,
|
required=True,
|
||||||
)
|
)
|
||||||
@@ -63,9 +59,7 @@ class Config(Cog):
|
|||||||
try:
|
try:
|
||||||
timezone_parsed: ZoneInfo = ZoneInfo(timezone)
|
timezone_parsed: ZoneInfo = ZoneInfo(timezone)
|
||||||
except ZoneInfoNotFoundError:
|
except ZoneInfoNotFoundError:
|
||||||
await ctx.respond(
|
await ctx.respond(self.bot._("timezone_invalid", "messages", locale=ctx.locale).format(timezone=timezone))
|
||||||
self.bot._("timezone_invalid", "messages", locale=ctx.locale).format(timezone=timezone)
|
|
||||||
)
|
|
||||||
return
|
return
|
||||||
|
|
||||||
await guild.update(
|
await guild.update(
|
||||||
@@ -85,14 +79,11 @@ class Config(Cog):
|
|||||||
@option(
|
@option(
|
||||||
"confirm",
|
"confirm",
|
||||||
description=_("description", "commands", "config_reset", "options", "confirm"),
|
description=_("description", "commands", "config_reset", "options", "confirm"),
|
||||||
description_localizations=in_every_locale(
|
description_localizations=in_every_locale("description", "commands", "config_reset", "options", "confirm"),
|
||||||
"description", "commands", "config_reset", "options", "confirm"
|
|
||||||
),
|
|
||||||
required=False,
|
required=False,
|
||||||
)
|
)
|
||||||
async def command_config_reset(self, ctx: ApplicationContext, confirm: bool = False) -> None:
|
async def command_config_reset(self, ctx: ApplicationContext, confirm: bool = False) -> None:
|
||||||
if confirm is None or not confirm:
|
if not (await is_operation_confirmed(ctx, confirm)):
|
||||||
await ctx.respond(self.bot._("operation_unconfirmed", "messages", locale=ctx.locale))
|
|
||||||
return
|
return
|
||||||
|
|
||||||
guild: PycordGuild = await self.bot.find_guild(ctx.guild.id)
|
guild: PycordGuild = await self.bot.find_guild(ctx.guild.id)
|
||||||
@@ -123,4 +114,4 @@ class Config(Cog):
|
|||||||
|
|
||||||
|
|
||||||
def setup(bot: PycordBot) -> None:
|
def setup(bot: PycordBot) -> None:
|
||||||
bot.add_cog(Config(bot))
|
bot.add_cog(CogConfig(bot))
|
@@ -1,5 +1,5 @@
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from typing import Dict, List, Any
|
from typing import Any, Dict, List
|
||||||
from zoneinfo import ZoneInfo
|
from zoneinfo import ZoneInfo
|
||||||
|
|
||||||
from bson.errors import InvalidId
|
from bson.errors import InvalidId
|
||||||
@@ -12,12 +12,17 @@ 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 classes import PycordEvent, PycordGuild
|
from classes import PycordEvent, PycordEventStage, PycordGuild
|
||||||
from classes.pycord_bot import PycordBot
|
from classes.pycord_bot import PycordBot
|
||||||
from modules.utils import autocomplete_active_events, validate_event_validity
|
from modules.utils import (
|
||||||
|
autocomplete_active_events,
|
||||||
|
get_unix_timestamp,
|
||||||
|
is_operation_confirmed,
|
||||||
|
validate_event_validity,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class Event(Cog):
|
class CogEvent(Cog):
|
||||||
"""Cog with event management commands."""
|
"""Cog with event management commands."""
|
||||||
|
|
||||||
def __init__(self, bot: PycordBot):
|
def __init__(self, bot: PycordBot):
|
||||||
@@ -46,8 +51,7 @@ class Event(Cog):
|
|||||||
guild: PycordGuild = await self.bot.find_guild(ctx.guild.id)
|
guild: PycordGuild = await self.bot.find_guild(ctx.guild.id)
|
||||||
|
|
||||||
if not guild.is_configured():
|
if not guild.is_configured():
|
||||||
# TODO Make a nice message
|
await ctx.respond(self.bot._("guild_unconfigured_admin", "messages", locale=ctx.locale))
|
||||||
await ctx.respond("Guild is not configured.")
|
|
||||||
return
|
return
|
||||||
|
|
||||||
guild_timezone: ZoneInfo = ZoneInfo(guild.timezone)
|
guild_timezone: ZoneInfo = ZoneInfo(guild.timezone)
|
||||||
@@ -59,8 +63,10 @@ class Event(Cog):
|
|||||||
start_date = start_date.replace(tzinfo=guild_timezone)
|
start_date = start_date.replace(tzinfo=guild_timezone)
|
||||||
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 Introduce i18n
|
||||||
await ctx.respond("Could not parse start and end dates.")
|
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
|
||||||
|
|
||||||
await validate_event_validity(ctx, name, start_date, end_date, guild_timezone)
|
await validate_event_validity(ctx, name, start_date, end_date, guild_timezone)
|
||||||
@@ -78,8 +84,10 @@ class Event(Cog):
|
|||||||
thumbnail=processed_media[0] if thumbnail else None,
|
thumbnail=processed_media[0] if thumbnail else None,
|
||||||
)
|
)
|
||||||
|
|
||||||
# TODO Make a nice message
|
# TODO Introduce i18n
|
||||||
await ctx.respond("Event has been created.")
|
await ctx.respond(
|
||||||
|
f"Event **{event.name}** has been created and will take place <t:{get_unix_timestamp(event.starts)}:R>."
|
||||||
|
)
|
||||||
|
|
||||||
# TODO Introduce i18n
|
# TODO Introduce i18n
|
||||||
@command_group.command(
|
@command_group.command(
|
||||||
@@ -115,8 +123,7 @@ class Event(Cog):
|
|||||||
return
|
return
|
||||||
|
|
||||||
if not guild.is_configured():
|
if not guild.is_configured():
|
||||||
# TODO Make a nice message
|
await ctx.respond(self.bot._("guild_unconfigured_admin", "messages", locale=ctx.locale))
|
||||||
await ctx.respond("Guild is not configured.")
|
|
||||||
return
|
return
|
||||||
|
|
||||||
guild_timezone: ZoneInfo = ZoneInfo(guild.timezone)
|
guild_timezone: ZoneInfo = ZoneInfo(guild.timezone)
|
||||||
@@ -132,9 +139,7 @@ class Event(Cog):
|
|||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
end_date: datetime = (
|
end_date: datetime = pycord_event.ends if end is None else datetime.strptime(end, "%d.%m.%Y %H:%M")
|
||||||
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
|
||||||
@@ -155,8 +160,12 @@ class Event(Cog):
|
|||||||
thumbnail=pycord_event.thumbnail if thumbnail is None else processed_media[0],
|
thumbnail=pycord_event.thumbnail if thumbnail is None else processed_media[0],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# TODO Notify participants about time changes
|
||||||
|
|
||||||
# TODO Make a nice message
|
# TODO Make a nice message
|
||||||
await ctx.respond("Event has been updated.")
|
await ctx.respond(
|
||||||
|
f"Event **{pycord_event.name}** has been updated and will take place <t:{get_unix_timestamp(pycord_event.starts)}:R>."
|
||||||
|
)
|
||||||
|
|
||||||
# TODO Introduce i18n
|
# TODO Introduce i18n
|
||||||
@command_group.command(
|
@command_group.command(
|
||||||
@@ -176,9 +185,7 @@ class Event(Cog):
|
|||||||
event: str,
|
event: str,
|
||||||
confirm: bool = False,
|
confirm: bool = False,
|
||||||
) -> None:
|
) -> None:
|
||||||
if confirm is None or not confirm:
|
if not (await is_operation_confirmed(ctx, confirm)):
|
||||||
# TODO Make a nice message
|
|
||||||
await ctx.respond("Operation not confirmed.")
|
|
||||||
return
|
return
|
||||||
|
|
||||||
guild: PycordGuild = await self.bot.find_guild(ctx.guild.id)
|
guild: PycordGuild = await self.bot.find_guild(ctx.guild.id)
|
||||||
@@ -191,8 +198,7 @@ class Event(Cog):
|
|||||||
return
|
return
|
||||||
|
|
||||||
if not guild.is_configured():
|
if not guild.is_configured():
|
||||||
# TODO Make a nice message
|
await ctx.respond(self.bot._("guild_unconfigured_admin", "messages", locale=ctx.locale))
|
||||||
await ctx.respond("Guild is not configured.")
|
|
||||||
return
|
return
|
||||||
|
|
||||||
start_date: datetime = pycord_event.starts.replace(tzinfo=ZoneInfo("UTC"))
|
start_date: datetime = pycord_event.starts.replace(tzinfo=ZoneInfo("UTC"))
|
||||||
@@ -210,8 +216,10 @@ class Event(Cog):
|
|||||||
|
|
||||||
await pycord_event.cancel()
|
await pycord_event.cancel()
|
||||||
|
|
||||||
|
# TODO Notify participants about cancellation
|
||||||
|
|
||||||
# TODO Make a nice message
|
# TODO Make a nice message
|
||||||
await ctx.respond("Event was cancelled.")
|
await ctx.respond(f"Event **{pycord_event.name}** was cancelled.")
|
||||||
|
|
||||||
# TODO Introduce i18n
|
# TODO Introduce i18n
|
||||||
@command_group.command(
|
@command_group.command(
|
||||||
@@ -237,11 +245,21 @@ class Event(Cog):
|
|||||||
starts_date: datetime = pycord_event.starts.replace(tzinfo=ZoneInfo("UTC"))
|
starts_date: datetime = pycord_event.starts.replace(tzinfo=ZoneInfo("UTC"))
|
||||||
ends_date: datetime = pycord_event.ends.replace(tzinfo=ZoneInfo("UTC"))
|
ends_date: datetime = pycord_event.ends.replace(tzinfo=ZoneInfo("UTC"))
|
||||||
|
|
||||||
|
stages: List[PycordEventStage] = await self.bot.get_event_stages(pycord_event)
|
||||||
|
|
||||||
# TODO Make a nice message
|
# TODO Make a nice message
|
||||||
|
stages_string: str = "\n\n".join(
|
||||||
|
f"**Stage {stage.sequence+1}**\nQuestion: {stage.question}\nAnswer: ||{stage.answer}||"
|
||||||
|
for stage in stages
|
||||||
|
)
|
||||||
|
|
||||||
|
# TODO Show users registered for the event
|
||||||
|
|
||||||
|
# TODO Introduce i18n
|
||||||
await ctx.respond(
|
await ctx.respond(
|
||||||
f"**Event details**\n\nName: {pycord_event.name}\nStarts: <t:{int(starts_date.timestamp())}>\nEnds: <t:{int(ends_date.timestamp())}>"
|
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}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def setup(bot: PycordBot) -> None:
|
def setup(bot: PycordBot) -> None:
|
||||||
bot.add_cog(Event(bot))
|
bot.add_cog(CogEvent(bot))
|
@@ -2,13 +2,13 @@ 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, option, slash_command, File
|
from discord import ApplicationContext, Cog, File, option, slash_command
|
||||||
|
|
||||||
from classes import PycordEvent, PycordUser, PycordGuild, PycordEventStage
|
from classes import PycordEvent, PycordEventStage, PycordGuild, PycordUser
|
||||||
from classes.pycord_bot import PycordBot
|
from classes.pycord_bot import PycordBot
|
||||||
|
|
||||||
|
|
||||||
class Guess(Cog):
|
class CogGuess(Cog):
|
||||||
"""Cog with the guessing command."""
|
"""Cog with the guessing command."""
|
||||||
|
|
||||||
def __init__(self, bot: PycordBot):
|
def __init__(self, bot: PycordBot):
|
||||||
@@ -24,17 +24,14 @@ class Guess(Cog):
|
|||||||
guild: PycordGuild = await self.bot.find_guild(ctx.guild.id)
|
guild: PycordGuild = await self.bot.find_guild(ctx.guild.id)
|
||||||
|
|
||||||
if not guild.is_configured():
|
if not guild.is_configured():
|
||||||
# TODO Make a nice message
|
await ctx.respond(self.bot._("guild_unconfigured", "messages", locale=ctx.locale))
|
||||||
await ctx.respond("Guild is not configured.")
|
|
||||||
return
|
return
|
||||||
|
|
||||||
user: PycordUser = await self.bot.find_user(ctx.author, ctx.guild)
|
user: PycordUser = await self.bot.find_user(ctx.author, ctx.guild)
|
||||||
|
|
||||||
if user.is_jailed:
|
if user.is_jailed:
|
||||||
# TODO Make a nice message
|
# TODO Make a nice message
|
||||||
await ctx.respond(
|
await ctx.respond("You are jailed and cannot interact with events. Please, contact the administrator.")
|
||||||
"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:
|
||||||
@@ -47,9 +44,7 @@ class Guess(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(
|
await ctx.respond("Your event could not be found. Please, report this issue to the event's management.")
|
||||||
"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)]:
|
||||||
@@ -107,4 +102,4 @@ class Guess(Cog):
|
|||||||
|
|
||||||
|
|
||||||
def setup(bot: PycordBot) -> None:
|
def setup(bot: PycordBot) -> None:
|
||||||
bot.add_cog(Guess(bot))
|
bot.add_cog(CogGuess(bot))
|
@@ -1,15 +1,13 @@
|
|||||||
from zoneinfo import ZoneInfo
|
|
||||||
|
|
||||||
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 classes import PycordEvent, PycordGuild, PycordUser
|
from classes import PycordEvent, PycordGuild, PycordUser
|
||||||
from classes.pycord_bot import PycordBot
|
from classes.pycord_bot import PycordBot
|
||||||
from modules.utils import autocomplete_active_events
|
from modules.utils import autocomplete_active_events, get_unix_timestamp
|
||||||
|
|
||||||
|
|
||||||
class Register(Cog):
|
class CogRegister(Cog):
|
||||||
"""Cog with the event registration command."""
|
"""Cog with the event registration command."""
|
||||||
|
|
||||||
def __init__(self, bot: PycordBot):
|
def __init__(self, bot: PycordBot):
|
||||||
@@ -36,17 +34,14 @@ class Register(Cog):
|
|||||||
return
|
return
|
||||||
|
|
||||||
if not guild.is_configured():
|
if not guild.is_configured():
|
||||||
# TODO Make a nice message
|
await ctx.respond(self.bot._("guild_unconfigured", "messages", locale=ctx.locale))
|
||||||
await ctx.respond("Guild is not configured.")
|
|
||||||
return
|
return
|
||||||
|
|
||||||
user: PycordUser = await self.bot.find_user(ctx.author, ctx.guild)
|
user: PycordUser = await self.bot.find_user(ctx.author, ctx.guild)
|
||||||
|
|
||||||
if user.is_jailed:
|
if user.is_jailed:
|
||||||
# TODO Make a nice message
|
# TODO Make a nice message
|
||||||
await ctx.respond(
|
await ctx.respond("You are jailed and cannot interact with events. Please, contact the administrator.")
|
||||||
"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:
|
||||||
@@ -58,9 +53,9 @@ class Register(Cog):
|
|||||||
|
|
||||||
# TODO Make a nice message
|
# TODO Make a nice message
|
||||||
await ctx.respond(
|
await ctx.respond(
|
||||||
f"You are now registered for the event **{pycord_event.name}**.\n\nNew channel will be created for you and further instructions will be provided as soon as the event starts <t:{int((pycord_event.starts.replace(tzinfo=ZoneInfo('UTC'))).timestamp())}:R>. Good luck!"
|
f"You are now registered for the event **{pycord_event.name}**.\n\nNew channel will be created for you and further instructions will be provided as soon as the event starts <t:{get_unix_timestamp(pycord_event.starts)}:R>. Good luck!"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def setup(bot: PycordBot) -> None:
|
def setup(bot: PycordBot) -> None:
|
||||||
bot.add_cog(Register(bot))
|
bot.add_cog(CogRegister(bot))
|
@@ -1,6 +1,4 @@
|
|||||||
from datetime import datetime
|
from typing import Any, Dict, List
|
||||||
from typing import List, Dict, Any
|
|
||||||
from zoneinfo import ZoneInfo
|
|
||||||
|
|
||||||
from bson.errors import InvalidId
|
from bson.errors import InvalidId
|
||||||
from discord import ApplicationContext, Attachment, SlashCommandGroup, option
|
from discord import ApplicationContext, Attachment, SlashCommandGroup, option
|
||||||
@@ -9,31 +7,15 @@ from discord.utils import basic_autocomplete
|
|||||||
|
|
||||||
from classes import PycordEvent, PycordEventStage, PycordGuild
|
from classes import PycordEvent, PycordEventStage, PycordGuild
|
||||||
from classes.pycord_bot import PycordBot
|
from classes.pycord_bot import PycordBot
|
||||||
from modules.utils import autocomplete_active_events, autocomplete_event_stages
|
from modules.utils import (
|
||||||
|
autocomplete_active_events,
|
||||||
|
autocomplete_event_stages,
|
||||||
|
is_event_status_valid,
|
||||||
|
is_operation_confirmed,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
async def validate_event_status(
|
class CogStage(Cog):
|
||||||
ctx: ApplicationContext,
|
|
||||||
event: PycordEvent,
|
|
||||||
) -> bool:
|
|
||||||
if event.is_cancelled:
|
|
||||||
# TODO Make a nice message
|
|
||||||
await ctx.respond("This event was cancelled.")
|
|
||||||
return False
|
|
||||||
|
|
||||||
if (
|
|
||||||
event.starts.replace(tzinfo=ZoneInfo("UTC"))
|
|
||||||
<= datetime.now(tz=ZoneInfo("UTC"))
|
|
||||||
<= event.ends.replace(tzinfo=ZoneInfo("UTC"))
|
|
||||||
):
|
|
||||||
# TODO Make a nice message
|
|
||||||
await ctx.respond("Ongoing events cannot be modified.")
|
|
||||||
return False
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
class Stage(Cog):
|
|
||||||
"""Cog with event stage management commands."""
|
"""Cog with event stage management commands."""
|
||||||
|
|
||||||
def __init__(self, bot: PycordBot):
|
def __init__(self, bot: PycordBot):
|
||||||
@@ -67,8 +49,7 @@ class Stage(Cog):
|
|||||||
guild: PycordGuild = await self.bot.find_guild(ctx.guild.id)
|
guild: PycordGuild = await self.bot.find_guild(ctx.guild.id)
|
||||||
|
|
||||||
if not guild.is_configured():
|
if not guild.is_configured():
|
||||||
# TODO Make a nice message
|
await ctx.respond(self.bot._("guild_unconfigured_admin", "messages", locale=ctx.locale))
|
||||||
await ctx.respond("Guild is not configured.")
|
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -78,12 +59,10 @@ class Stage(Cog):
|
|||||||
await ctx.respond("Event was not found.")
|
await ctx.respond("Event was not found.")
|
||||||
return
|
return
|
||||||
|
|
||||||
if not (await validate_event_status(ctx, pycord_event)):
|
if not (await is_event_status_valid(ctx, pycord_event)):
|
||||||
return
|
return
|
||||||
|
|
||||||
processed_media: List[Dict[str, Any]] = (
|
processed_media: List[Dict[str, Any]] = [] if media is None else await self.bot.process_attachments([media])
|
||||||
[] if media is None else await self.bot.process_attachments([media])
|
|
||||||
)
|
|
||||||
|
|
||||||
event_stage: PycordEventStage = await self.bot.create_event_stage(
|
event_stage: PycordEventStage = await self.bot.create_event_stage(
|
||||||
event=pycord_event,
|
event=pycord_event,
|
||||||
@@ -137,8 +116,7 @@ class Stage(Cog):
|
|||||||
guild: PycordGuild = await self.bot.find_guild(ctx.guild.id)
|
guild: PycordGuild = await self.bot.find_guild(ctx.guild.id)
|
||||||
|
|
||||||
if not guild.is_configured():
|
if not guild.is_configured():
|
||||||
# TODO Make a nice message
|
await ctx.respond(self.bot._("guild_unconfigured_admin", "messages", locale=ctx.locale))
|
||||||
await ctx.respond("Guild is not configured.")
|
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -148,7 +126,7 @@ class Stage(Cog):
|
|||||||
await ctx.respond("Event was not found.")
|
await ctx.respond("Event was not found.")
|
||||||
return
|
return
|
||||||
|
|
||||||
if not (await validate_event_status(ctx, pycord_event)):
|
if not (await is_event_status_valid(ctx, pycord_event)):
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -163,9 +141,7 @@ class Stage(Cog):
|
|||||||
await ctx.respond("Stage sequence out of range.")
|
await ctx.respond("Stage sequence out of range.")
|
||||||
return
|
return
|
||||||
|
|
||||||
processed_media: List[Dict[str, Any]] = (
|
processed_media: List[Dict[str, Any]] = [] if media is None else await self.bot.process_attachments([media])
|
||||||
[] if media is None else await self.bot.process_attachments([media])
|
|
||||||
)
|
|
||||||
|
|
||||||
if not (question is None and answer is None and media is None and remove_media is False):
|
if not (question is None and answer is None and media is None and remove_media is False):
|
||||||
await event_stage.update(
|
await event_stage.update(
|
||||||
@@ -201,16 +177,13 @@ class Stage(Cog):
|
|||||||
async def command_stage_delete(
|
async def command_stage_delete(
|
||||||
self, ctx: ApplicationContext, event: str, stage: str, confirm: bool = False
|
self, ctx: ApplicationContext, event: str, stage: str, confirm: bool = False
|
||||||
) -> None:
|
) -> None:
|
||||||
if confirm is None or not confirm:
|
if not (await is_operation_confirmed(ctx, confirm)):
|
||||||
# TODO Make a nice message
|
|
||||||
await ctx.respond("Operation not confirmed.")
|
|
||||||
return
|
return
|
||||||
|
|
||||||
guild: PycordGuild = await self.bot.find_guild(ctx.guild.id)
|
guild: PycordGuild = await self.bot.find_guild(ctx.guild.id)
|
||||||
|
|
||||||
if not guild.is_configured():
|
if not guild.is_configured():
|
||||||
# TODO Make a nice message
|
await ctx.respond(self.bot._("guild_unconfigured_admin", "messages", locale=ctx.locale))
|
||||||
await ctx.respond("Guild is not configured.")
|
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -220,7 +193,7 @@ class Stage(Cog):
|
|||||||
await ctx.respond("Event was not found.")
|
await ctx.respond("Event was not found.")
|
||||||
return
|
return
|
||||||
|
|
||||||
if not (await validate_event_status(ctx, pycord_event)):
|
if not (await is_event_status_valid(ctx, pycord_event)):
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -238,4 +211,4 @@ class Stage(Cog):
|
|||||||
|
|
||||||
|
|
||||||
def setup(bot: PycordBot) -> None:
|
def setup(bot: PycordBot) -> None:
|
||||||
bot.add_cog(Stage(bot))
|
bot.add_cog(CogStage(bot))
|
@@ -4,10 +4,10 @@ from discord.utils import basic_autocomplete
|
|||||||
|
|
||||||
from classes import PycordEvent, PycordGuild, PycordUser
|
from classes import PycordEvent, PycordGuild, PycordUser
|
||||||
from classes.pycord_bot import PycordBot
|
from classes.pycord_bot import PycordBot
|
||||||
from modules.utils import autocomplete_user_registered_events
|
from modules.utils import autocomplete_user_registered_events, is_operation_confirmed
|
||||||
|
|
||||||
|
|
||||||
class Unregister(Cog):
|
class CogUnregister(Cog):
|
||||||
"""Cog with the event unregistration command."""
|
"""Cog with the event unregistration command."""
|
||||||
|
|
||||||
def __init__(self, bot: PycordBot):
|
def __init__(self, bot: PycordBot):
|
||||||
@@ -25,9 +25,7 @@ class Unregister(Cog):
|
|||||||
)
|
)
|
||||||
@option("confirm", description="Confirmation of the operation", required=False)
|
@option("confirm", description="Confirmation of the operation", 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 confirm is None or not confirm:
|
if not (await is_operation_confirmed(ctx, confirm)):
|
||||||
# TODO Make a nice message
|
|
||||||
await ctx.respond("Operation not confirmed.")
|
|
||||||
return
|
return
|
||||||
|
|
||||||
guild: PycordGuild = await self.bot.find_guild(ctx.guild.id)
|
guild: PycordGuild = await self.bot.find_guild(ctx.guild.id)
|
||||||
@@ -40,17 +38,14 @@ class Unregister(Cog):
|
|||||||
return
|
return
|
||||||
|
|
||||||
if not guild.is_configured():
|
if not guild.is_configured():
|
||||||
# TODO Make a nice message
|
await ctx.respond(self.bot._("guild_unconfigured", "messages", locale=ctx.locale))
|
||||||
await ctx.respond("Guild is not configured.")
|
|
||||||
return
|
return
|
||||||
|
|
||||||
user: PycordUser = await self.bot.find_user(ctx.author, ctx.guild)
|
user: PycordUser = await self.bot.find_user(ctx.author, ctx.guild)
|
||||||
|
|
||||||
if user.is_jailed:
|
if user.is_jailed:
|
||||||
# TODO Make a nice message
|
# TODO Make a nice message
|
||||||
await ctx.respond(
|
await ctx.respond("You are jailed and cannot interact with events. Please, contact the administrator.")
|
||||||
"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:
|
||||||
@@ -66,4 +61,4 @@ class Unregister(Cog):
|
|||||||
|
|
||||||
|
|
||||||
def setup(bot: PycordBot) -> None:
|
def setup(bot: PycordBot) -> None:
|
||||||
bot.add_cog(Unregister(bot))
|
bot.add_cog(CogUnregister(bot))
|
@@ -8,9 +8,10 @@ from discord.ext.commands import Cog
|
|||||||
|
|
||||||
from classes import PycordUser
|
from classes import PycordUser
|
||||||
from classes.pycord_bot import PycordBot
|
from classes.pycord_bot import PycordBot
|
||||||
|
from modules.utils import is_operation_confirmed
|
||||||
|
|
||||||
|
|
||||||
class User(Cog):
|
class CogUser(Cog):
|
||||||
"""Cog with user management commands."""
|
"""Cog with user management commands."""
|
||||||
|
|
||||||
def __init__(self, bot: PycordBot):
|
def __init__(self, bot: PycordBot):
|
||||||
@@ -53,9 +54,7 @@ class User(Cog):
|
|||||||
description="Selected user",
|
description="Selected user",
|
||||||
)
|
)
|
||||||
@option("confirm", description="Confirmation of the operation", required=False)
|
@option("confirm", description="Confirmation of the operation", required=False)
|
||||||
async def command_user_delete_channel(
|
async def command_user_delete_channel(self, ctx: ApplicationContext, user: User, confirm: bool = False) -> None:
|
||||||
self, ctx: ApplicationContext, user: User, confirm: bool = False
|
|
||||||
) -> None:
|
|
||||||
await ctx.respond("Not implemented.")
|
await ctx.respond("Not implemented.")
|
||||||
|
|
||||||
# TODO Introduce i18n
|
# TODO Introduce i18n
|
||||||
@@ -69,23 +68,20 @@ class User(Cog):
|
|||||||
)
|
)
|
||||||
@option("confirm", description="Confirmation of the operation", required=False)
|
@option("confirm", description="Confirmation of the operation", required=False)
|
||||||
async def command_user_jail(self, ctx: ApplicationContext, user: User, confirm: bool = False) -> None:
|
async def command_user_jail(self, ctx: ApplicationContext, user: User, confirm: bool = False) -> None:
|
||||||
if confirm is None or not confirm:
|
if not (await is_operation_confirmed(ctx, confirm)):
|
||||||
await ctx.respond(self.bot._("operation_unconfirmed", "messages", locale=ctx.locale))
|
|
||||||
return
|
return
|
||||||
|
|
||||||
pycord_user: PycordUser = await self.bot.find_user(user, ctx.guild)
|
pycord_user: PycordUser = await self.bot.find_user(user, ctx.guild)
|
||||||
|
|
||||||
if pycord_user.is_jailed:
|
if pycord_user.is_jailed:
|
||||||
# TODO Make a nice message
|
# TODO Introduce i18n
|
||||||
await ctx.respond(f"User **{user.display_name}** is already jailed.")
|
await ctx.respond(f"User **{user.display_name}** is already jailed.")
|
||||||
return
|
return
|
||||||
|
|
||||||
await pycord_user.jail(self.bot.cache)
|
await pycord_user.jail(self.bot.cache)
|
||||||
|
|
||||||
# TODO Make a nice message
|
# TODO Introduce i18n
|
||||||
await ctx.respond(
|
await ctx.respond(f"User **{user.display_name}** has been jailed and cannot interact with events anymore.")
|
||||||
f"User **{user.display_name}** has been jailed and cannot interact with events anymore."
|
|
||||||
)
|
|
||||||
|
|
||||||
# TODO Introduce i18n
|
# TODO Introduce i18n
|
||||||
@command_group.command(
|
@command_group.command(
|
||||||
@@ -98,24 +94,21 @@ class User(Cog):
|
|||||||
)
|
)
|
||||||
@option("confirm", description="Confirmation of the operation", required=False)
|
@option("confirm", description="Confirmation of the operation", required=False)
|
||||||
async def command_user_unjail(self, ctx: ApplicationContext, user: User, confirm: bool = False) -> None:
|
async def command_user_unjail(self, ctx: ApplicationContext, user: User, confirm: bool = False) -> None:
|
||||||
if confirm is None or not confirm:
|
if not (await is_operation_confirmed(ctx, confirm)):
|
||||||
await ctx.respond(self.bot._("operation_unconfirmed", "messages", locale=ctx.locale))
|
|
||||||
return
|
return
|
||||||
|
|
||||||
pycord_user: PycordUser = await self.bot.find_user(user, ctx.guild)
|
pycord_user: PycordUser = await self.bot.find_user(user, ctx.guild)
|
||||||
|
|
||||||
if not pycord_user.is_jailed:
|
if not pycord_user.is_jailed:
|
||||||
# TODO Make a nice message
|
# TODO Introduce i18n
|
||||||
await ctx.respond(f"User **{user.display_name}** is not jailed.")
|
await ctx.respond(f"User **{user.display_name}** is not jailed.")
|
||||||
return
|
return
|
||||||
|
|
||||||
await pycord_user.unjail(self.bot.cache)
|
await pycord_user.unjail(self.bot.cache)
|
||||||
|
|
||||||
# TODO Make a nice message
|
# TODO Introduce i18n
|
||||||
await ctx.respond(
|
await ctx.respond(f"User **{user.display_name}** has been unjailed and can interact with events again.")
|
||||||
f"User **{user.display_name}** has been unjailed and can interact with events again."
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def setup(bot: PycordBot) -> None:
|
def setup(bot: PycordBot) -> None:
|
||||||
bot.add_cog(User(bot))
|
bot.add_cog(CogUser(bot))
|
2
main.py
2
main.py
@@ -6,7 +6,7 @@ from os import makedirs
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from sys import exit
|
from sys import exit
|
||||||
|
|
||||||
from discord import LoginFailure, Intents
|
from discord import Intents, LoginFailure
|
||||||
from libbot.utils import config_get
|
from libbot.utils import config_get
|
||||||
|
|
||||||
from classes.pycord_bot import PycordBot
|
from classes.pycord_bot import PycordBot
|
||||||
|
@@ -7,5 +7,7 @@ from .autocomplete_utils import (
|
|||||||
autocomplete_user_registered_events,
|
autocomplete_user_registered_events,
|
||||||
)
|
)
|
||||||
from .cache_utils import restore_from_cache
|
from .cache_utils import restore_from_cache
|
||||||
|
from .datetime_utils import get_unix_timestamp
|
||||||
from .event_utils import validate_event_validity
|
from .event_utils import validate_event_validity
|
||||||
from .logging_utils import get_logger, get_logging_config
|
from .logging_utils import get_logger, get_logging_config
|
||||||
|
from .validation_utils import is_event_status_valid, is_operation_confirmed
|
||||||
|
@@ -92,8 +92,6 @@ async def autocomplete_event_stages(ctx: AutocompleteContext) -> List[OptionChoi
|
|||||||
event_stages: List[OptionChoice] = []
|
event_stages: List[OptionChoice] = []
|
||||||
|
|
||||||
async for result in col_stages.find(query).sort([("sequence", ASCENDING)]):
|
async for result in col_stages.find(query).sort([("sequence", ASCENDING)]):
|
||||||
event_stages.append(
|
event_stages.append(OptionChoice(f"{result['sequence']+1} ({result['question']})", str(result["_id"])))
|
||||||
OptionChoice(f"{result['sequence']+1} ({result['question']})", str(result["_id"]))
|
|
||||||
)
|
|
||||||
|
|
||||||
return event_stages
|
return event_stages
|
||||||
|
7
modules/utils/datetime_utils.py
Normal file
7
modules/utils/datetime_utils.py
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
from datetime import datetime
|
||||||
|
from zoneinfo import ZoneInfo
|
||||||
|
|
||||||
|
|
||||||
|
# TODO Add documentation
|
||||||
|
def get_unix_timestamp(date: datetime) -> int:
|
||||||
|
return int((date.replace(tzinfo=ZoneInfo("UTC"))).timestamp())
|
33
modules/utils/validation_utils.py
Normal file
33
modules/utils/validation_utils.py
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
from datetime import datetime
|
||||||
|
from zoneinfo import ZoneInfo
|
||||||
|
|
||||||
|
from discord import ApplicationContext
|
||||||
|
|
||||||
|
|
||||||
|
async def is_operation_confirmed(ctx: ApplicationContext, confirm: bool) -> bool:
|
||||||
|
if confirm is None or not confirm:
|
||||||
|
await ctx.respond(ctx.bot._("operation_unconfirmed", "messages", locale=ctx.locale))
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
async def is_event_status_valid(
|
||||||
|
ctx: ApplicationContext,
|
||||||
|
event: "PycordEvent",
|
||||||
|
) -> bool:
|
||||||
|
if event.is_cancelled:
|
||||||
|
# TODO Make a nice message
|
||||||
|
await ctx.respond("This event was cancelled.")
|
||||||
|
return False
|
||||||
|
|
||||||
|
if (
|
||||||
|
event.starts.replace(tzinfo=ZoneInfo("UTC"))
|
||||||
|
<= datetime.now(tz=ZoneInfo("UTC"))
|
||||||
|
<= event.ends.replace(tzinfo=ZoneInfo("UTC"))
|
||||||
|
):
|
||||||
|
# TODO Make a nice message
|
||||||
|
await ctx.respond("Ongoing events cannot be modified.")
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
@@ -5,7 +5,7 @@ readme = "README.md"
|
|||||||
requires-python = ">=3.11"
|
requires-python = ">=3.11"
|
||||||
|
|
||||||
[tool.black]
|
[tool.black]
|
||||||
line-length = 108
|
line-length = 118
|
||||||
target-version = ["py311", "py312", "py313"]
|
target-version = ["py311", "py312", "py313"]
|
||||||
|
|
||||||
[tool.isort]
|
[tool.isort]
|
||||||
|
Reference in New Issue
Block a user