def get_gm_elo_data(top: int) -> dict:
    """Gets top clans by ELO for Global Map"""
    wgapi = CommonFramework.RetrieveConfigOptions('wargaming')
    uri = "https://api.worldoftanks.com/wot/clanratings/top/ \
    ?application_id={0}&rank_field=gm_elo_rating&limit={1}".format(
        wgapi['apitoken'], top)
    apiresults = CommonFramework.get_json_data(uri)
    return apiresults
def player_data_info(wgid: List[int]) -> dict:
    apikey = CommonFramework.RetrieveConfigOptions("wargaming")
    apikey = apikey['apitoken']
    if len(wgid) > 100:
        return None
    else:
        wgidcsv = ""
        for wid in wgid:
            wgidcsv += "{0},".format(wid)
        wgidcsv = wgidcsv[:-1]
        uri = 'https://api.worldoftanks.com/wot/account/info/?application_id={0}&account_id={1}&extra=statistics.random'.format(
            apikey, wgidcsv)
        playerdata = CommonFramework.get_json_data(uri)
        return playerdata
def GetPlayersClanInfo(wgids: List[int]) -> List[Tuple[int, int, str]]:
    apikey = CommonFramework.RetrieveConfigOptions("wargaming")
    apikey = apikey['apitoken']
    wgids = ",".join(map(str, wgids))
    uri = "https://api.worldoftanks.com/wgn/clans/membersinfo/?application_id={0}&account_id={1}".format(
        str(apikey), wgids)
    playerData = CommonFramework.get_json_data(uri)  # type: dict

    def getInfo(rawinfo: Tuple[str, Any]) -> Tuple[int, int, str]:
        wgid, info = rawinfo
        clan = info['clan']['clan_id'] if info is not None else None
        role = info['role'] if info is not None else None
        return int(wgid), clan, role

    return list(map(getInfo, playerData['data'].items()))
Ejemplo n.º 4
0
 def __remove_cone_role(discordid: str) -> int:
     ConeOfShameDiscordId = '525870180505747467'
     config = CommonFramework.RetrieveConfigOptions('discord')
     status_code = DiscordFramework.RemoveUserRole(ConeOfShameDiscordId,
                                                   discordid,
                                                   config['serverid'])
     return status_code
Ejemplo n.º 5
0
def SetupCosmosDB(container=None):
        #Azure Function Setup
        config = CommonFramework.RetrieveConfigOptions("cosmosdb")
        cosmosclient = cosmos_client.CosmosClient(url_connection=config['ENDPOINT'],auth={'masterKey': config['PRIMARYKEY']})
        db = next((data for data in cosmosclient.ReadDatabases() if data['id'] == config['DATABASE']))
        if container is None:
                coll = next((coll for coll in cosmosclient.ReadContainers(db['_self']) if coll['id'] == config['CONTAINER']))
        else:
                coll = next((coll for coll in cosmosclient.ReadContainers(db['_self']) if coll['id'] == str(container)))
        return cosmosclient, coll
