""" Set command heirarchy. """ import nextcord from nextcord.ext import commands from sqlalchemy import select from sqlalchemy.orm import Session # pylint: disable=import-error from database_setup.sql_data_classes import CategoryGroup, Guild, engine from utilities.utils import MAX_LINE_LENGTH, autofill_groups class SetCog(commands.Cog, name="Set command."): """ Class holds commands for setting variables in guild's database. """ def __init__(self) -> None: """ Default constructor for SetCog class. Does nothing. """ @nextcord.slash_command(default_member_permissions=nextcord.Permissions(administrator=True)) async def set(self, interaction: nextcord.Interaction): """ Parent slash command for setting settings. Never called. """ @set.subcommand(description="Registers the channel for a Category Group's messages.") async def group_output_channel( self, interaction: nextcord.Interaction, group_id: str = nextcord.SlashOption( name="group", description="Category Group to assign to channel.", required=True ), channel: nextcord.abc.GuildChannel | None = nextcord.SlashOption( description="Channel to register", required=False, channel_types=[nextcord.ChannelType.text], default=None, ), ) -> None: """ Command function to register a CategoryGroup's output channel. Args: interaction (nextcord.Interaction): Interaction that invoked the command. group_id (str): String representation of Group id to register channel to. Is SlashOption. channel (nextcord.abc.GuildChannel, optional): Channel to register Is a SlashOption. Limited to text channels, Defaults to None. """ if not channel: channel = interaction.channel channel_id = channel.id with Session(engine) as session: stmt = ( select(CategoryGroup) .where(CategoryGroup.GuildId == interaction.guild_id) .where(CategoryGroup.GroupId == int(group_id)) ) group = session.scalar(stmt) group.ChannelId = channel_id session.commit() await interaction.send(f"Registered <#{channel_id}>.", ephemeral=True) @set.subcommand( description="Set character length for a category. Can cut off username/score. Affects all categories." ) async def pad_length( self, interaction: nextcord.Interaction, group_id: str = nextcord.SlashOption( name="group", description="Category Group to assign pad length to.", required=True ), length: int = nextcord.SlashOption( description="Number of characters alloted to a category.", required=True, default=26, min_value=7, max_value=MAX_LINE_LENGTH, ), ) -> None: """ Changes guild's category pad length. Args: interaction (nextcord.Interaction): Interaction that invoked the command group_id (str): String representation of Group id to set pad length in. Is SlashOption. length (int): Number of characters. Is SlashOption. Defaults to 26. """ with Session(engine) as session: stmt = ( select(CategoryGroup) .where(CategoryGroup.GuildId == interaction.guild_id) .where(CategoryGroup.GroupId == int(group_id)) ) group = session.scalar(stmt) group.PadLength = length session.commit() await interaction.response.send_message( f"Category pad length set to {length} for {group.GroupName}", ephemeral=True ) @set.subcommand( description="Registers the channel for submission messages. Currently this information is deprecated." ) async def submission_channel( self, interaction: nextcord.Interaction, channel: nextcord.abc.GuildChannel | None = nextcord.SlashOption( description="Channel to register", required=False, channel_types=[nextcord.ChannelType.text], default=None, ), ) -> None: """ Command function to register the submission message channel. Args: interaction (nextcord.Interaction): Interaction that invoked the command channel Optional[nextcord.abc.GuildChannel], optional): Channel to register Is a SlashOption. Limited to text channels, Defaults to None. """ if not channel: channel = interaction.channel with Session(engine) as session: channel_id = channel.id stmt = select(Guild).where(Guild.GuildId == interaction.guild_id) guild = session.scalar(stmt) guild.SubmissionChannel = channel_id session.commit() await interaction.send(f"Registered <#{channel_id}>.", ephemeral=True) @set.subcommand(description="Set username length for a Group of Categories.") async def username_length( self, interaction: nextcord.Interaction, group_id: str = nextcord.SlashOption( name="group", description="Group to change username length of.", required=True ), length: int = nextcord.SlashOption( description="Number of characters.", required=True, default=12, min_value=1, max_value=30 ), ) -> None: """ Changes guild's username length limit. Args: interaction (nextcord.Interaction): Interaction that invoked the command length (int): Number of characters. Is SlashOption. Defaults to 12. """ with Session(engine) as session: stmt = ( select(CategoryGroup) .where(CategoryGroup.GuildId == interaction.guild_id) .where(CategoryGroup.GroupId == int(group_id)) ) group = session.scalar(stmt) group.UsernameLength = length session.commit() await interaction.response.send_message(f"Username length set to {length}.", ephemeral=True) @set.subcommand(description="Registers the channel for verification messages.") async def verify_channel( self, interaction: nextcord.Interaction, channel: nextcord.abc.GuildChannel | None = nextcord.SlashOption( description="Channel to register", required=False, channel_types=[nextcord.ChannelType.text], default=None, ), ) -> None: """ Command function to register the verification message channel. Args: interaction (nextcord.Interaction): Interaction that invoked the command channel (Optional[nextcord.abc.GuildChannel]): Channel to register Is a SlashOption. Limited to text channels, Defaults to None. """ if not channel: channel = interaction.channel channel_id = channel.id with Session(engine) as session: stmt = select(Guild).where(Guild.GuildId == interaction.guild_id) guild = session.scalar(stmt) guild.VerificationChannel = channel_id session.commit() await interaction.send(f"Registered <#{channel_id}>.", ephemeral=True) @group_output_channel.on_autocomplete("group_id") @pad_length.on_autocomplete("group_id") @username_length.on_autocomplete("group_id") async def group_autocomplete(self, interaction: nextcord.Interaction, group_id: str): """ Sends results from autofill_groups back to group_output_channel for autocompletion of group_id. Args: interaction (nextcord.Interaction): Interaction with command. group_id (str): String to run autocompletion against. """ await interaction.response.send_autocomplete(autofill_groups(interaction.guild_id, group_id))