2021-07-18 23:16:58 +01:00
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 , reloadCog , cogsDir , unloadCog
#### Separate cog to remove and modify timeslots that is reloaded if timeslots are added or removed
class ManipulateTimeslots ( commands . Cog , name = ' Manipulate Timeslots ' ) :
def __init__ ( self , client ) :
self . client = client
#### Only emable for guilds with timeslots
#### N.B.: if there are no guilds with any timeslots, 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 timeslot configured.
#### If the deletion of timeslots removes timeslots from all guilds, it will unload the cog and delete the commands until a new timeslot is defined.
guild_ids = [ int ( guildKey ) for guildKey in yaml_load ( configFile ) if len ( yaml_load ( configFile ) [ guildKey ] [ ' timeslots ' ] ) > 0 ]
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 = ' timeslots ' ,
name = ' remove ' ,
description = ' Remove a configured game timeslot. ' ,
# 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 = ' timeslot ' ,
description = ' The timeslot you wish to delete. ' ,
option_type = 3 ,
required = True
)
]
)
async def _config_timeslots_remove ( self , ctx : SlashContext , timeslot : str ) :
conf = yaml_load ( configFile )
if ' timeslots ' not in conf [ str ( ctx . guild . id ) ] :
conf [ str ( ctx . guild . id ) ] [ ' timeslots ' ] = { }
if timeslot in conf [ str ( ctx . guild . id ) ] [ ' timeslots ' ] :
await ctx . send ( f ' ```Timeslot { conf [ str ( ctx . guild . id ) ] [ " timeslots " ] [ timeslot ] } with the key ` { timeslot } ` has been deleted for the guild ` { ctx . guild . name } `.``` ' )
conf [ str ( ctx . guild . id ) ] [ ' timeslots ' ] . pop ( timeslot , None )
yaml_dump ( conf , configFile )
2021-07-19 15:30:04 +01:00
if not all ( [ x [ ' timeslots ' ] for x in yaml_load ( configFile ) . values ( ) ] ) :
2021-07-18 23:16:58 +01:00
unloadCog ( f ' ./ { cogsDir } /slashcommands/secondary/manipulate_timeslots.py ' )
2021-07-19 15:30:04 +01:00
if self . client . get_cog ( ' Game Management ' ) is not None :
unloadCog ( f ' ./ { cogsDir } /slashcommands/secondary/game_management.py ' )
if self . client . get_cog ( ' Game Setup ' ) is not None :
unloadCog ( f ' ./ { cogsDir } /slashcommands/secondary/game_setup.py ' )
2021-07-18 23:16:58 +01:00
await self . client . slash . sync_all_commands ( )
elif len ( conf [ str ( ctx . guild . id ) ] [ ' timeslots ' ] ) > 0 :
output = f ' ```Timeslot ` { timeslot } ` was not found in the guild ` { ctx . guild . name } `. Please enter a valid key. \n \n Available timeslots are: \n (key): (timeslot name) '
for c in conf [ str ( ctx . guild . id ) ] [ ' timeslots ' ] :
output = ' ' . join ( [ output , f ' \n { c } : { conf [ str ( ctx . guild . id ) ] [ " timeslots " ] [ c ] } ' ] )
await ctx . send ( ' ' . join ( [ output , ' ``` ' ] ) )
else :
await ctx . send ( f ' ```No timeslots have been defined for the guild ` { ctx . guild . name } `.``` ' )
@cog_ext.cog_subcommand (
base = ' config ' ,
subcommand_group = ' timeslots ' ,
name = ' modify ' ,
description = ' Modify the value of a configured gametime slot. ' ,
# 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 = ' key ' ,
description = ' Key of timeslot being modified ' ,
option_type = 3 ,
required = True ,
) ,
create_option (
name = ' name ' ,
description = ' New value for timeslot name ' ,
option_type = 3 ,
required = True
)
]
)
async def _config_timeslots_modify ( self , ctx : SlashContext , key : str , name : str ) :
conf = yaml_load ( configFile )
if ' timeslots ' not in conf [ str ( ctx . guild . id ) ] :
conf [ str ( ctx . guild . id ) ] [ ' timeslots ' ] = { }
if key in conf [ str ( ctx . guild . id ) ] [ ' timeslots ' ] :
await ctx . send ( f ' ```Timeslot { conf [ str ( ctx . guild . id ) ] [ " timeslots " ] [ key ] } with the key ` { key } ` has been renamed to { name } for the guild ` { ctx . guild . name } `.``` ' )
conf [ str ( ctx . guild . id ) ] [ ' timeslots ' ] [ key ] = name
yaml_dump ( conf , configFile )
elif len ( conf [ str ( ctx . guild . id ) ] [ ' timeslots ' ] ) > 0 :
output = f ' ```Timeslot ` { key } ` was not found in the guild ` { ctx . guild . name } `. Please enter a valid key. \n \n Available timeslots are: \n (key): (timeslot name) '
for c in conf [ str ( ctx . guild . id ) ] [ ' timeslots ' ] :
output = ' ' . join ( [ output , f ' \n { c } : { conf [ str ( ctx . guild . id ) ] [ " timeslots " ] [ c ] } ' ] )
await ctx . send ( ' ' . join ( [ output , ' ``` ' ] ) )
else :
await ctx . send ( f ' ```No timeslots have been defined for the guild ` { ctx . guild . name } `.``` ' )
@cog_ext.cog_subcommand (
base = ' config ' ,
subcommand_group = ' timeslots ' ,
name = ' list ' ,
description = ' List the existing game timeslots 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_timeslots_list ( self , ctx : SlashContext ) :
conf = yaml_load ( configFile )
if ' timeslots ' not in conf [ str ( ctx . guild . id ) ] :
conf [ str ( ctx . guild . id ) ] [ ' timeslots ' ] = { }
if len ( conf [ str ( ctx . guild . id ) ] [ ' timeslots ' ] ) > 0 :
output = f ' ```The following timeslots have been configured for the guild { ctx . guild . name } : \n (key): (timeslot name) '
for c in conf [ str ( ctx . guild . id ) ] [ ' timeslots ' ] :
output = ' ' . join ( [ output , f ' \n { c } : { conf [ str ( ctx . guild . id ) ] [ " timeslots " ] [ c ] } ' ] )
await ctx . send ( ' ' . join ( [ output , ' ``` ' ] ) )
else :
await ctx . send ( f ' ```No timeslots have been defined for the guild ` { ctx . guild . name } `.``` ' )
def setup ( client ) :
client . add_cog ( ManipulateTimeslots ( client ) )