def addgame(body: dict) -> dict:
    returnmessage = {}
    discordmessage = __get_split_message(body['message'])
    try:
        game = discordmessage[1]
        results = CosmosFramework.QueryItems(
            'SELECT * FROM c WHERE c.game = %s'.format(game), 'game')
        if not bool(results):
            game = {'game': game}
            game['messageid'] = body['messageid']
            CosmosFramework.InsertItem(game, 'game')
    except ValueError:
        returnmessage['channel'] = "You didn't pass in a game"
def startcontest(body: dict) -> dict:
    """Starts the contest in database for contest"""
    returnmessage = {}
    currenttime = int(time.time())
    if str(body['authorid']) not in [
            '298272014005829642', '113304266269003776'
    ]:
        returnmessage['author'] = 'You are not authorized to start a contest'
        return returnmessage
    discordmessage = __get_split_message(body['message'])
    try:  #Catching user not sending number
        if int(discordmessage[1]) > 28:
            returnmessage['author'] = 'Contests may not be longer then 28 days'
            return returnmessage
        endtime = currenttime + (86400 * int(discordmessage[1]))
    except:
        returnmessage[
            'author'] = 'You do not specify how long contests can be for'
        return returnmessage
    results = CosmosFramework.QueryItems(
        'SELECT * FROM c WHERE c.active = true OR c.start = true', 'contest')
    if len(results) > 1:
        returnmessage[
            'author'] = 'It appears multiple contests are currently underway at this time, please let rabbit know'
        return returnmessage
    elif len(results) == 1:
        returnmessage['author'] = 'Contest is currently under way'
        return returnmessage
    else:
        doc = {'starttime': int(currenttime)}
        doc['endtime'] = int(endtime)
        doc['active'] = False
        doc['start'] = True
        statlist = [
            'capture_points', 'damage_dealt', 'damage_received',
            'direct_hits_received', 'dropped_capture_points', 'explosion_hits',
            'explosion_hits_received', 'frags', 'hits', 'piercings',
            'piercings_received', 'shots', 'spotted', 'stun_assisted_damage',
            'stun_number', 'survived_battles'
        ]
        doc['stat'] = statlist[(random.randint(0, len(statlist) - 1))]
        CosmosFramework.InsertItem(doc, 'contest')
        returnmessage['author'] = 'Contest started for {0} days'.format(
            discordmessage[1])
        return returnmessage
def cone(body: dict) -> dict:
    """Cones user, adds information to database and sends return messages"""
    discordmessage = body['message'].split()
    ConeOfShameDiscordId = '525870180505747467'
    returnmessage = {}
    config = CommonFramework.RetrieveConfigOptions('discord')
    try:
        if len(discordmessage) < 3:
            returnmessage['author'] = 'Invalid command format'
            return returnmessage
        timetocone = int(discordmessage[2])
        if timetocone > 2880:
            returnmessage[
                'author'] = 'You cannot Cone someone longer then 2 days'
            return returnmessage
        discordid = int(__discord_id_from_mention(
            discordmessage[1]))  ##Trys int to make sure it's int
        result = __query_cosmos_for_info_by_discordid(discordid)
        if result is None:
            newitem = {}
            newitem['discordid'] = str(discordid)
            result = CosmosFramework.InsertItem(newitem, 'users')
        if 'cone' in result:
            returnmessage['author'] = 'User is already coned'
        statuscode = DiscordFramework.AddUserRole(ConeOfShameDiscordId,
                                                  discordid,
                                                  config['serverid'])
        if statuscode == 204:  #Meaning add role was successful
            result['cone'] = int(time.time()) + (60 * int(timetocone))
            CosmosFramework.ReplaceItem(result['_self'], result)
            returnmessage['channel'] = '{0} muted user for {1} minutes'.format(
                body['authordisplayname'], timetocone)
            returnmessage['author'] = 'Cone issued as requested'
            returnmessage['targetdiscordid'] = discordid
            returnmessage[
                'target'] = 'You were muted for {0} minutes by {1}'.format(
                    timetocone, body['authordisplayname'])
    except Exception as e:
        returnmessage['author'] = 'Following error has occured: {0}'.format(e)
    return returnmessage
cmd = "SELECT discordid,wgid,clan,rank,wgtoken,updated FROM users"
mysqlcur.execute(cmd)
data = mysqlcur.fetchall()
#discordserverid = CommonFramework.RetrieveConfigOptions('discord')
#discordserverid = discordserverid['discordserverid']
#Upload Users
csdbdoc = {}
for row in data:
    csdbdoc.clear()
    csdbdoc['discordid'] = str(row[0])
    csdbdoc['wgid'] = row[1]
    csdbdoc['clan'] = row[2]
    csdbdoc['rank'] = row[3]
    csdbdoc['wgtoken'] = str(row[4])
    csdbdoc['server'] = 'NA'
    CosmosFramework.InsertItem(csdbdoc, 'users')
    #time.sleep(.03)

