Added migrate command. Bot ready for testing.

This commit is contained in:
Vivek Santayana 2021-07-24 09:25:46 +01:00
parent 882e0b3ab8
commit 1826b9d72b
3 changed files with 127 additions and 30 deletions

View File

@ -104,6 +104,7 @@ The permissions for these commands has been set up at the Cog level.
| Command | Permissions | Syntax and Aliases | Description |
|---|---|---| --- |
| debug | Admin Only | `-debug on/off`| Enables debug features for the bot. Debug features can be used by the Bot's maintainer, as set up during configuration. Activating debug features will need to be authorised by an Admin.|
| migrate | Bot Maintainer Only | `-migrate`| Migrates the guild data from the old bot to the new bot by inferring information from the roles and categories on the server. `After data migration has been completed, please uninstall the migrate.py cog to prevent future data clashes`.|
| testconfig | Admin Only | `-testconfig` or `-configtest` | This command checks the completeness of the configurations of the Guild against the blueprint. |
### Prefix Command
@ -114,4 +115,4 @@ The permission has been set up at the Cog level.
| Command | Permissions | Syntax and Aliases | Description |
|---|---|---| --- |
| changeprefix | Admin Only | `-changeprefix [str]` or `-prefix [str]` | Sets the given string as a prefix. The argument is option, and if not provided an argument it sets the prefix to `-` as the default. |
| changeprefix | Admin Only | `-changeprefix [str]` or `-prefix [str]` | Sets the given string as a prefix. The argument is option, and if not provided an argument it sets the prefix to `-` as the default. |

View File

@ -0,0 +1,125 @@
import os
from dotenv import load_dotenv # Import OS variables from Dotenv file.
load_dotenv() # Load Dotenv. Delete this for production
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 # Slash Command features
from pprint import pprint
from bot import clearConfig, configFile, loadCog, loadCogs, setConfig, unloadCog, unloadCogs, yaml_dump, yaml_load, reloadCog, reloadCogs, categoriesFile, gmFile, lookupFile, dataFile
##### Migrate from Old Database Cog
class Migrate(commands.Cog, name='Migrate Command'):
def __init__(self, client):
self.client = client
#### Permission Check: Only available to the bot's maintainer.
async def cog_check(self, ctx):
return ctx.author.id == int(os.getenv('BOT_MAINTAINER_ID'))
@commands.command(
name='migrate',
aliases=['migrategames','migratedata'],
description='A command to migrate games from the old Guild settings to the new data structure by inferring the information of existing games from the existing roles and channels.',
brief='Infer guild data from games and channels'
)
async def _migrate(self, ctx:commands.Context):
guildStr = str(ctx.guild.id)
conf = yaml_load(configFile)
categories = yaml_load(categoriesFile)
gms = yaml_load(gmFile)
lookup = yaml_load(lookupFile)
data = yaml_load(dataFile)
await ctx.reply(f'```Preparing to migrate guild `{ctx.guild.name}` from the data setup used by the old bot to the new bot. Inferring information from the channel structure.```')
await ctx.channel.trigger_typing()
gNum = 0
for r in ctx.guild.roles:
if r.name.split(': ', maxsplit=1)[0] in ['WED', 'SUN AFT', 'SUN EVE', 'ONE SHOT', 'OTHER']:
flag = True
game_title = r.name.split(': ', maxsplit=1)[1]
t = r.name.split(': ', maxsplit=1)[0]
if t == 'WED':
timeslot = {
'key': 'wedeve',
'value': 'Wednesday Evenings'
}
elif t == 'SUN AFT':
timeslot = {
'key': 'sunaft',
'value': 'Sunday Afternoons'
}
elif t == 'SUN EVE':
timeslot = {
'key': 'suneve',
'value': 'Sunday Evenings'
}
elif t == 'ONE SHOT':
timeslot = {
'key': 'oneshot',
'value': 'One Shots'
}
elif t == 'OTHER':
timeslot = {
'key': 'other',
'value': 'Other'
}
gNum += 1
await r.edit(
reason=f'`migrate` command issued by {ctx.author.display_name}',
mentionable=True,
colour=discord.Colour.green
)
c = discord.utils.get(ctx.guild.categories, name=r.name)
if c is None:
raise(f'Channel category for game `{r.name}` was not found.')
await ctx.channel.trigger_typing()
else:
permissions = c.overwrites
for p in permissions:
if isinstance(p,discord.Member) and permissions[p].manage_channels: break
t = None
tPos = len(ctx.guild.channels)
for tc in c.text_channels:
if tc.position <= tPos:
tPos = tc.position
t = tc
if timeslot['key'] not in conf[guildStr]['timeslots']: conf[guildStr]['timeslots'][timeslot['key']] = timeslot['value']
if guildStr not in data: data[guildStr] = {}
if timeslot['key'] not in data[guildStr]: data[guildStr][timeslot['key']] = {}
data[guildStr][timeslot['key']][str(r.id)] = {
'game_title': game_title,
'gm': p.id,
'max_players': 5,
'min_players': None,
'current_players': 0,
'system': None,
'platform': None,
'role': r.id,
'category': c.id,
'text_channel': t.id,
'header_message': None
}
if guildStr not in lookup: lookup[guildStr] = {}
lookup[guildStr][str(r.id)] = {
'category': c.id,
'gm': p.id,
'time': timeslot['key'],
'game_title': game_title,
'text_channel': t.id
}
if guildStr not in gms: gms[guildStr] = {}
if str(p.id) not in gms[guildStr]: gms[guildStr][str(p.id)] = []
gms[guildStr][str(p.id)].append(r.id)
if str(guildStr) not in categories: categories[guildStr] = {}
categories[guildStr][str(c.id)] = r.id
yaml_dump(data,dataFile)
yaml_dump(lookup,lookupFile)
yaml_dump(gms,gmFile)
yaml_dump(categories,categoriesFile)
yaml_dump(data, dataFile)
await ctx.reply(f'```Finished migrating {gNum} games to the new bot. All games were set up using the minimal mandatory information. The maximum number of players in each game has been reset to 5. Where necessary, new timecodes have been created for games. Please reboot the bot to allow for the new configurations and data to sync, and remove the cog `migrate.py` to avoid future data clashes.```')
def setup(client):
client.add_cog(Migrate(client))

