import os # OS Locations import yaml # YAML parser for Bot config files import asyncio # Discord Py Dependency import discord # Main Lib from discord.ext import commands # Commands module from discord_slash import SlashCommand, SlashContext, cog_ext, utils # Slash Command Library from discord_slash.utils.manage_commands import create_choice, create_option, create_permission # Slash Command features from discord_slash.model import SlashCommandPermissionType from discord_slash.client import SlashCommand from bot import configFile, yaml_load, yaml_dump, cogsDir, unloadCog #### Separate cog to remove and modify membership registrations that is reloaded if timeslots are added or removed class EditMembership(commands.Cog, name='Edit Membership'): def __init__(self, client): self.client = client #### Only emable for guilds with registered membership types #### N.B.: if there are no guilds with any membership types, then this will throw an exception. #### The solution I have implemented is that this will be classed as a 'secondary' cog: it will not be loaded by default, and will only be loaded if at least one guild has a membership role registered. #### If the deletion of membership roles removes memberships from all guilds, it will unload the cog and delete the commands until a new membership role is defined. guild_ids=[int(guildKey) for guildKey in yaml_load(configFile) if yaml_load(configFile)[guildKey]['membership']] conf = yaml_load(configFile) permissions = {} for guildID in guild_ids: permissions[guildID] = [] permissions[guildID].append(create_permission(id=conf[str(guildID)]['owner'],id_type=SlashCommandPermissionType.USER,permission=True)) for admin in conf[str(guildID)]['roles']['admin']: permissions[guildID].append(create_permission(id=admin,id_type=SlashCommandPermissionType.ROLE,permission=True)) @cog_ext.cog_subcommand( base='config', subcommand_group='membership', name='remove', description='Remove a registered membership role.', # base_description='Commands for configuring the various parameters of the Guild', # base_default_permission=False, # base_permissions=permissions, # subcommand_group_description='Adds a time slot available to the channel for games.', guild_ids=guild_ids, options=[ create_option( name='role', description='The role of the membership type you want to delete.', option_type=8, required=True ) ] ) async def _config_membership_remove(self, ctx:SlashContext, role:discord.Role): conf = yaml_load(configFile) if 'membership' not in conf[str(ctx.guild.id)]: conf[str(ctx.guild.id)]['timeslots'] = {} if role.id in conf[str(ctx.guild.id)]['membership']: conf[str(ctx.guild.id)]['membership'].remove(role.id) yaml_dump(conf, configFile) await ctx.send(f'```Membership type {role.name} has been deleted for the guild `{ctx.guild.name}`.```', hidden=True) await role.delete(reason=f'`/config membership remove` command issued by `{ctx.author.display_name}`.') if not any([x['membership'] for x in yaml_load(configFile).values()]): unloadCog(f'./{cogsDir}/slashcommands/secondary/edit_membership.py') await self.client.slash.sync_all_commands() elif conf[str(ctx.guild.id)]['membership']: output = f'Role `{role.name}` is not a registered membership role in the guild `{ctx.guild.name}`. Please select a valid membership role.\n\n Eligible roles are:\n' for m in conf[str(ctx.guild.id)]['membership']: output = ''.join([output, f'\n{ctx.guild.get_role(m).name}']) await ctx.send(''.join(['```',output,'```']),hidden=True) else: await ctx.send(f'```No roles have been registered as membership types for the guild `{ctx.guild.name}`.```',hidden=True) @cog_ext.cog_subcommand( base='config', subcommand_group='membership', name='list', description='List the existing game memberships on the server.', # base_description='Commands for configuring the various parameters of the Guild', # base_default_permission=False, # base_permissions=permissions, # subcommand_group_description='Adds a time slot available to the channel for games.', guild_ids=guild_ids, ) async def _config_membership_list(self, ctx:SlashContext): conf = yaml_load(configFile) if 'membership' not in conf[str(ctx.guild.id)]: conf[str(ctx.guild.id)]['membership'] = {} if conf[str(ctx.guild.id)]['membership']: output = f'The following membership types have been registered for the guild {ctx.guild.name}:\n' for m in conf[str(ctx.guild.id)]['membership']: output = ''.join([output, f'\n{ctx.guild.get_role(m).name}']) await ctx.send(''.join(['```',output,'```']),hidden=True) else: await ctx.send(f'```No roles have been registered as membership types for the guild `{ctx.guild.name}`.```',hidden=True) def setup(client): client.add_cog(EditMembership(client))