#Upload Rank info
cmd = "SELECT discordid,wotclan,wotrank from discordroles"
mysqlcur.execute(cmd)
data = mysqlcur.fetchall()
csdbdoc = {}
for row in data:
    csdbdoc.clear()
    csdbdoc['discordid'] = str(row[0])
    csdbdoc['wotclan'] = row[1]
    csdbdoc['wotrank'] = row[2]
    csdbdoc['wotserver'] = 'NA'
    csdbdoc['discordserver'] = '414198832092545037'
    CosmosFramework.InsertItem(csdbdoc, 'roles')
def run_citadel_check():
    def __get_citadel_results() -> dict:
        primary = {}
        secondary = {}
        results = CosmosFramework.QueryItems(
            'SELECT * FROM c WHERE c.citadel = true', 'citadel')
        for result in results:
            secondary['tag'] = result.get('tag')
            secondary['name'] = result.get('name')
            secondary['citadel'] = result.get('citadel')
            secondary['override'] = result.get('citadeloverride')
            secondary['excludereason'] = result.get('excludereason')
            secondary['excludetime'] = result.get('excludetime')
            primary[result['wgid']] = dict(secondary)
            secondary.clear()
        return primary

    def __exclude_clan_from_citadel(clanid):
        citadelroleid = 636372439261249566
        discordserverid = CommonFramework.RetrieveConfigOptions('discord')
        discordserverid = discordserverid['serverid']
        results = CosmosFramework.QueryItems(
            'SELECT * FROM c WHERE c.clan = {0} AND c.citadel = true'.format(
                clanid), 'users')
        for result in results:
            status_code = DiscordFramework.RemoveUserRole(
                citadelroleid, result['discordid'], discordserverid)
            if status_code == 204:
                del result['citadel']
                CosmosFramework.ReplaceItem(result['_self'], result)
            else:
                DiscordFramework.send_discord_private_message(
                    "Citadel checker is having issues", 113304266269003776)
                raise "Clan removal failed"

    def __exclude_wgid_from_citadel(wgid: int) -> None:
        """Removes WGID from citadel"""
        citadelroleid = 636372439261249566
        discordserverid = CommonFramework.RetrieveConfigOptions('discord')
        discordserverid = discordserverid['serverid']
        result = CosmosFramework.QueryItems(
            'SELECT * FROM c WHERE c.discordid="{0}"'.format(wgid), 'users')
        if bool(result):
            result = result[0]
            DiscordFramework.RemoveUserRole(citadelroleid, result['discordid'],
                                            discordserverid)
            DiscordFramework.send_discord_private_message(
                'You have been removed from RDDT citadel due clan/rank changes',
                result['discordid'])
            del result['citadel']
            CosmosFramework.ReplaceItem(result['_self'], result)

    citadelchannelid = 636374196355858452  #Actual citadel channel
    wgapi = CommonFramework.RetrieveConfigOptions('wargaming')
    results = __get_citadel_results()
    apiresults = CommonFramework.get_json_data(
        "https://api.worldoftanks.com/wot/clanratings/top/?application_id={0}&rank_field=gm_elo_rating&limit=200"
        .format(wgapi['apitoken']))
    wgidlist = []
    #Do clan checks ##TODO put this in it's own def block
    for apiresult in apiresults[
            'data']:  #Get information about clans from Wargaming API
        wgidlist.append(apiresult['clan_id'])
        if apiresult['clan_id'] not in results:
            item = {}
            item['wgid'] = apiresult['clan_id']
            item['name'] = apiresult['clan_name']
            item['tag'] = apiresult['clan_tag']
            item['citadel'] = True
            CosmosFramework.InsertItem(item, 'citadel')
        elif apiresult['clan_id'] in results and (
                results[apiresult['clan_id']]['tag'] != apiresult['clan_tag']
                or results[apiresult['clan_id']]['name'] !=
                apiresult['clan_name']):
            #Checks the database and Wargaming API match around clan tag and name, if not, it updates it
            updateitem = CosmosFramework.QueryItems(
                'SELECT * FROM c WHERE c.wgid={0}'.format(
                    apiresult['clan_id']), 'citadel')
            updateitem = updateitem[0]
            updateitem['name'] = apiresult['clan_name']
            updateitem['tag'] = apiresult['clan_tag']
            CosmosFramework.ReplaceItem(updateitem['_self'], updateitem)
    clanlist = list(results.keys())
    removeclans = list(set(clanlist) -
                       set(wgidlist))  #List of clans to be removed
    for removeclan in removeclans:
        claninfo = CosmosFramework.QueryItems(
            'SELECT * FROM c WHERE c.wgid={0}'.format(removeclan), 'citadel')
        claninfo = claninfo[0]
        if 'override' in claninfo and claninfo['override'] is True:
            continue  #Overrides are not removed
        elif 'excludetime' not in claninfo:  #Step 2, put in removal time
            claninfo['excludetime'] = int(time.time(
            )) + 604700  #This is 6 days, 23 hours and ~58 minutes
            message = "WARNING: Clan {0} ({1}) will be removed within 7 days due to lack of clan rating.".format(
                claninfo['name'], claninfo['tag'])
            DiscordFramework.SendDiscordMessage(message, citadelchannelid)
            CosmosFramework.ReplaceItem(claninfo['_self'], claninfo)
        elif claninfo['excludetime'] < int(
                time.time()
        ):  #when their time is hit, mark them no longer allowed in citadel with reason and remove all clan members
            __exclude_clan_from_citadel(removeclan)
            message = "Clan {0} ({1}) has been removed from citadel.".format(
                claninfo['name'], claninfo['tag'])
            DiscordFramework.SendDiscordMessage(message, citadelchannelid)
            claninfo['citadel'] = False
            claninfo['excludetime'] = None
            claninfo['excludereason'] = 'Excluded due to lack of ranking'
            CosmosFramework.ReplaceItem(claninfo['_self'], claninfo)
    #Do user checks ##TODO Put this in it's own def block
    userresults = CosmosFramework.QueryItems(
        'SELECT c.wgid FROM c WHERE c.citadel = true', 'users')
    wgidtocheck = []
    for userresult in userresults:
        wgidtocheck.append(userresult['wgid'])
        if len(wgidtocheck) >= 99:
            apiresults = wotframework.GetPlayersClanInfo(wgidtocheck)
            for apiresult in apiresults:
                if apiresult[1] is None or apiresult[2] not in [
                        'commander', 'executive_officer', 'combat_officer',
                        'personnel_officer'
                ]:
                    __exclude_wgid_from_citadel(apiresult[0])
            wgidtocheck.clear()
