geas-bot/app/cogs/controlcommands/migrate.py

125 lines
4.7 KiB
Python

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))