def citadel(body: dict) -> dict:
    returnmessage = {}
    citadelroleid = 636372439261249566
    citadelchannelid = 636374196355858452
    result = __query_cosmos_for_info_by_discordid(str(body['authorid']))
    discordserverid = CommonFramework.RetrieveConfigOptions('discord')
    discordserverid = discordserverid['serverid']
    if result is None or 'wgid' not in result:
        returnmessage[
            'author'] = "You have not registered with the bot, this is mandatory. Please visit <#507725600073449482> to register or please complete registration."
        return returnmessage
    wgid = [int(result['wgid'])]
    claninfo = wotframework.GetPlayersClanInfo(wgid)
    claninfo = claninfo[0]
    if claninfo[1] is None:
        returnmessage[
            'author'] = "You are not a member of clan, citadel access is denied"
        return returnmessage
    elif claninfo[2] not in [
            'commander', 'executive_officer', 'combat_officer',
            'personnel_officer'
    ]:
        returnmessage[
            'author'] = "Citadel access is restricted to Clan officers only"
        return returnmessage
    results = CosmosFramework.QueryItems(
        'SELECT * FROM c WHERE c.wgid = {0}'.format(claninfo[1]), 'citadel')
    if bool(results):  #Meaning their clan ID is in citadel container
        result = results[0]
        if result['citadel'] is True:
            DiscordFramework.AddUserRole(citadelroleid, body['authorid'],
                                         discordserverid)
            returnmessage['author'] = "Access granted"
            DiscordFramework.SendDiscordMessage(
                "{0} from {1} has joined the citadel.".format(
                    body['authordisplayname'], result['name']),
                citadelchannelid)
            result = __query_cosmos_for_info_by_discordid(str(
                body['authorid']))
            result['citadel'] = True
            CosmosFramework.ReplaceItem(result['_self'], result)
        else:
            returnmessage[
                'author'] = 'Citadel access has been revoked because: {0}. If you believe access should be granted, please see moderator.'.format(
                    result['excludereason'])
    else:
        returnmessage[
            'author'] = 'Citadel access is restricted to clans who rank on Global Map ELO. If you believe access should be granted, please see moderator.'
    return returnmessage
 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)
 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 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
 def __post_contest_results(channelid: str,
                            statrandom: bool = True) -> None:
     """Posts Contest results, Needs Channel ID and if results should be randomized"""
     results = CosmosFramework.QueryItems(
         'SELECT TOP 3 * FROM c WHERE IS_DEFINED(c.contest.currentscore) AND c.contest.currentscore != 0 ORDER BY c.contest.currentscore DESC',
         'users')
     if not bool(results):  ##No users with score greater then 1
         return None
     config = CommonFramework.RetrieveConfigOptions('discord')
     place = 1
     if statrandom is True:
         message = 'Please note that score is slightly randomized when displayed and may lead to appear that lower place is winning, true score is used when determining place.'
         DiscordFramework.SendDiscordMessage(message=message,
                                             channelid=channelid)
     DiscordFramework.SendDiscordMessage('Current Contest results:',
                                         channelid)
     for result in results:
         userdata = DiscordFramework.get_user_guild_info(
             result['discordid'], config['serverid'])
         if result['contest']['currentscore'] == 0:
             place += 1
             continue
         if 'code' in userdata and userdata['code'] == 10007:
             CosmosFramework.delete_user_from_cosmos_by_discordid(
                 result['discordid'])
             continue
         if userdata['nick'] is None:
             nick = userdata['user']['username']
         else:
             nick = userdata['nick']
         if statrandom is True:
             score = int(result['contest']['currentscore'] *
                         (random.randint(100, 110) / 100))
         else:
             score = int(result['contest']['currentscore'])
         discordmessage = "{0} is currently in #{1} place with score: {2}".format(
             nick, place, score)
         DiscordFramework.SendDiscordMessage(discordmessage, channelid)
         place += 1
