from typing import List from zoneinfo import ZoneInfo, ZoneInfoNotFoundError, available_timezones from discord import ( ApplicationContext, CategoryChannel, SlashCommandGroup, TextChannel, option, AutocompleteContext, ) from discord.ext.commands import Cog from discord.utils import basic_autocomplete from classes import PycordGuild from classes.pycord_bot import PycordBot # TODO Move to staticmethod or to a separate module async def get_timezones(ctx: AutocompleteContext) -> List[str]: return sorted(list(available_timezones())) # TODO Move to staticmethod or to a separate module async def get_languages(ctx: AutocompleteContext) -> List[str]: # TODO Discord normally uses a different set of locales. # For example, "en" being "en-US", etc. This will require changes to locale handling later. return ctx.bot.locales.keys() class Config(Cog): """Cog with guild configuration commands.""" def __init__(self, bot: PycordBot): self.bot: PycordBot = bot # TODO Introduce i18n command_group: SlashCommandGroup = SlashCommandGroup("config", "Guild management") # TODO Introduce i18n @command_group.command( name="set", description="Configure the guild", ) @option("category", description="Category where channels for each user will be created", required=True) @option("channel", description="Text channel for admin notifications", required=True) @option( "timezone", description="Timezone in which events take place", autocomplete=basic_autocomplete(get_timezones), required=True, ) @option( "language", description="Language for bot's messages", autocomplete=basic_autocomplete(get_languages), required=True, ) async def command_config_set( self, ctx: ApplicationContext, category: CategoryChannel, channel: TextChannel, timezone: str, language: str, ) -> None: guild: PycordGuild = await self.bot.find_guild(ctx.guild.id) try: timezone_parsed: ZoneInfo = ZoneInfo(timezone) except ZoneInfoNotFoundError: await ctx.respond(f"Timezone {timezone} was not found.") return await guild.update( self.bot.cache, channel_id=channel.id, category_id=category.id, timezone=str(timezone_parsed), language=language, ) # TODO Make a nice message await ctx.respond("Okay.") # TODO Introduce i18n @command_group.command( name="reset", description="Reset the guild's configuration", ) @option("confirm", description="Confirmation of the operation", required=False) async def command_config_reset(self, ctx: ApplicationContext, confirm: bool = False) -> None: if confirm is None or not confirm: # TODO Make a nice message await ctx.respond("Operation not confirmed.") return guild: PycordGuild = await self.bot.find_guild(ctx.guild.id) await guild.purge(self.bot.cache) # TODO Make a nice message await ctx.respond("Okay.") # TODO Introduce i18n @command_group.command( name="show", description="Show the guild's configuration", ) async def command_config_reset(self, ctx: ApplicationContext) -> None: guild: PycordGuild = await self.bot.find_guild(ctx.guild.id) # TODO Make a nice message await ctx.respond( f"**Guild config**\n\nChannel: <#{guild.channel_id}>\nCategory: <#{guild.category_id}>" ) def setup(bot: PycordBot) -> None: bot.add_cog(Config(bot))