mirror of
https://github.com/Jylpah/blitz-tools.git
synced 2026-10-21 10:17:05 +02:00
Class BlitzStars update
- PEB-8 naming - tank_stats2WG() added - get_player_stats() added - get_tank_stats(9 added
This commit is contained in:
1 parent
d8b6f7d354
commit
a189a45dc8
2 files changed
+194
-74
No files matched your search
+187
-67
@@ -42,6 +42,7 @@ def set_log_level_normal():
|
||||
global _log_level
|
||||
_log_level = NORMAL
|
||||
|
||||
|
||||
def set_log_level(silent: bool,verbose: bool, debug: bool):
|
||||
global _log_level
|
||||
_log_level = NORMAL
|
||||
@@ -81,42 +82,45 @@ def verbose_std(msg = "", id = None):
|
||||
return None
|
||||
|
||||
|
||||
def debug(msg = "", n = None):
|
||||
def debug(msg = "", id = None, exception = None):
|
||||
"""print a conditional debug message"""
|
||||
if _log_level >= DEBUG:
|
||||
curframe = inspect.currentframe()
|
||||
calframe = inspect.getouterframes(curframe, 2)
|
||||
caller = calframe[1][3]
|
||||
if n == None:
|
||||
print('DEBUG: ' + caller + '(): ' + msg)
|
||||
else:
|
||||
print('DEBUG: ' + caller + '()' + '[' + str(n) + ']: ' + msg)
|
||||
_print_log_msg('DEBUG', msg, exception, id)
|
||||
return None
|
||||
|
||||
|
||||
def error(msg = "", exception = None, id = None):
|
||||
"""Print an error message"""
|
||||
_print_log_msg('ERROR', msg, exception, id)
|
||||
return None
|
||||
|
||||
|
||||
def _print_log_msg(prefix = 'LOG', msg = '', exception = None, id = None):
|
||||
curframe = inspect.currentframe()
|
||||
calframe = inspect.getouterframes(curframe, 2)
|
||||
caller = calframe[1][3]
|
||||
calframe = inspect.getouterframes(curframe)
|
||||
caller = calframe[2].function
|
||||
|
||||
prefix = prefix + ': ' + caller + '(): '
|
||||
if id != None:
|
||||
prefix = prefix + '[' + str(id) + ']: '
|
||||
|
||||
exception_msg = ''
|
||||
if (exception != None) and isinstance(exception, Exception):
|
||||
exception_msg = ' : Exception: ' + str(type(exception)) + ' : ' + str(exception)
|
||||
|
||||
if id == None:
|
||||
print('ERROR: ' + caller + '(): ' + msg + exception_msg)
|
||||
else:
|
||||
print('ERROR: ' + caller + '()' + '[' + str(id) + ']: ' + msg + exception_msg)
|
||||
print(prefix + msg + exception_msg)
|
||||
return None
|
||||
|
||||
|
||||
def print_progress(force = False):
|
||||
"""Print progress dots"""
|
||||
def print_progress(force = False) -> bool:
|
||||
"""Print progress dots. Returns True if the dot is being printed."""
|
||||
global _progress_N, _progress_i
|
||||
if (_log_level > SILENT) and ( force or (_log_level < DEBUG ) ):
|
||||
_progress_i = (_progress_i + 1) % _progress_N
|
||||
if _progress_i == 0:
|
||||
print('.', end='', flush=True)
|
||||
print('.', end='', flush=True)
|
||||
return True
|
||||
return False
|
||||
|
||||
def set_progress_step(n: int):
|
||||
"""Set the frquency of the progress dots. The bigger 'n', the fewer dots"""
|
||||
@@ -206,10 +210,10 @@ async def get_url_JSON(session: aiohttp.ClientSession, url: str, chk_JSON_func =
|
||||
if (chk_JSON_func == None) or chk_JSON_func(json_resp):
|
||||
# debug("Received valid JSON: " + str(json_resp))
|
||||
return json_resp
|
||||
else:
|
||||
debug('Received JSON error. URL: ' + url)
|
||||
# Sometimes WG API returns JSON error even a retry gives valid JSON
|
||||
# return None
|
||||
# else:
|
||||
# debug('Received JSON error. URL: ' + url)
|
||||
# # Sometimes WG API returns JSON error even a retry gives valid JSON
|
||||
# # return None
|
||||
if retry == max_tries:
|
||||
if json_resp != None:
|
||||
str_json = str(json_resp)
|
||||
@@ -221,7 +225,7 @@ async def get_url_JSON(session: aiohttp.ClientSession, url: str, chk_JSON_func =
|
||||
|
||||
except aiohttp.ClientError as err:
|
||||
error("Could not retrieve URL: " + url)
|
||||
error(exception=err)
|
||||
error(str(err))
|
||||
except asyncio.CancelledError as err:
|
||||
error('Queue gets cancelled while still working.')
|
||||
except Exception as err:
|
||||
@@ -253,7 +257,7 @@ def bld_dict_hierarcy(d : dict, key : str, value) -> dict:
|
||||
#### Class StatsNotFound
|
||||
## -----------------------------------------------------------
|
||||
|
||||
class CachedStatsNotFound(Exception):
|
||||
class StatsNotFound(Exception):
|
||||
pass
|
||||
|
||||
## -----------------------------------------------------------
|
||||
@@ -751,8 +755,8 @@ class WG:
|
||||
return None
|
||||
|
||||
|
||||
async def get_player_tanks_stats(self, account_id: int, tank_ids = [], fields = []) -> dict:
|
||||
"""Get player's stats (WR, # of battles) in a tank"""
|
||||
async def get_player_tank_stats(self, account_id: int, tank_ids = [], fields = [], cache=True) -> dict:
|
||||
"""Get player's stats (WR, # of battles) in a tank or all tanks (empty tank_ids[])"""
|
||||
# debug('Started')
|
||||
|
||||
try:
|
||||
@@ -760,9 +764,10 @@ class WG:
|
||||
stats = None
|
||||
|
||||
# try cached stats first:
|
||||
stats = await self.get_cached_tank_stats(account_id, tank_ids, fields)
|
||||
if stats != None:
|
||||
return stats
|
||||
if cache:
|
||||
stats = await self.get_cached_tank_stats(account_id, tank_ids, fields)
|
||||
if stats != None:
|
||||
return stats
|
||||
|
||||
# Cached stats not found, fetching new ones
|
||||
url = self.get_url_player_tanks_stats(account_id, tank_ids, fields)
|
||||
@@ -770,27 +775,29 @@ class WG:
|
||||
if json_data != None:
|
||||
#debug('JSON Response received: ' + str(json_data))
|
||||
stats = json_data['data'][str(account_id)]
|
||||
await self.save_stats('tank_stats', [account_id, tank_ids], stats)
|
||||
if cache:
|
||||
await self.save_stats('tank_stats', [account_id, tank_ids], stats)
|
||||
return stats
|
||||
except Exception as err:
|
||||
error(exception=err)
|
||||
return None
|
||||
|
||||
|
||||
async def get_player_stats(self, account_id: int, fields = []) -> dict:
|
||||
async def get_player_stats(self, account_id: int, fields = [], cache=True) -> dict:
|
||||
"""Get player's global stats """
|
||||
try:
|
||||
#debug('account_id: ' + str(account_id) )
|
||||
stats = None
|
||||
|
||||
# try cached stats first:
|
||||
stats = await self.get_cached_player_stats(account_id,fields)
|
||||
# stats found unless CachedStatsNotFound exception is raised
|
||||
return stats
|
||||
if cache:
|
||||
stats = await self.get_cached_player_stats(account_id,fields)
|
||||
# stats found unless StatsNotFound exception is raised
|
||||
return stats
|
||||
|
||||
except CachedStatsNotFound as err:
|
||||
except StatsNotFound as err:
|
||||
# No cached stats found, need to retrieve
|
||||
debug(str(err))
|
||||
debug(exception=err)
|
||||
pass
|
||||
|
||||
try:
|
||||
@@ -800,7 +807,8 @@ class WG:
|
||||
if json_data != None:
|
||||
#debug('JSON Response received: ' + str(json_data))
|
||||
stats = json_data['data'][str(account_id)]
|
||||
await self.save_stats('player_stats', [account_id], stats)
|
||||
if cache:
|
||||
await self.save_stats('player_stats', [account_id], stats)
|
||||
return stats
|
||||
except Exception as err:
|
||||
error(exception=err)
|
||||
@@ -971,7 +979,7 @@ class WG:
|
||||
debug('Trying cached stats first')
|
||||
if self.cache == None:
|
||||
#debug('No cache DB')
|
||||
raise CachedStatsNotFound('No cache DB in use')
|
||||
raise StatsNotFound('No cache DB in use')
|
||||
|
||||
async with self.cache.execute(WG.SQL_PLAYER_STATS_CACHED, (account_id, NOW() - WG.CACHE_GRACE_TIME) ) as cursor:
|
||||
row = await cursor.fetchone()
|
||||
@@ -979,7 +987,7 @@ class WG:
|
||||
if row == None:
|
||||
# no cached stats found, marked with an empty array
|
||||
#debug('No cached stats found')
|
||||
raise CachedStatsNotFound('No cached stats found')
|
||||
raise StatsNotFound('No cached stats found')
|
||||
|
||||
debug('Cached stats found')
|
||||
if row[3] == None:
|
||||
@@ -989,8 +997,8 @@ class WG:
|
||||
else:
|
||||
# Return proper stats
|
||||
return json.loads(row[3])
|
||||
except CachedStatsNotFound as err:
|
||||
debug(str(err))
|
||||
except StatsNotFound as err:
|
||||
debug(exception=err)
|
||||
raise
|
||||
except Exception as err:
|
||||
error('Error trying to look for cached stats', err)
|
||||
@@ -1167,51 +1175,163 @@ class WoTinspector:
|
||||
|
||||
class BlitzStars:
|
||||
|
||||
URL_BlitzStars = 'https://www.blitzstars.com'
|
||||
URL_playerStats = URL_BlitzStars + '/api/playerstats'
|
||||
URL_playerTankStats = URL_BlitzStars + '/api/tanks'
|
||||
URL_playersTankStats= URL_BlitzStars + '/api/top/forjylpah?'
|
||||
URL_tankAverages = URL_BlitzStars + '/tankaverages.json'
|
||||
URL_activeplayers = URL_BlitzStars + '/api/playerstats/activeinlast30days'
|
||||
URL_BLITZSTARS = 'https://www.blitzstars.com'
|
||||
URL_PLAYER_STATS = URL_BLITZSTARS + '/api/playerstats'
|
||||
URL_PLAYER_TANK_STATS = URL_BLITZSTARS + '/api/tanks'
|
||||
URL_TANK_AVERAGES = URL_BLITZSTARS + '/tankaverages.json'
|
||||
URL_ACTIVE_PLAYERS = URL_BLITZSTARS + '/api/playerstats/activeinlast30days'
|
||||
|
||||
|
||||
def __init__(self):
|
||||
self.session = aiohttp.ClientSession()
|
||||
|
||||
|
||||
async def close(self):
|
||||
if self.session != None:
|
||||
await self.session.close()
|
||||
|
||||
|
||||
@classmethod
|
||||
def getUrlTankAvgs(cls):
|
||||
return cls.URL_tankAverages
|
||||
def get_url_tank_averages(cls):
|
||||
return cls.URL_TANK_AVERAGES
|
||||
|
||||
|
||||
@classmethod
|
||||
def get_url_player_stats(cls, account_id: int):
|
||||
return cls.URL_playerStats + '/' + str(account_id)
|
||||
return cls.URL_PLAYER_STATS + '/' + str(account_id)
|
||||
|
||||
|
||||
@classmethod
|
||||
def getUrlPlayerTankStats(cls, account_id: int, tank_id: int):
|
||||
return cls.URL_playerTankStats + '/' + str(account_id) + '/' + str(tank_id)
|
||||
def get_url_player_tank_stats(cls, account_id: int, tank_id: int):
|
||||
return cls.URL_PLAYER_TANK_STATS + '/' + str(account_id) + '/' + str(tank_id)
|
||||
|
||||
|
||||
@classmethod
|
||||
def getUrlPlayersTankStats(cls, account_id: int):
|
||||
return cls.URL_playersTankStats + '&accountId=' + str(account_id)
|
||||
def get_url_player_tanks_stats(cls, account_id: int):
|
||||
return cls.URL_PLAYER_TANK_STATS + '/' + str(account_id)
|
||||
|
||||
|
||||
@classmethod
|
||||
def getUrlActivePlayers(cls):
|
||||
return cls.URL_activeplayers
|
||||
|
||||
def get_url_active_players(cls):
|
||||
return cls.URL_ACTIVE_PLAYERS
|
||||
|
||||
|
||||
@classmethod
|
||||
def chkJSONtankStats(cls, json_resp):
|
||||
""""Check String for being a valid JSON file"""
|
||||
def chk_JSON_tank_stats(cls, json_resp):
|
||||
"""Check BlitzStars player tank stats"""
|
||||
try:
|
||||
# print(str(json_resp['data']))
|
||||
if ('data' in json_resp):
|
||||
debug("JSON check OK")
|
||||
return True
|
||||
except KeyError as err:
|
||||
error('Key not found', err)
|
||||
except:
|
||||
debug("JSON check failed")
|
||||
return False
|
||||
if (len(json_resp) > 0) and ('tank_id' in json_resp[0]):
|
||||
debug('JSON check OK')
|
||||
return True
|
||||
except Exception as err:
|
||||
error('JSON check FAILED: ' + str(json_resp) )
|
||||
error(exception=err)
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
def chk_JSON_player_stats(cls, json_resp : list):
|
||||
"""Check BlitzStars player stats"""
|
||||
try:
|
||||
if (len(json_resp) > 0) and ('account_id' in json_resp[0]):
|
||||
debug('JSON check OK')
|
||||
return True
|
||||
except Exception as err:
|
||||
error('JSON check FAILED: ' + str(json_resp) )
|
||||
error(exception=err)
|
||||
return False
|
||||
|
||||
|
||||
@classmethod
|
||||
async def tank_stats2WG(cls, BS_tank_stats: list) -> list:
|
||||
"""Convert BlitzStars player tank stats to WG API format"""
|
||||
try:
|
||||
if BS_tank_stats == None:
|
||||
return None
|
||||
WG_tank_stats = []
|
||||
for stat in BS_tank_stats:
|
||||
try:
|
||||
tmp = {}
|
||||
for field in ['all', 'last_battle_time', 'tank_id', 'battle_life_time', 'account_id']:
|
||||
tmp[field] = stat[field]
|
||||
WG_tank_stats.append(tmp)
|
||||
except KeyError as err:
|
||||
error(exception=err)
|
||||
if len(WG_tank_stats) > 0:
|
||||
return WG_tank_stats
|
||||
|
||||
except Exception as err:
|
||||
error(exception=err)
|
||||
pass
|
||||
return None
|
||||
|
||||
|
||||
async def get_player_stats(self, account_id: int, cache=True):
|
||||
"""Get player stats from BlitzStars"""
|
||||
try:
|
||||
#debug('account_id: ' + str(account_id) )
|
||||
stats = None
|
||||
|
||||
if cache:
|
||||
error('CACHE NOT IMPLEMENTED YET FOR BlitzStars()')
|
||||
sys.exit(1)
|
||||
#stats = await self.get_cached_player_stats(account_id,fields)
|
||||
# stats found unless StatsNotFound exception is raised
|
||||
return stats
|
||||
|
||||
except StatsNotFound as err:
|
||||
# No cached stats found, need to retrieve
|
||||
debug(exception=err)
|
||||
pass
|
||||
|
||||
try:
|
||||
# Cached stats not found, fetching new ones
|
||||
url = self.get_url_player_stats(account_id)
|
||||
stats = await get_url_JSON(self.session, url, self.chk_JSON_player_stats)
|
||||
if stats != None:
|
||||
#debug('JSON Response received: ' + str(json_data))
|
||||
if cache:
|
||||
error('CACHE NOT IMPLEMENTED YET FOR BlitzStars()')
|
||||
sys.exit(1)
|
||||
# await self.save_stats('player_stats', [account_id], stats)
|
||||
return stats
|
||||
except Exception as err:
|
||||
error(exception=err)
|
||||
return None
|
||||
|
||||
async def get_player_tank_stats(self, account_id: int, tank_id = None, cache=True):
|
||||
"""Get player stats for all his tanks from BlitzStars"""
|
||||
try:
|
||||
#debug('account_id: ' + str(account_id) )
|
||||
stats = None
|
||||
|
||||
if cache:
|
||||
error('CACHE NOT IMPLEMENTED YET FOR BlitzStars()')
|
||||
sys.exit(1)
|
||||
#stats = await self.get_cached_player_stats(account_id,fields)
|
||||
# stats found unless StatsNotFound exception is raised
|
||||
return stats
|
||||
|
||||
except StatsNotFound as err:
|
||||
# No cached stats found, need to retrieve
|
||||
debug(exception=err)
|
||||
pass
|
||||
|
||||
try:
|
||||
# Cached stats not found, fetching new ones
|
||||
if tank_id == None:
|
||||
# get stats for all the player's tanks
|
||||
url = self.get_url_player_tanks_stats(account_id)
|
||||
else:
|
||||
url = self.get_url_player_tank_stats(account_id, tank_id)
|
||||
stats = await get_url_JSON(self.session, url, self.chk_JSON_tank_stats)
|
||||
if stats != None:
|
||||
#debug('JSON Response received: ' + str(json_data))
|
||||
if cache:
|
||||
error('CACHE NOT IMPLEMENTED YET FOR BlitzStars()')
|
||||
sys.exit(1)
|
||||
# await self.save_stats('player_stats', [account_id], stats)
|
||||
return stats
|
||||
except Exception as err:
|
||||
error(exception=err)
|
||||
return None
|
||||
|
||||
Reference in new issue
Block a user