View File

@ -95,7 +95,6 @@ class Debug(commands.Cog, name='Debug Commands'):
bot_token=os.getenv('TEST_3_TOKEN'),
guild_id=ctx.guild.id
)
# try:
target = list(filter(lambda t: t['name'] == command, c))[0]['id']
await utils.manage_commands.remove_slash_command(
bot_id=self.client.user.id,
@ -104,8 +103,6 @@ class Debug(commands.Cog, name='Debug Commands'):
cmd_id=target
)
await ctx.reply(f'```Slash command {command} has been deleted for the guild {ctx.guild.name}.```')
# except:
# raise commands.CommandError(message=f'The command `/{command}` was not found.')
@commands.command(
name='addcommand',
@ -155,31 +152,5 @@ class Debug(commands.Cog, name='Debug Commands'):
await self.client.slash.sync_all_commands()
await ctx.reply(f'```All slash commands have been synced with the Server.```')
# @commands.command(
# name='removecogcommands',
# aliases=['clearcogcommands'],
# description='Removes /commands defined in a particular cog.',
# brief='Remove /command by cog.'
# )
# async def _removecogcommands(self, ctx:commands.Context, cogName:str):
# try:
# SlashCommand.remove_cog_commands(self.client, cogName)
# await ctx.reply(f'```All commands from cog `{cogName}` have been removed.```')
# except Exception as e:
# raise commands.CommandError(e)
# @commands.command(
# name='getcogcommands',
# aliases=['addcogcommands'],
# description='Adds /commands defined in a particular cog.',
# brief='Add /command by cog.'
# )
# async def _getcogcommands(self, ctx:commands.Context, cogName:str):
# try:
# SlashCommand.get_cog_commands(cogName)
# await ctx.reply(f'```All commands from cog `{cogName}` have been removed.```')
# except Exception as e:
# raise commands.CommandError(e)
def setup(client):
client.add_cog(Debug(client))