diff --git a/blitzstats.ini.default b/blitzstats.ini.default index 27f2d77..6b3d51f 100644 --- a/blitzstats.ini.default +++ b/blitzstats.ini.default @@ -11,4 +11,6 @@ #db_user = blitzAnalysiz #db_password = PASSWORD #db_ssl = True -#db_cert_req = 2 \ No newline at end of file +#db_cert_req = 2 +#db_ssl_cert_file= cert.pem +#db_ssl_ca_file = ca.pem \ No newline at end of file diff --git a/blitzutils.py b/blitzutils.py index 7d4be15..33f72b2 100644 --- a/blitzutils.py +++ b/blitzutils.py @@ -210,6 +210,9 @@ def bldDictHierarcy(d : dict, key : str, value) -> dict: error(str(err)) return None +## ----------------------------------------------------------- +#### Class WG +## ----------------------------------------------------------- class WG: @@ -275,6 +278,7 @@ class WG: } tanks = None + tanks_by_tier = None nations = [ 'ussr', 'germany', 'usa', 'china', 'france', 'uk', 'japan', 'other', 'european'] nation_id = { @@ -305,10 +309,10 @@ class WG: } accountID_server= { - 'ru' : range(0, int(5e8)), - 'eu' : range(int(5e8), int(10e8)), - 'na' : range(int(1e9),int(2e9)), - 'asia': range(int(2e9),int(4e9)) + 'ru' : range(0, int(5e8)), + 'eu' : range(int(5e8), int(10e8)), + 'na' : range(int(1e9),int(2e9)), + 'asia' : range(int(2e9),int(4e9)) } def __init__(self, WG_appID = None, tankopedia_fn = None, maps_fn = None): @@ -518,11 +522,21 @@ class WG: try: async with aiofiles.open(tankopedia_fn, 'rt', encoding='utf8') as f: self.tanks = json.loads(await f.read()) + self.tanks_by_tier = dict() + for tier in range(1,11): + self.tanks_by_tier[str(tier)]= list() + for tank in self.tanks['data']: + self.tanks_by_tier[str(tank['tier'])].append(tank['tank_id']) return True except Exception as err: error('Could not read tankopedia: ' + tankopedia_fn + '\n' + str(err)) return False + + async def getTanksByTier(self, tier: int) -> list(): + """Returns tank_ids by tier""" + return self.tanks_by_tier[str(tier)] + def getUrlClanInfo(self, server: str, clanID: int) -> str: return self.URL_WG_server[server] + self.URL_WG_clanInfo + self.WG_appID + '&clan_id=' + str(clanID) @@ -530,7 +544,7 @@ class WG: server = self.getServer(accountID) return self.URL_WG_server[server] + self.URL_WG_playerTankList + self.WG_appID + '&account_id=' + str(accountID) - def getUrlPlayerTankStats(self, accountID, tankID, fields) -> str: + def getUrlPlayerTankStats(self, accountID: int, tankID: int, fields: list) -> str: server = self.getServer(accountID) url = self.URL_WG_server[server] + self.URL_WG_playerTankStats + self.WG_appID + '&account_id=' + str(accountID) + '&tank_id=' + str(tankID) if (fields != None) and (len(fields) > 0): @@ -539,6 +553,17 @@ class WG: field_str = '' return url + '&fields=tank_id' + field_str + def getUrlPlayerTanksStats(self, accountID: int, tankIDs: list, fields: list) -> str: + server = self.getServer(accountID) + tank_ids = '%2C'.join(str(x) for x in tankIDs) + url = self.URL_WG_server[server] + self.URL_WG_playerTankStats + self.WG_appID + '&account_id=' + str(accountID) + '&tank_id=' + tank_ids + if (fields != None) and (len(fields) > 0): + field_str = '%2C' + '%2C'.join(fields) + else: + field_str = '' + return url + '&fields=tank_id' + field_str + + def getUrlPlayerStats(self, accountID, fields) -> str: server = self.getServer(accountID) return self.URL_WG_server[server] + self.URL_WG_playerStats + self.WG_appID + '&account_id=' + str(accountID) + '&fields=' + '%2C'.join(fields) @@ -568,7 +593,24 @@ class WG: except Exception as err: error(str(err)) return None - + + async def getPlayerTanksStats(self, accountID: int, tankIDs : list, fields: list) -> dict: + """Get player's stats (WR, # of battles) in a tank""" + # debug('Started') + if self.session == None: + error('Session must be initialized first') + sys.exit(1) + try: + debug('AccountID: ' + str(accountID) + ' TankID: ' + ','.join(tankIDs)) + url = self.getUrlPlayerTanksStats(accountID, tankIDs, fields) + json_data = await getUrlJSON(self.session, url, self.chkJSONtankList) + if json_data != None: + debug('JSON Response received: ' + str(json_data)) + return json_data['data'][str(accountID)] + except Exception as err: + error(err) + return None + async def getPlayerTankStats(self, accountID: int, tankID : int, fields: list) -> dict: """Get player's stats (WR, # of battles) in a tank""" # debug('Started') @@ -681,6 +723,10 @@ class WG: error(str(err)) return None +## ----------------------------------------------------------- +#### Class WoTinspector +## ----------------------------------------------------------- + class WoTinspector: URL_WI = 'https://replays.wotinspector.com' URL_REPLAYS = URL_WI + '/en/sort/ut/page/' diff --git a/wotbreplay_uploader.py b/wotbreplay_uploader.py index cc49bda..dae421e 100644 --- a/wotbreplay_uploader.py +++ b/wotbreplay_uploader.py @@ -1,7 +1,7 @@ #!/usr/bin/python3.7 import json, argparse, inspect, sys, os, base64, aiohttp, urllib, asyncio, aiofiles, aioconsole -import logging, re, concurrent.futures, configparser, motor.motor_asyncio, ssl +import logging, re, concurrent.futures, configparser, motor.motor_asyncio, ssl, pymongo import blitzutils as bu from blitzutils import WG from blitzutils import WoTinspector @@ -38,7 +38,9 @@ async def main(argv): DB_NAME = configDB.get('db_name', 'BlitzStats') DB_USER = configDB.get('db_user', 'mongouser') DB_PASSWD = configDB.get('db_password', "PASSWORD") - + DB_CERT = configDB.get('db_ssl_cert_file', None) + DB_CA = configDB.get('db_ssl_ca_file', None) + bu.debug('DB_SERVER: ' + DB_SERVER) bu.debug('DB_PORT: ' + str(DB_PORT)) bu.debug('DB_SSL: ' + "True" if DB_SSL else "False") @@ -52,7 +54,7 @@ async def main(argv): #### Connect to MongoDB (TBD) try: - client = motor.motor_asyncio.AsyncIOMotorClient(DB_SERVER,DB_PORT, authSource=DB_AUTH, username=DB_USER, password=DB_PASSWD, ssl=DB_SSL, ssl_cert_reqs=DB_CERT_REQ) + client = motor.motor_asyncio.AsyncIOMotorClient(DB_SERVER,DB_PORT, authSource=DB_AUTH, username=DB_USER, password=DB_PASSWD, ssl=DB_SSL, ssl_cert_reqs=DB_CERT_REQ, ssl_certfile=DB_CERT, tlsCAFile=DB_CA) db = client[DB_NAME] except: db = None @@ -229,6 +231,9 @@ async def saveReplay2DB(db: motor.motor_asyncio.AsyncIOMotorDatabase, replay: di replay['_id'] = replay_id await dbc.insert_one(replay) bu.debug('Replay added to database') + except pymongo.errors.DuplicateKeyError as err: + bu.verbose_std('Replay already in the DB: ' + replay['data']['summary']['title'] + ' : _id=' + replay_id) + return False except Exception as err: bu.error('Unexpected Exception: ' + str(type(err)) + ' : ' + str(err)) return False @@ -276,4 +281,4 @@ def getTitle(replayfile: str, title: str, i : int) -> str: ### main() ------------------------------------------- if __name__ == "__main__": - asyncio.run(main(sys.argv[1:]), debug=False) \ No newline at end of file + asyncio.run(main(sys.argv[1:]), debug=False)