def checkroles(discordid: str) -> None:
    """Checks user for proper roles"""
    def get_responsible_roles() -> list:
        """Gets a list of Discordid roles that bot thinks it's responsible for"""
        results = CosmosFramework.QueryItems(
            "SELECT DISTINCT(c.discordid) FROM c", 'roles')
        listofroles = []
        for result in results:
            listofroles.append(result['discordid'])
        return listofroles

    discord_request = DiscordFramework.DiscordHTTP()
    config = CommonFramework.RetrieveConfigOptions('discord')
    playerresult = CosmosFramework.QueryItems(
        'SELECT * FROM c WHERE c.discordid="{0}"'.format(discordid), 'users')
    if not bool(playerresult):  #Meaning unknown Discord ID
        return None
    playerresult = playerresult[0]
    resproles = get_responsible_roles()  #Roles controlled by the bot
    userroles = DiscordFramework.GetUserRoles(discordid, config['serverid'])
    if userroles == 0:
        return None  #User unknown, exit
    if playerresult['rank'] == "friend":
        friendrole = CosmosFramework.QueryItems(
            'SELECT * FROM c WHERE c.wotrank = "friend"', 'roles')
        friendrole = friendrole[0]
        friendrole = friendrole['discordid']
        if int(friendrole) not in userroles:
            discord_request.add_role_to_user(guildid=config['serverid'],
                                             userid=discordid,
                                             roleid=friendrole)
            #DiscordFramework.AddUserRole(friendrole,discordid,config['serverid'])
        resproles.remove(friendrole)
    else:
        userrankrole = CosmosFramework.QueryItems(
            'SELECT c.discordid FROM c WHERE c.wotrank ="{0}" AND c.wotclan = {1}'
            .format(playerresult['rank'], playerresult['clan']), 'roles')
        userrankrole = userrankrole[0]['discordid']
        userclanrole = CosmosFramework.QueryItems(
            'SELECT c.discordid FROM c WHERE c.wotclan = {0} AND c.wotrank = null'
            .format(playerresult['clan']), 'roles')
        userclanrole = userclanrole[0]['discordid']
        if int(userrankrole) not in userroles or int(
                userclanrole) not in userroles:
            discord_request.add_role_to_user(guildid=config['serverid'],
                                             userid=discordid,
                                             roleid=userclanrole)
            discord_request.add_role_to_user(guildid=config['serverid'],
                                             userid=discordid,
                                             roleid=userrankrole)
            #DiscordFramework.AddUserRole(userclanrole,discordid,config['serverid'])
            #DiscordFramework.AddUserRole(userrankrole,discordid,config['serverid'])
        resproles.remove(userclanrole)
        resproles.remove(userrankrole)
    commonroles = set(int(i) for i in resproles) & set(
        userroles)  #userroles comes back as int
    if bool(commonroles
            ):  #Meaning there is roles showing up that shouldn't be there
        for role in commonroles:
            discord_request.remove_role_from_user(guildid=config['serverid'],
                                                  userid=discordid,
                                                  roleid=role)
            time.sleep(2)
            #DiscordFramework.RemoveUserRole(role,discordid,config['serverid'])
    return None
"""
This is check for Wargaming NA Stream and posting if active
"""
import time

from Modules.twitch import TwitchAPI
import Modules.CommonFramework as CommonFramework
import Modules.DiscordFramework as DiscordFramework

i = 0
channelid = '414607006821777440'
options = CommonFramework.RetrieveConfigOptions("twitch")
twitch = TwitchAPI(options['clientid'], options['clientsecret'])
users = ['worldoftanksna']
active = {}
for user in users:
    active[user] = False
while i < 1008:
    for user in users:
        currentstreams = twitch.get_streams_by_userlogin(userlogin=user)
        if len(currentstreams['data']) > 0 and active[user] is False:
            embed = {"title": f"Twitch Streamer {user} is active"}
            embed['type'] = 'rich'
            title = currentstreams['data'][0]['title']
            embed[
                'description'] = f"Twitch Stream {user} is currently active and streaming {title}"
            embed['url'] = f"https://www.twitch.tv/{user}"
            DiscordFramework.SendDiscordMessage(message=None,
                                                channelid=channelid,
                                                embed=embed)
            active[user] = True
Ejemplo n.º 13
0
#This module is to provide web interface for users to register. This module simply takes token generated by another application and matches up WG OpenID response then stores WGID in
#the database for RDDT_Teamspeak_Bot Module to interact with.

from flask import Flask, request, redirect, session
from flask_openid import OpenID
import re
#import MySQLdb
import Modules.CommonFramework as CommonFramework
import Modules.CosmosFramework as CosmosFramework

#Flask Setup
config = CommonFramework.RetrieveConfigOptions('registration')

app_id = config['app_id']
oid = OpenID()
app = Flask(__name__)
app.secret_key = config['app_secret']

port = 8080
wgid_handler = '/wgid/redirect'
response_message = 'Processing registration'
login_message = 'Please click here to log in with wargaming'
auth_url = '/wgid/auth'

min_battles = 0


@app.route(auth_url)
def landing_page():
    if 'token' not in request.values:
        return 'Invalid request'
import discord
from azure.servicebus import QueueClient, Message
import json
#Local Modules
import Modules.CommonFramework as CommonFramework
import Modules.DiscordFramework as DiscordFramework
import Modules.CosmosFramework as CosmosFramework