def register(message: dict) -> dict:
    """Registration"""
    def genToken(discordId: str) -> str:
        time = str(datetime.datetime.utcnow().microsecond
                   )  # only microseconds in last second. i.e. <100
        hasher = hashlib.sha256(discordId.encode('utf-8'))
        hasher.update(time.encode('utf-8'))
        return hasher.hexdigest()[-8:]

    def genURL(token: str) -> str:
        """Generate FLask URI"""
        link = CommonFramework.RetrieveConfigOptions("registration")
        link = link['flaskuri']
        return "{0}?token={1}".format(link, token)

    authordiscordid = message['authorid']
    link = CommonFramework.RetrieveConfigOptions("registration")
    link = link['flaskuri']
    returnmessage = {}
    result = CosmosFramework.QueryItems(
        'SELECT * FROM c WHERE c.discordid = "{0}"'.format(authordiscordid))
    if not bool(result):  #meaning no result
        document = {}
        document['discordid'] = str(
            authordiscordid)  #Discord IDs are in strings
        document['wgtoken'] = str(genToken(str(authordiscordid)))
        CosmosFramework.InsertItem(document)
        returnmessage[
            'channel'] = "Welcome {0}! Check your direct messages for a link. Please note, I only support NA Server for sign in.".format(
                message['authordisplayname'])
        #returnmessage['author'] = genURL(document['wgtoken'])
        pmresult = DiscordFramework.send_discord_private_message(
            message=genURL(document['wgtoken']), discordid=message['authorid'])
        if pmresult.get('message') == 'Cannot send messages to this user':
            DiscordFramework.DiscordHTTP().add_reaction_to_message(
                channelid=message.get('guildchannelid'),
                messageid=message['messageid'],
                emoji="❌")
        else:
            DiscordFramework.DiscordHTTP().add_reaction_to_message(
                channelid=message.get('guildchannelid'),
                messageid=message['messageid'],
                emoji="\N{WHITE HEAVY CHECK MARK}")
    elif result[0]['wgtoken'] is not None and 'wgid' not in result[0]:
        pmresult = DiscordFramework.send_discord_private_message(
            message=genURL(result[0]['wgtoken']),
            discordid=message['authorid'])
        if pmresult.get('message') == 'Cannot send messages to this user':
            DiscordFramework.DiscordHTTP().add_reaction_to_message(
                channelid=message.get('guildchannelid'),
                messageid=message['messageid'],
                emoji="❌")
        else:
            DiscordFramework.DiscordHTTP().add_reaction_to_message(
                channelid=message.get('guildchannelid'),
                messageid=message['messageid'],
                emoji="\N{WHITE HEAVY CHECK MARK}")
        #returnmessage['author'] = genURL(result[0]['wgtoken'])
    elif result[0]['wgid'] is not None:
        pmresult = DiscordFramework.send_discord_private_message(
            message="You have already registered",
            discordid=message['authorid'])
        if pmresult.get('message') == 'Cannot send messages to this user':
            DiscordFramework.DiscordHTTP().add_reaction_to_message(
                channelid=message.get('guildchannelid'),
                messageid=message['messageid'],
                emoji="❌")
        else:
            DiscordFramework.DiscordHTTP().add_reaction_to_message(
                channelid=message.get('guildchannelid'),
                messageid=message['messageid'],
                emoji="\N{WHITE HEAVY CHECK MARK}")
        #returnmessage['author'] = "You have already registered"
    return returnmessage