forked from viveksantayana/geas-bot
Vivek Santayana
0f447264ec
Purging not possible because data files keep getting overwritten by parallel processes.
173 lines
7.6 KiB
Python
173 lines
7.6 KiB
Python
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 discord_slash.utils.manage_components import create_select, create_select_option, create_actionrow, wait_for_component
|
|
# from discord_components import *
|
|
|
|
from bot import configFile, yaml_load, yaml_dump, reloadCog, cogsDir, unloadCog, dataFile
|
|
|
|
#### 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 yaml_load(configFile)[guildKey]['timeslots']]
|
|
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)
|
|
data = yaml_load(dataFile)
|
|
guildStr = str(ctx.guild.id)
|
|
if 'timeslots' not in conf[guildStr]:
|
|
conf[guildStr]['timeslots'] = {}
|
|
tsDict = conf[guildStr]['timeslots'].copy()
|
|
optionsList = [create_select_option(label=tsDict[x], value=x, description=x) for x in tsDict]
|
|
try:
|
|
m = await ctx.send(
|
|
content='```Select which time slot you would like to delete.```',
|
|
components=[
|
|
create_actionrow(
|
|
create_select(
|
|
placeholder='Time Slot',
|
|
options= optionsList,
|
|
min_values=1,
|
|
max_values=1
|
|
)
|
|
)
|
|
],
|
|
delete_after=5,
|
|
# hidden=True Can't have hidden responses for menus apparently.
|
|
)
|
|
while True:
|
|
select_ctx = await wait_for_component(self.client,messages=m, timeout=5)
|
|
if select_ctx.author != ctx.author:
|
|
await select_ctx.send(f'```Invalid response: you are not the person who issued the command.```', hidden=True)
|
|
else:
|
|
break
|
|
await m.delete()
|
|
[timeslot] = select_ctx.selected_options
|
|
except asyncio.TimeoutError:
|
|
await ctx.send(f'```Error: Command timed out.```', hidden=True)
|
|
return
|
|
if timeslot not in data[guildStr] or not data[guildStr][timeslot]:
|
|
await ctx.send(f'```Timeslot {conf[guildStr]["timeslots"][timeslot]} with the key `{timeslot}` has been deleted for the guild `{ctx.guild.name}`.```',hidden=True)
|
|
conf[guildStr]['timeslots'].pop(timeslot, None)
|
|
yaml_dump(conf, configFile)
|
|
if not any([x['timeslots'] for x in yaml_load(configFile).values()]):
|
|
unloadCog(f'./{cogsDir}/slashcommands/secondary/manipulate_timeslots.py')
|
|
if self.client.get_cog('Game Management') is not None:
|
|
unloadCog(f'./{cogsDir}/slashcommands/secondary/game_management.py')
|
|
if self.client.get_cog('Game Create') is not None:
|
|
unloadCog(f'./{cogsDir}/slashcommands/secondary/game_create.py')
|
|
if self.client.get_cog('Player Commands') is not None:
|
|
unloadCog(f'./{cogsDir}/slashcommands/secondary/player_commands.py')
|
|
if self.client.get_cog('Pitch Command') is not None:
|
|
unloadCog(f'./{cogsDir}/slashcommands/secondary/pitch.py')
|
|
await self.client.slash.sync_all_commands()
|
|
else:
|
|
await ctx.send('```Error: You cannot delete a timeslot that has existing game entries. Please delete all games first.```',hidden=True)
|
|
|
|
@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)
|
|
guildStr = str(ctx.guild.id)
|
|
if 'timeslots' not in conf[guildStr]:
|
|
conf[guildStr]['timeslots'] = {}
|
|
if key in conf[guildStr]['timeslots']:
|
|
await ctx.send(f'```Timeslot {conf[guildStr]["timeslots"][key]} with the key `{key}` has been renamed to {name} for the guild `{ctx.guild.name}`.```',hidden=True)
|
|
conf[guildStr]['timeslots'][key] = name
|
|
yaml_dump(conf, configFile)
|
|
elif conf[guildStr]['timeslots']:
|
|
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[guildStr]['timeslots']:
|
|
output = ''.join([output, f'\n {c}: {conf[guildStr]["timeslots"][c]}'])
|
|
await ctx.send(''.join([output,'```']),hidden=True)
|
|
else:
|
|
await ctx.send(f'```No timeslots have been defined for the guild `{ctx.guild.name}`.```',hidden=True)
|
|
|
|
@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)
|
|
guildStr = str(ctx.guild.id)
|
|
if 'timeslots' not in conf[guildStr]:
|
|
conf[guildStr]['timeslots'] = {}
|
|
if conf[guildStr]['timeslots']:
|
|
output = f'```The following timeslots have been configured for the guild {ctx.guild.name}:\n(key): (timeslot name)'
|
|
for c in conf[guildStr]['timeslots']:
|
|
output = ''.join([output, f'\n {c}: {conf[guildStr]["timeslots"][c]}'])
|
|
await ctx.send(''.join([output,'```']))
|
|
else:
|
|
await ctx.send(f'```No timeslots have been defined for the guild `{ctx.guild.name}`.```',hidden=True)
|
|
|
|
def setup(client):
|
|
client.add_cog(ManipulateTimeslots(client)) |