#import Modules.EventGridFramework as EventGridFramework
#import Modules.DiscordBotFramework as DiscordBotFramework

##Discord options
discordoptions = CommonFramework.RetrieveConfigOptions('discord')
token = discordoptions['token']
discordclient = discord.Client()
commandprefix = '!'

#Discord Incoming Service Bus setup
servicebusoptions = CommonFramework.RetrieveConfigOptions('discordlisten')
connection_str = servicebusoptions['connectionstring']
queue_path = servicebusoptions['queue']
servicebusclient = QueueClient.from_connection_string(connection_str,
                                                      queue_path)
###


@discordclient.event
async def on_message(message):
    if message.author == discordclient.user:
        return None  #Bot ignores itself
Ejemplo n.º 15
0
import json
import requests
import os
from time import sleep
import Modules.CommonFramework as CommonFramework

baseuri = "https://discord.com/api"
config = CommonFramework.RetrieveConfigOptions("discord")


class DiscordHTTP:
    def __init__(self) -> None:
        global config
        self.token = config['token']
        self.baseuri = "https://discord.com/api"

    def __generate_discord_header(self) -> dict:
        header = {
            'Authorization':
            str(f"Bot {self.token}"),
            'User-Agent':
            '/r/worldoftanks Discord Bot (https://github.com/Rabbit994/RDDT-Discord-Bot-Azure, v1.0.5)'
        }
        return header

    def __send_discord_put_request(self, uri: str):
        statuscode = 0
        for x in range(0, 3):
            r = requests.put(uri, headers=self.__generate_discord_header())
            statuscode = r.status_code
            if statuscode == 429:  #If
Ejemplo n.º 16
0
#This handles incoming discord messages

import json
from time import sleep
import requests
##3rd Party Modules
from azure.servicebus import QueueClient, Message
##Local Modules
import Modules.CosmosFramework as CosmosFramework
import Modules.CommonFramework as CommonFramework
import Modules.DiscordFramework as DiscordFramework
import Modules.DiscordBotFramework as DiscordBotFramework
from Modules.DiscordBotFramework import MessageHandler

#region Service Bus for incoming
config = CommonFramework.RetrieveConfigOptions('discordlisten')
connection_str = config['connectionstring']
queue = config['queue']
sbclient = QueueClient.from_connection_string(connection_str,queue)
#endregion

def __return_message(body:dict, returnmessage:dict) -> None:
    """Gets original message and return message and sends to proper channels"""
    if 'channel' in returnmessage:
        DiscordFramework.SendDiscordMessage(returnmessage['channel'],body['guildchannelid'])
    if 'author' in returnmessage:
        DiscordFramework.send_discord_private_message(returnmessage['author'],body['authorid'])
    if 'target' in returnmessage and 'targetdiscordid' in returnmessage:
        DiscordFramework.send_discord_private_message(returnmessage['target'],returnmessage['targetdiscordid'])
    return None
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
 def genURL(token: str) -> str:
     """Generate FLask URI"""
     link = CommonFramework.RetrieveConfigOptions("registration")
     link = link['flaskuri']
     return "{0}?token={1}".format(link, token)
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()
import json
import MySQLdb
import Modules.CommonFramework as CommonFramework
import Modules.CosmosFramework as CosmosFramework
import time

mysqlcinfo = CommonFramework.RetrieveConfigOptions("mysql")
mysqlconn = MySQLdb.connect(host=mysqlcinfo['server'],
                            user=mysqlcinfo['username'],
                            passwd=mysqlcinfo['password'],
                            db=mysqlcinfo['database'])
mysqlconn.autocommit(True)
mysqlcur = mysqlconn.cursor()
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)
def GetClanInfo(wgclanid: int) -> dict:
    apikey = CommonFramework.RetrieveConfigOptions("wargaming")
    apikey = apikey['apitoken']
    uri = f"https://api.worldoftanks.com/wot/clans/info/?application_id={apikey}&clan_id={wgclanid}"
    return CommonFramework.get_json_data(uri)