geas-bot/app/cogs/slashcommands/secondary/pitch.py
2021-07-27 11:51:02 +01:00

186 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, ButtonStyle
from discord_slash.client import SlashCommand
from discord_slash.utils.manage_components import create_select, create_select_option, create_actionrow, wait_for_component, create_button, create_actionrow
from bot import configFile, yaml_load, yaml_dump, cogsDir, unloadCog, dataFile, lookupFile, gmFile, categoriesFile, pitchesFile, loadCog
#### Pitch Command
class Pitch(commands.Cog, name='Pitch Command'):
def __init__(self, client):
self.client = client
conf=yaml_load(configFile)
permissions={}
guild_ids = list(set.intersection(set([int(guildKey) for guildKey in yaml_load(configFile) if yaml_load(configFile)[guildKey]['timeslots']]),set([int(guildKey) for guildKey in yaml_load(configFile) if 'bot' in yaml_load(configFile)[guildKey]['roles'] and type(yaml_load(configFile)[guildKey]['roles']['bot']) is int])))
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))
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_slash(
name='pitch',
description='Initialises the menu for game pitches.',
default_permission=False,
permissions=permissions,
guild_ids=guild_ids,
)
async def _pitch(self, ctx:SlashContext):
await ctx.channel.trigger_typing()
conf = yaml_load(configFile)
data = yaml_load(dataFile)
lookup = yaml_load(lookupFile)
gms = yaml_load(gmFile)
categories = yaml_load(categoriesFile)
guildStr = str(ctx.guild.id)
pitches = yaml_load(pitchesFile)
if guildStr not in pitches: pitches[guildStr] = {}
if pitches[guildStr]:
await ctx.send(f'```Error: pitches are already running for the guild `{ctx.guild.name}`. Please close the existing pitches first before issuing this command.```')
return
if 'timeslots' not in conf[guildStr]: conf[guildStr]['timeslots'] = {}
tsDict = {k: conf[guildStr]['timeslots'][k] for k in data[guildStr] if data[guildStr][k]}
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 for which you would like to run pitches for.```',
delete_after=5,
components=[
create_actionrow(
create_select(
placeholder='Time Slot',
options= optionsList,
min_values=1,
max_values=1
)
)
]
)
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
await ctx.channel.trigger_typing()
p = discord.PermissionOverwrite()
p.read_messages = False
p.send_messages = False
await ctx.channel.edit(
reason=f'/pitch command issued by {ctx.author.display_name}',
overwrites = {
ctx.guild.default_role: p
}
)
if timeslot not in pitches[guildStr]: pitches[guildStr][timeslot] = {}
pitches[guildStr][timeslot]['indices'] = {}
pitches[guildStr][timeslot]['entries'] = [x for x in data[guildStr][timeslot].values()]
pitches[guildStr][timeslot]['entries'].sort(key= lambda x: x['game_title'])
header_message = await ctx.channel.send(
content=f'**Game listing for {conf[guildStr]["timeslots"][timeslot]}**\n_ _```The following are the games that are being pitched. Please select which game you would like to join by clicking on the `Join` button below.```'
)
pitches[guildStr][timeslot]['header_message'] = header_message.id
pitches[guildStr][timeslot]['messages'] = []
pitches[guildStr][timeslot]['roles'] = {}
for index, element in enumerate(pitches[guildStr][timeslot]['entries']):
gm = await self.client.fetch_user(element["gm"])
o = f'_ _\n***{element["game_title"]}*** (GM: {gm.mention})\n```\n'
if element['system'] is not None: o = ''.join([o,f'System: {element["system"]}\n'])
if element['min_players'] is not None: o = ''.join([o,f'Minimum Players: {str(element["min_players"])} '])
if element['max_players'] is not None: o = ''.join([o,f'Maximum Players: {str(element["max_players"])}\n'])
if element['platform'] is not None: o = ''.join([o,f'Platform: {element["platform"]}\n'])
o = ''.join([o,f'```'])
spaces_remaining = element["max_players"] - element["current_players"]
o = ''.join([o,f'~~Spaces Remaining: {str(0)}~~'])if spaces_remaining <= 0 else ''.join([o,f'Spaces Remaining: {str(spaces_remaining)}'])
m = await ctx.channel.send(
content=o,
components=[
create_actionrow(
create_button(
style=ButtonStyle.green,
label='Join',
emoji='🉑',
custom_id=f'join_{index}'
),
create_button(
style=ButtonStyle.red,
label='Leave',
emoji='🈳',
custom_id=f'leave_{index}'
)
)
]
)
pitches[guildStr][timeslot]['messages'].append(m.id)
r = discord.utils.find(lambda x: x.id == element['role'],ctx.guild.roles)
pitches[guildStr][timeslot]['roles'][index] = r.id
pitches[guildStr][timeslot]['indices'][r.id] = index
newcomer = returning_player = None
if 'newcomer' in conf[guildStr]['roles']: newcomer = discord.utils.find(lambda x: x.id == conf[guildStr]['roles']['newcomer'], ctx.guild.roles)
if 'returning_player' in conf[guildStr]['roles']: returning_player = discord.utils.find(lambda x: x.id == conf[guildStr]['roles']['returning_player'], ctx.guild.roles)
buttons = []
if returning_player is not None:
buttons.append(
create_button(
style= ButtonStyle.grey,
label= 'Allow Returning Players',
emoji= '🔁',
custom_id='allow_returning'
)
)
if newcomer is not None:
buttons.append(
create_button(
style= ButtonStyle.grey,
label= 'Allow Newcomers',
emoji= '🆕',
custom_id='allow_newcomers'
)
)
buttons.append(
create_button(
style= ButtonStyle.green,
label= 'Allow All',
emoji='🚪',
custom_id='allow_all'
)
)
buttons.append(
create_button(
style= ButtonStyle.red,
label= 'Close Pitches',
emoji='🔒',
custom_id='close_pitches'
)
)
control = await ctx.channel.send(
content='_ _\n```Control Panel:\nFor Admin Use Only```',
components=[
create_actionrow(
*buttons
)
]
)
pitches[guildStr][timeslot]['control'] = control.id
yaml_dump(pitches,pitchesFile)
if self.client.get_cog('Pitch Listener') is None:
loadCog(f'./{cogsDir}/events/secondary/pitch_listener.py')
#### Activate global pitch listener
def setup(client):
client.add_cog(Pitch(client))