diff --git a/cogs/commands/__init__.py b/cogs/commands/__init__.py index dbe5bde..5c1d3f2 100644 --- a/cogs/commands/__init__.py +++ b/cogs/commands/__init__.py @@ -8,6 +8,7 @@ from cogs.commands.remove import RemoveCog from cogs.commands.request import RequestCog from cogs.commands.set import SetCog from cogs.commands.test import TestCog +from cogs.commands.time import TimeCog from cogs.commands.view import ViewCog @@ -19,6 +20,7 @@ def setup(bot: commands.Bot) -> None: bot.add_cog(RefreshCog(bot)) bot.add_cog(RemoveCog()) bot.add_cog(RequestCog(bot)) - bot.add_cog(TestCog(bot)) - bot.add_cog(ViewCog()) bot.add_cog(SetCog()) + bot.add_cog(TestCog(bot)) + bot.add_cog(TimeCog()) + bot.add_cog(ViewCog()) diff --git a/cogs/commands/test.py b/cogs/commands/test.py index 1e93b1e..c8dd53e 100644 --- a/cogs/commands/test.py +++ b/cogs/commands/test.py @@ -6,14 +6,13 @@ import nextcord from nextcord.ext import application_checks, commands from classes.election_cycle import ElectionCycle -from utils import get_current_election_cycle +from utils import GUILDS, get_current_election_cycle if TYPE_CHECKING: from config import DakinyConfig ME = 206602713511886849 -GUILDS = [1000247361639030804] def is_me(): # noqa: ANN201 diff --git a/cogs/commands/time.py b/cogs/commands/time.py new file mode 100644 index 0000000..cb3ddef --- /dev/null +++ b/cogs/commands/time.py @@ -0,0 +1,109 @@ +"""Contains commands for time commands.""" + +from datetime import MAXYEAR, MINYEAR, UTC, datetime + +import nextcord +from nextcord.ext import commands + +from utils import GUILDS + + +class TimeCog(commands.Cog, name="Time Commands"): + """Class holds time commands.""" + + @nextcord.slash_command(guild_ids=GUILDS) + async def time(self, interaction: nextcord.Interaction) -> None: + """Parent slash command. Never called.""" + + @time.subcommand( + description="Get a discord timestamp of the given game time. If date information is left blank, uses current day." # noqa: E501 + ) + async def at( # noqa: PLR0913 + self, + interaction: nextcord.Interaction, + hour: int = nextcord.SlashOption( + description="The hour you want a timestamp of. Given in gametime/UTC.", + min_value=0, + max_value=23, + required=True, + ), + minute: int = nextcord.SlashOption( + description="The minute you want a timestamp of. Given in gametime/UTC.", + min_value=0, + max_value=59, + required=True, + ), + year: int = nextcord.SlashOption( + description="Year to make timestamp of.", required=False, min_value=MINYEAR, max_value=MAXYEAR + ), + month: int = nextcord.SlashOption( + description="Month to make timestamp of.", required=False, min_value=1, max_value=12 + ), + day: int = nextcord.SlashOption( + description="Day to make timestamp of.", required=False, min_value=1, max_value=31 + ), + ephemeral: bool = nextcord.SlashOption( # noqa: FBT001 + description="Whether the replying message will be public or not.", required=False, default=True + ), + ) -> None: + """ + Replies with a discord timestamp of given UTC time. + + Args: + interaction (nextcord.Interaction): Interaction with the command. + hour (int): The hour in UTC to make the timestamp of.. + minute (int): The minute in UTC to make the timestamp of.. + year (int): The year to make the timestamp of. + month (int): The month to make the timestamp of. + day (int): The day to make the timestamp of. + ephemeral (bool): Whether the response is ephemeral or not. + """ + gametime_today: datetime = datetime.now(tz=UTC).replace(hour=hour, minute=minute) + + if year is not None: + gametime_today = gametime_today.replace(year=year) + + if month is not None and day is not None: + try: + gametime_today = gametime_today.replace(month=month, day=day) + except ValueError: + await interaction.response.send_message(f"Day {day} is out of range for month {month}.", ephemeral=True) + return + else: + if month is not None: + try: + gametime_today = gametime_today.replace(month=month) + except ValueError: + await interaction.response.send_message( + f"Today ({gametime_today.day}) is out of range for month {month}.", ephemeral=True + ) + return + + if day is not None: + try: + gametime_today = gametime_today.replace(day=day) + except ValueError: + await interaction.response.send_message( + f"Day {day} is out of range for this month {gametime_today.month}.", ephemeral=True + ) + return + + await interaction.response.send_message(content=f"", ephemeral=ephemeral) + + @time.subcommand(description="Get the current time in game.") + async def gametime( + self, + interaction: nextcord.Interaction, + ephemeral: bool = nextcord.SlashOption( # noqa: FBT001 + description="Whether the replying message will be public or not.", required=False, default=True + ), + ) -> None: + """ + Replies with the current time in game. + + Args: + interaction (nextcord.Interaction): Interaction with the command. + ephemeral: (bool): Whether the response is ephemeral or not. + """ + gametime = datetime.now(tz=UTC) + await interaction.response.send_message(content=f"{gametime.hour}:{gametime.minute}", ephemeral=ephemeral) diff --git a/utils.py b/utils.py index 3501231..e02ada8 100644 --- a/utils.py +++ b/utils.py @@ -27,6 +27,7 @@ REPO_DIR = "./dakiny-messages" MESSAGES_DIR = f"{REPO_DIR}/messages" TEMPLATES_DIR = f"{REPO_DIR}/message_templates" MAX_DISCORD_MESSAGE_LENGTH = 2000 +GUILDS = [1000247361639030804, 239758371358638080] VoteType = StrEnum("VoteType", ["COUNCIL", "DISCORDMANAGER", "CLANLEADER"])