mirror of
https://github.com/Jylpah/blitz-tools.git
synced 2026-10-21 02:07:06 +02:00
Merge pull request #38 from Jylpah/dev-fix-tankopedia
FIX: JSON search, REAFACTOR: blitzutils.Maps
This commit is contained in:
3 files changed
+452
-194
No files matched your search
+49
-63
@@ -5,11 +5,16 @@
|
|||||||
|
|
||||||
import sys, argparse, json, os, concurrent, inspect, aiohttp, asyncio, aiofiles, aioconsole
|
import sys, argparse, json, os, concurrent, inspect, aiohttp, asyncio, aiofiles, aioconsole
|
||||||
import configparser, ssl, re, logging, time, xmltodict, collections, csv
|
import configparser, ssl, re, logging, time, xmltodict, collections, csv
|
||||||
|
from asyncio import Queue, Task, create_task
|
||||||
from datetime import datetime, timedelta, date
|
from datetime import datetime, timedelta, date
|
||||||
from motor.motor_asyncio import AsyncIOMotorDatabase, AsyncIOMotorClient
|
from motor.motor_asyncio import (
|
||||||
|
AsyncIOMotorDatabase,
|
||||||
|
AsyncIOMotorClient,
|
||||||
|
)
|
||||||
import blitzutils1 as bu
|
import blitzutils1 as bu
|
||||||
from blitzutils1 import WG
|
from blitzutils1 import WG
|
||||||
from blitzutils1 import WoTinspector
|
from blitzutils1 import WoTinspector
|
||||||
|
from pyutils import FileQueue
|
||||||
|
|
||||||
logging.getLogger("asyncio").setLevel(logging.DEBUG)
|
logging.getLogger("asyncio").setLevel(logging.DEBUG)
|
||||||
|
|
||||||
@@ -2006,7 +2011,7 @@ async def main(argv):
|
|||||||
|
|
||||||
# try:
|
# try:
|
||||||
BattleCategory.set_fields(args.mode)
|
BattleCategory.set_fields(args.mode)
|
||||||
replayQ = asyncio.Queue(maxsize=1000)
|
replayQ = Queue(maxsize=1000)
|
||||||
reader_tasks = []
|
reader_tasks = []
|
||||||
# Make replay Queue
|
# Make replay Queue
|
||||||
|
|
||||||
@@ -2072,8 +2077,8 @@ async def main(argv):
|
|||||||
if args.csv:
|
if args.csv:
|
||||||
await export_csv(args, blt_cat_list, histograms)
|
await export_csv(args, blt_cat_list, histograms)
|
||||||
|
|
||||||
if args.replays:
|
# if args.replays:
|
||||||
await export_replays(replays)
|
# await export_replays(replays)
|
||||||
|
|
||||||
bu.debug("Finished. Cleaning up..................")
|
bu.debug("Finished. Cleaning up..................")
|
||||||
# except Exception as err:
|
# except Exception as err:
|
||||||
@@ -2146,8 +2151,8 @@ async def export_json(
|
|||||||
|
|
||||||
|
|
||||||
async def help_extended(
|
async def help_extended(
|
||||||
db: AsyncIOMotorDatabase = None,
|
db: AsyncIOMotorDatabase | None = None,
|
||||||
parser: argparse.ArgumentParser = None,
|
parser: argparse.ArgumentParser | None = None,
|
||||||
):
|
):
|
||||||
"""Help for --filters"""
|
"""Help for --filters"""
|
||||||
if parser is not None:
|
if parser is not None:
|
||||||
@@ -2208,26 +2213,26 @@ async def help_extended(
|
|||||||
bu.error(exception=err)
|
bu.error(exception=err)
|
||||||
|
|
||||||
|
|
||||||
async def export_replays(replays: dict):
|
# async def export_replays(replays: dict):
|
||||||
"""Export replays"""
|
# """Export replays"""
|
||||||
global wg
|
# global wg
|
||||||
try:
|
# try:
|
||||||
replay_dir = OPT_EXPORT_REPLAY_DIR + "_" + bu.get_date_str()
|
# replay_dir = OPT_EXPORT_REPLAY_DIR + "_" + bu.get_date_str()
|
||||||
bu.verbose_std("Exporting replays to " + replay_dir)
|
# bu.verbose_std("Exporting replays to " + replay_dir)
|
||||||
if not os.path.isdir(replay_dir):
|
# if not os.path.isdir(replay_dir):
|
||||||
os.mkdir(replay_dir)
|
# os.mkdir(replay_dir)
|
||||||
|
|
||||||
i = 0
|
# i = 0
|
||||||
for replay in replays.values():
|
# for replay in replays.values():
|
||||||
filename = wg.get_replay_filename(replay)
|
# filename = wg.get_replay_filename(replay)
|
||||||
async with aiofiles.open(
|
# async with aiofiles.open(
|
||||||
os.path.join(replay_dir, filename), "w", encoding="utf8"
|
# os.path.join(replay_dir, filename), "w", encoding="utf8"
|
||||||
) as f:
|
# ) as f:
|
||||||
await f.write(json.dumps(replay, indent=4))
|
# await f.write(json.dumps(replay, indent=4))
|
||||||
i += 1
|
# i += 1
|
||||||
bu.verbose_std(str(i) + " replays exported")
|
# bu.verbose_std(str(i) + " replays exported")
|
||||||
except Exception as err:
|
# except Exception as err:
|
||||||
bu.error(exception=err)
|
# bu.error(exception=err)
|
||||||
|
|
||||||
|
|
||||||
## move the class PlayerHistogram?
|
## move the class PlayerHistogram?
|
||||||
@@ -2426,7 +2431,7 @@ async def process_player_stats(
|
|||||||
"""Start stat_workers to retrieve and store players' stats"""
|
"""Start stat_workers to retrieve and store players' stats"""
|
||||||
## Create queue of player-tank pairs to find stats for
|
## Create queue of player-tank pairs to find stats for
|
||||||
try:
|
try:
|
||||||
statsQ = asyncio.Queue()
|
statsQ = Queue()
|
||||||
bu.debug("Create player stats queue: " + str(len(players)) + " players")
|
bu.debug("Create player stats queue: " + str(len(players)) + " players")
|
||||||
stat_id_map = dict()
|
stat_id_map = dict()
|
||||||
stat_ids = set()
|
stat_ids = set()
|
||||||
@@ -2569,7 +2574,7 @@ def calc_team_stats(
|
|||||||
|
|
||||||
|
|
||||||
async def stat_worker(
|
async def stat_worker(
|
||||||
queue: asyncio.Queue,
|
queue: Queue,
|
||||||
workerID: int,
|
workerID: int,
|
||||||
args: argparse.Namespace,
|
args: argparse.Namespace,
|
||||||
db: AsyncIOMotorDatabase,
|
db: AsyncIOMotorDatabase,
|
||||||
@@ -2968,14 +2973,15 @@ async def player_stats_helper(player_stats: dict):
|
|||||||
|
|
||||||
|
|
||||||
async def mk_replayQ(
|
async def mk_replayQ(
|
||||||
queue: asyncio.Queue,
|
replayQ: Queue,
|
||||||
args: argparse.Namespace,
|
args: argparse.Namespace,
|
||||||
db: AsyncIOMotorDatabase = None,
|
db: AsyncIOMotorDatabase | None = None,
|
||||||
):
|
):
|
||||||
"""Create queue of replays to post"""
|
"""Create queue of replays to post"""
|
||||||
p_replayfile = re.compile(".*\\.wotbreplay\\.json$")
|
p_replayfile = re.compile(".*\\.wotbreplay\\.json$")
|
||||||
files = args.files
|
files: list[str] = args.files
|
||||||
Nreplays = 0
|
Nreplays = 0
|
||||||
|
|
||||||
if files[0] == "db:":
|
if files[0] == "db:":
|
||||||
if db is None:
|
if db is None:
|
||||||
bu.error("No database connection opened")
|
bu.error("No database connection opened")
|
||||||
@@ -2995,7 +3001,7 @@ async def mk_replayQ(
|
|||||||
async for replay_json in cursor:
|
async for replay_json in cursor:
|
||||||
_id = replay_json["_id"]
|
_id = replay_json["_id"]
|
||||||
# del(replay_json['_id'])
|
# del(replay_json['_id'])
|
||||||
await queue.put(await mk_readerQ_item(replay_json, _id=_id))
|
await replayQ.put(await mk_readerQ_item(replay_json, _id=_id))
|
||||||
Nreplays += 1
|
Nreplays += 1
|
||||||
bu.debug("All the matching replays have been read from the DB")
|
bu.debug("All the matching replays have been read from the DB")
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
@@ -3004,53 +3010,33 @@ async def mk_replayQ(
|
|||||||
elif files[0] == "-":
|
elif files[0] == "-":
|
||||||
bu.debug("reading replay file list from STDIN")
|
bu.debug("reading replay file list from STDIN")
|
||||||
stdin, _ = await aioconsole.get_standard_streams()
|
stdin, _ = await aioconsole.get_standard_streams()
|
||||||
while True:
|
while (line := (await stdin.readline()).decode("utf-8").rstrip()) is not None:
|
||||||
try:
|
try:
|
||||||
line = (await stdin.readline()).decode("utf-8").rstrip()
|
|
||||||
if not line:
|
|
||||||
break
|
|
||||||
|
|
||||||
if p_replayfile.match(line) is not None:
|
if p_replayfile.match(line) is not None:
|
||||||
replay_json = await bu.open_JSON(line, wi.chk_JSON_replay)
|
replay_json = await bu.open_JSON(line, wi.chk_JSON_replay)
|
||||||
await queue.put(await mk_readerQ_item(replay_json, filename=line))
|
await replayQ.put(await mk_readerQ_item(replay_json, filename=line))
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
bu.error(exception=err)
|
bu.error(exception=err)
|
||||||
else:
|
else:
|
||||||
for fn in files:
|
jsonQ = FileQueue(maxsize=500, filter="*.wotbreplay.json")
|
||||||
|
scanner: Task = create_task(jsonQ.mk_queue(files=files))
|
||||||
|
async for fn in jsonQ:
|
||||||
try:
|
try:
|
||||||
# bu.debug('Filename: ' + fn)
|
|
||||||
if fn.endswith('"'):
|
|
||||||
fn = fn[:-1]
|
|
||||||
if os.path.isfile(fn) and (p_replayfile.match(fn) is not None):
|
|
||||||
replay_json = await bu.open_JSON(fn, wi.chk_JSON_replay)
|
replay_json = await bu.open_JSON(fn, wi.chk_JSON_replay)
|
||||||
await queue.put(await mk_readerQ_item(replay_json, filename=fn))
|
await replayQ.put(await mk_readerQ_item(replay_json, filename=fn))
|
||||||
bu.debug("File added to queue: " + fn)
|
bu.debug("File added to queue: " + fn)
|
||||||
Nreplays += 1
|
Nreplays += 1
|
||||||
elif os.path.isdir(fn):
|
|
||||||
with os.scandir(fn) as dirEntry:
|
|
||||||
for entry in dirEntry:
|
|
||||||
if entry.is_file() and (
|
|
||||||
p_replayfile.match(entry.name) is not None
|
|
||||||
):
|
|
||||||
bu.debug(entry.name)
|
|
||||||
replay_json = await bu.open_JSON(
|
|
||||||
entry.path, wi.chk_JSON_replay
|
|
||||||
)
|
|
||||||
await queue.put(
|
|
||||||
await mk_readerQ_item(
|
|
||||||
replay_json, filename=entry.name
|
|
||||||
)
|
|
||||||
)
|
|
||||||
bu.debug("File added to queue: " + entry.path)
|
|
||||||
Nreplays += 1
|
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
bu.error(exception=err)
|
bu.error(exception=err)
|
||||||
|
await asyncio.wait([scanner])
|
||||||
return Nreplays
|
return Nreplays
|
||||||
|
|
||||||
|
|
||||||
async def mk_readerQ_item(replay_json, filename: str = None, _id: str = None) -> list:
|
async def mk_readerQ_item(
|
||||||
|
replay_json, filename: str | None = None, _id: str | None = None
|
||||||
|
) -> list | None:
|
||||||
"""Make an item to replay queue"""
|
"""Make an item to replay queue"""
|
||||||
global REPLAY_N
|
global REPLAY_N, wi
|
||||||
REPLAY_N += 1
|
REPLAY_N += 1
|
||||||
try:
|
try:
|
||||||
if wi.chk_JSON_replay(replay_json):
|
if wi.chk_JSON_replay(replay_json):
|
||||||
@@ -3071,7 +3057,7 @@ async def mk_readerQ_item(replay_json, filename: str = None, _id: str = None) ->
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
async def replay_reader(queue: asyncio.Queue, readerID: int, args: argparse.Namespace):
|
async def replay_reader(queue: Queue, readerID: int, args: argparse.Namespace):
|
||||||
"""Async Worker to process the replay queue"""
|
"""Async Worker to process the replay queue"""
|
||||||
# global SKIPPED_N
|
# global SKIPPED_N
|
||||||
global wi
|
global wi
|
||||||
|
|||||||
+402
-71
@@ -10,7 +10,8 @@ from progress.counter import Counter
|
|||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from blitzutils.wg_api import WGApiTankopedia, WGTank
|
from pydantic import ValidationError
|
||||||
|
from blitzutils import WGApiTankopedia, WGTank, Maps, Map
|
||||||
|
|
||||||
MAX_RETRIES = 3
|
MAX_RETRIES = 3
|
||||||
SLEEP = 1.5
|
SLEEP = 1.5
|
||||||
@@ -886,38 +887,357 @@ class WG:
|
|||||||
|
|
||||||
# Default data. Please use the latest maps.json
|
# Default data. Please use the latest maps.json
|
||||||
|
|
||||||
maps = {
|
MAPS_JSON: str = """
|
||||||
"Random": "Random map",
|
{
|
||||||
"amigosville": "Falls Creek",
|
"Random": {
|
||||||
"asia": "Lost Temple",
|
"key": "Random",
|
||||||
"canal": "Canal",
|
"name": "Random map",
|
||||||
"canyon": "Canyon",
|
"id": -1,
|
||||||
"desert_train": "Desert Sands",
|
"mode": 1
|
||||||
"erlenberg": "Middleburg",
|
},
|
||||||
"faust": "Faust",
|
"amigosville": {
|
||||||
"fort": "Macragge",
|
"key": "amigosville",
|
||||||
"grossberg": "Dynasty's Pearl",
|
"name": "Falls Creek",
|
||||||
"himmelsdorf": "Himmelsdorf",
|
"id": -1,
|
||||||
"italy": "Vineyards",
|
"mode": 1
|
||||||
"karelia": "Rockfield",
|
},
|
||||||
"karieri": "Copperfield",
|
"amigosville_02": {
|
||||||
"lake": "Mirage",
|
"key": "amigosville_02",
|
||||||
"lumber": "Alpenstadt",
|
"name": "Falls Creek - Bridge",
|
||||||
"malinovka": "Winter Malinovka",
|
"id": -1,
|
||||||
"medvedkovo": "Dead Rail",
|
"mode": 3
|
||||||
"milbase": "Yamato Harbor",
|
},
|
||||||
"mountain": "Black Goldville",
|
"amigosville_03": {
|
||||||
"north": "North",
|
"key": "amigosville_03",
|
||||||
"ordeal": "Trial by Fire",
|
"name": "Falls Creek - Factory",
|
||||||
"pliego": "Castilla",
|
"id": -1,
|
||||||
"port": "Port Bay",
|
"mode": 3
|
||||||
"rock": "Mayan Ruins",
|
},
|
||||||
"rudniki": "Mines",
|
"asia": {
|
||||||
"savanna": "Oasis Palms",
|
"key": "asia",
|
||||||
"skit": "Naval Frontier",
|
"name": "Lost Temple",
|
||||||
"test": "World of Ducks",
|
"id": -1,
|
||||||
"tutorial": "Proving Grounds",
|
"mode": 1
|
||||||
|
},
|
||||||
|
"canal": {
|
||||||
|
"key": "canal",
|
||||||
|
"name": "Canal",
|
||||||
|
"id": -1,
|
||||||
|
"mode": 1
|
||||||
|
},
|
||||||
|
"canal_01": {
|
||||||
|
"key": "canal_01",
|
||||||
|
"name": "Canal - Factory",
|
||||||
|
"id": -1,
|
||||||
|
"mode": 3
|
||||||
|
},
|
||||||
|
"canyon": {
|
||||||
|
"key": "canyon",
|
||||||
|
"name": "Canyon",
|
||||||
|
"id": -1,
|
||||||
|
"mode": 1
|
||||||
|
},
|
||||||
|
"desert_train": {
|
||||||
|
"key": "desert_train",
|
||||||
|
"name": "Desert Sands",
|
||||||
|
"id": -1,
|
||||||
|
"mode": 1
|
||||||
|
},
|
||||||
|
"desert_train_02": {
|
||||||
|
"key": "desert_train_02",
|
||||||
|
"name": "Desert Sands - Town",
|
||||||
|
"id": -1,
|
||||||
|
"mode": 3
|
||||||
|
},
|
||||||
|
"desert_train_03": {
|
||||||
|
"key": "desert_train_03",
|
||||||
|
"name": "Desert Sands - Dunes",
|
||||||
|
"id": -1,
|
||||||
|
"mode": 3
|
||||||
|
},
|
||||||
|
"erlenberg": {
|
||||||
|
"key": "erlenberg",
|
||||||
|
"name": "Middleburg",
|
||||||
|
"id": -1,
|
||||||
|
"mode": 1
|
||||||
|
},
|
||||||
|
"erlenberg_01": {
|
||||||
|
"key": "erlenberg_01",
|
||||||
|
"name": "Middleburg - Town",
|
||||||
|
"id": -1,
|
||||||
|
"mode": 3
|
||||||
|
},
|
||||||
|
"erlenberg_02": {
|
||||||
|
"key": "erlenberg_02",
|
||||||
|
"name": "Middleburg - Hill",
|
||||||
|
"id": -1,
|
||||||
|
"mode": 3
|
||||||
|
},
|
||||||
|
"faust": {
|
||||||
|
"key": "faust",
|
||||||
|
"name": "Faust",
|
||||||
|
"id": -1,
|
||||||
|
"mode": 1
|
||||||
|
},
|
||||||
|
"forgecity": {
|
||||||
|
"key": "forgecity",
|
||||||
|
"name": "New Bay",
|
||||||
|
"id": -1,
|
||||||
|
"mode": 1
|
||||||
|
},
|
||||||
|
"fort": {
|
||||||
|
"key": "fort",
|
||||||
|
"name": "Fort Despair",
|
||||||
|
"id": -1,
|
||||||
|
"mode": 1
|
||||||
|
},
|
||||||
|
"grossberg": {
|
||||||
|
"key": "grossberg",
|
||||||
|
"name": "Dynasty's Pearl",
|
||||||
|
"id": -1,
|
||||||
|
"mode": 1
|
||||||
|
},
|
||||||
|
"himmelsdorf": {
|
||||||
|
"key": "himmelsdorf",
|
||||||
|
"name": "Himmelsdorf",
|
||||||
|
"id": -1,
|
||||||
|
"mode": 1
|
||||||
|
},
|
||||||
|
"holland": {
|
||||||
|
"key": "holland",
|
||||||
|
"name": "Molendijk",
|
||||||
|
"id": -1,
|
||||||
|
"mode": 1
|
||||||
|
},
|
||||||
|
"holmeisk": {
|
||||||
|
"key": "holmeisk",
|
||||||
|
"name": "Wasteland",
|
||||||
|
"id": -1,
|
||||||
|
"mode": 1
|
||||||
|
},
|
||||||
|
"iceworld": {
|
||||||
|
"key": "iceworld",
|
||||||
|
"name": "Everfrost",
|
||||||
|
"id": -1,
|
||||||
|
"mode": 2
|
||||||
|
},
|
||||||
|
"idle": {
|
||||||
|
"key": "idle",
|
||||||
|
"name": "Yukon",
|
||||||
|
"id": -1,
|
||||||
|
"mode": 1
|
||||||
|
},
|
||||||
|
"italy": {
|
||||||
|
"key": "italy",
|
||||||
|
"name": "Vineyards",
|
||||||
|
"id": -1,
|
||||||
|
"mode": 1
|
||||||
|
},
|
||||||
|
"karelia": {
|
||||||
|
"key": "karelia",
|
||||||
|
"name": "Rockfield",
|
||||||
|
"id": -1,
|
||||||
|
"mode": 1
|
||||||
|
},
|
||||||
|
"karieri": {
|
||||||
|
"key": "karieri",
|
||||||
|
"name": "Copperfield",
|
||||||
|
"id": -1,
|
||||||
|
"mode": 1
|
||||||
|
},
|
||||||
|
"lake": {
|
||||||
|
"key": "lake",
|
||||||
|
"name": "Mirage",
|
||||||
|
"id": -1,
|
||||||
|
"mode": 1
|
||||||
|
},
|
||||||
|
"lumber": {
|
||||||
|
"key": "lumber",
|
||||||
|
"name": "Horrorstadt",
|
||||||
|
"id": -1,
|
||||||
|
"mode": 1
|
||||||
|
},
|
||||||
|
"lumber_01": {
|
||||||
|
"key": "lumber_01",
|
||||||
|
"name": "Alpenstadt - Town",
|
||||||
|
"id": -1,
|
||||||
|
"mode": 3
|
||||||
|
},
|
||||||
|
"malinovka": {
|
||||||
|
"key": "malinovka",
|
||||||
|
"name": "Winter Malinovka",
|
||||||
|
"id": -1,
|
||||||
|
"mode": 1
|
||||||
|
},
|
||||||
|
"medvedkovo": {
|
||||||
|
"key": "medvedkovo",
|
||||||
|
"name": "Dead Rail",
|
||||||
|
"id": -1,
|
||||||
|
"mode": 1
|
||||||
|
},
|
||||||
|
"medvedkovo_02": {
|
||||||
|
"key": "medvedkovo_02",
|
||||||
|
"name": "Dead Rail - Valley",
|
||||||
|
"id": -1,
|
||||||
|
"mode": 3
|
||||||
|
},
|
||||||
|
"medvedkovo_03": {
|
||||||
|
"key": "medvedkovo_03",
|
||||||
|
"name": "Dead Rail - Railroad",
|
||||||
|
"id": -1,
|
||||||
|
"mode": 3
|
||||||
|
},
|
||||||
|
"milbase": {
|
||||||
|
"key": "milbase",
|
||||||
|
"name": "Yamato Harbor",
|
||||||
|
"id": -1,
|
||||||
|
"mode": 1
|
||||||
|
},
|
||||||
|
"milbase_02": {
|
||||||
|
"key": "milbase_02",
|
||||||
|
"name": "Yamato Harbor - Battleship",
|
||||||
|
"id": -1,
|
||||||
|
"mode": 3
|
||||||
|
},
|
||||||
|
"milbase_03": {
|
||||||
|
"key": "milbase_03",
|
||||||
|
"name": "Yamato Harbor - Hills",
|
||||||
|
"id": -1,
|
||||||
|
"mode": 3
|
||||||
|
},
|
||||||
|
"milbase_04": {
|
||||||
|
"key": "milbase_04",
|
||||||
|
"name": "Yamato Harbor - Center",
|
||||||
|
"id": -1,
|
||||||
|
"mode": 3
|
||||||
|
},
|
||||||
|
"milbase_05": {
|
||||||
|
"key": "milbase_05",
|
||||||
|
"name": "Yamato Harbor - Dock",
|
||||||
|
"id": -1,
|
||||||
|
"mode": 3
|
||||||
|
},
|
||||||
|
"moon": {
|
||||||
|
"key": "moon",
|
||||||
|
"name": "Sea of Tranquility",
|
||||||
|
"id": -1,
|
||||||
|
"mode": 2
|
||||||
|
},
|
||||||
|
"mountain": {
|
||||||
|
"key": "mountain",
|
||||||
|
"name": "Black Goldville",
|
||||||
|
"id": -1,
|
||||||
|
"mode": 1
|
||||||
|
},
|
||||||
|
"neptune": {
|
||||||
|
"key": "neptune",
|
||||||
|
"name": "Normandy",
|
||||||
|
"id": -1,
|
||||||
|
"mode": 1
|
||||||
|
},
|
||||||
|
"neptune_01": {
|
||||||
|
"key": "neptune_01",
|
||||||
|
"name": "Normandy - Hills",
|
||||||
|
"id": -1,
|
||||||
|
"mode": 3
|
||||||
|
},
|
||||||
|
"neptune_02": {
|
||||||
|
"key": "neptune_02",
|
||||||
|
"name": "Normandy - Beach",
|
||||||
|
"id": -1,
|
||||||
|
"mode": 3
|
||||||
|
},
|
||||||
|
"north": {
|
||||||
|
"key": "north",
|
||||||
|
"name": "North",
|
||||||
|
"id": -1,
|
||||||
|
"mode": 1
|
||||||
|
},
|
||||||
|
"ordeal": {
|
||||||
|
"key": "ordeal",
|
||||||
|
"name": "Trial by Fire",
|
||||||
|
"id": -1,
|
||||||
|
"mode": 1
|
||||||
|
},
|
||||||
|
"plant": {
|
||||||
|
"key": "plant",
|
||||||
|
"name": "Ghost Factory",
|
||||||
|
"id": -1,
|
||||||
|
"mode": 1
|
||||||
|
},
|
||||||
|
"pliego": {
|
||||||
|
"key": "pliego",
|
||||||
|
"name": "Castilla",
|
||||||
|
"id": -1,
|
||||||
|
"mode": 1
|
||||||
|
},
|
||||||
|
"port": {
|
||||||
|
"key": "port",
|
||||||
|
"name": "Port Bay",
|
||||||
|
"id": -1,
|
||||||
|
"mode": 1
|
||||||
|
},
|
||||||
|
"rift": {
|
||||||
|
"key": "rift",
|
||||||
|
"name": "Hellas",
|
||||||
|
"id": -1,
|
||||||
|
"mode": 1
|
||||||
|
},
|
||||||
|
"rock": {
|
||||||
|
"key": "rock",
|
||||||
|
"name": "Mayan Ruins",
|
||||||
|
"id": -1,
|
||||||
|
"mode": 1
|
||||||
|
},
|
||||||
|
"rudniki": {
|
||||||
|
"key": "rudniki",
|
||||||
|
"name": "Mines",
|
||||||
|
"id": -1,
|
||||||
|
"mode": 1
|
||||||
|
},
|
||||||
|
"rudniki_01": {
|
||||||
|
"key": "rudniki_01",
|
||||||
|
"name": "Mines - Hill",
|
||||||
|
"id": -1,
|
||||||
|
"mode": 3
|
||||||
|
},
|
||||||
|
"rudniki_02": {
|
||||||
|
"key": "rudniki_02",
|
||||||
|
"name": "Mines - Village",
|
||||||
|
"id": -1,
|
||||||
|
"mode": 3
|
||||||
|
},
|
||||||
|
"rudniki_03": {
|
||||||
|
"key": "rudniki_03",
|
||||||
|
"name": "Mines - Center",
|
||||||
|
"id": -1,
|
||||||
|
"mode": 3
|
||||||
|
},
|
||||||
|
"savanna": {
|
||||||
|
"key": "savanna",
|
||||||
|
"name": "Oasis Palms",
|
||||||
|
"id": -1,
|
||||||
|
"mode": 1
|
||||||
|
},
|
||||||
|
"skit": {
|
||||||
|
"key": "skit",
|
||||||
|
"name": "Naval Frontier",
|
||||||
|
"id": -1,
|
||||||
|
"mode": 1
|
||||||
|
},
|
||||||
|
"test": {
|
||||||
|
"key": "test",
|
||||||
|
"name": "World of Ducks",
|
||||||
|
"id": -1,
|
||||||
|
"mode": 2
|
||||||
|
},
|
||||||
|
"tutorial": {
|
||||||
|
"key": "tutorial",
|
||||||
|
"name": "Proving Grounds",
|
||||||
|
"id": -1,
|
||||||
|
"mode": 0
|
||||||
}
|
}
|
||||||
|
}"""
|
||||||
|
|
||||||
tanks: WGApiTankopedia
|
tanks: WGApiTankopedia
|
||||||
tanks_by_tier = None
|
tanks_by_tier = None
|
||||||
@@ -979,33 +1299,44 @@ class WG:
|
|||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
tankopedia_fn: str,
|
tankopedia_fn: str = "tanks.json",
|
||||||
WG_app_id: str = _DEFAULT_WG_APP_ID,
|
WG_app_id: str = _DEFAULT_WG_APP_ID,
|
||||||
maps_fn: str | None = None,
|
maps_fn: str = "maps.json",
|
||||||
stats_cache: bool = False,
|
stats_cache: bool = False,
|
||||||
rate_limit: int = 10,
|
rate_limit: int = 10,
|
||||||
global_rate_limit=True,
|
global_rate_limit=True,
|
||||||
):
|
):
|
||||||
with open(tankopedia_fn, mode="r") as file:
|
self.WG_app_id: str = WG_app_id
|
||||||
|
self.tanks: WGApiTankopedia
|
||||||
|
self.maps: Maps
|
||||||
|
self.global_rate_limit = global_rate_limit
|
||||||
|
|
||||||
|
# read tankopedia
|
||||||
|
with open(tankopedia_fn, mode="rt") as file:
|
||||||
try:
|
try:
|
||||||
self.tanks: WGApiTankopedia = WGApiTankopedia.parse_raw(file.read())
|
self.tanks: WGApiTankopedia = WGApiTankopedia.parse_raw(file.read())
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
error(f"could not parse Tankopedia: {tankopedia_fn}")
|
error(f"could not parse Tankopedia: {tankopedia_fn}")
|
||||||
|
|
||||||
self.WG_app_id = WG_app_id
|
WG.tanks = self.tanks # WHY?
|
||||||
# self.load_tanks(tankopedia_fn)
|
|
||||||
WG.tanks = self.tanks
|
|
||||||
self.global_rate_limit = global_rate_limit
|
|
||||||
|
|
||||||
if maps_fn is not None:
|
# read maps
|
||||||
if os.path.exists(maps_fn) and os.path.isfile(maps_fn):
|
if (maps := Maps.parse_str(self.MAPS_JSON)) is not None:
|
||||||
try:
|
self.maps = maps
|
||||||
with open(maps_fn, "rt", encoding="utf8") as f:
|
|
||||||
WG.maps = json.loads(f.read())
|
|
||||||
except Exception as err:
|
|
||||||
error("Could not read maps file: " + maps_fn + "\n" + str(err))
|
|
||||||
else:
|
else:
|
||||||
verbose("Could not find maps file: " + maps_fn)
|
error("could not parse default map data")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if os.path.isfile(maps_fn):
|
||||||
|
try:
|
||||||
|
with open(maps_fn, "rt", encoding="utf8") as file:
|
||||||
|
self.maps = Maps.parse_raw(file.read())
|
||||||
|
except ValidationError as err:
|
||||||
|
error(f"invalid maps file format: {maps_fn}")
|
||||||
|
except IOError as err:
|
||||||
|
error(f"Could not read maps file: {maps_fn}")
|
||||||
|
error(err)
|
||||||
|
|
||||||
if self.WG_app_id is not None:
|
if self.WG_app_id is not None:
|
||||||
headers = {"Accept-Encoding": "gzip, deflate"}
|
headers = {"Accept-Encoding": "gzip, deflate"}
|
||||||
if self.global_rate_limit:
|
if self.global_rate_limit:
|
||||||
@@ -1082,20 +1413,20 @@ class WG:
|
|||||||
return "eu"
|
return "eu"
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@classmethod
|
# @classmethod
|
||||||
def update_maps(cls, map_data: dict):
|
# def update_maps(cls, map_data: dict):
|
||||||
"""Update maps data"""
|
# """Update maps data"""
|
||||||
cls.maps = map_data
|
# cls.maps = map_data
|
||||||
return None
|
# return None
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_map(self, map_str: str) -> str:
|
def get_map(self, map_str: str) -> str:
|
||||||
"""Return map name from short map string in replays"""
|
"""Return map name from short map string in replays"""
|
||||||
try:
|
try:
|
||||||
return self.maps[map_str]
|
return self.maps[map_str].name
|
||||||
except:
|
except:
|
||||||
error("Map " + map_str + " not found")
|
error("Map " + map_str + " not found")
|
||||||
return None
|
return "UNKNOWN MAP"
|
||||||
|
|
||||||
# @classmethod
|
# @classmethod
|
||||||
# def get_tank_user_strs(self) -> str:
|
# def get_tank_user_strs(self) -> str:
|
||||||
@@ -1256,25 +1587,25 @@ class WG:
|
|||||||
# error("Could not read tankopedia: " + tankopedia_fn, err)
|
# error("Could not read tankopedia: " + tankopedia_fn, err)
|
||||||
# return False
|
# return False
|
||||||
|
|
||||||
def get_replay_filename(self, replay: dict):
|
# def get_replay_filename(self, replay: dict):
|
||||||
try:
|
# try:
|
||||||
summary = replay["data"]["summary"]
|
# summary = replay["data"]["summary"]
|
||||||
timestamp = int(summary["battle_start_timestamp"])
|
# timestamp = int(summary["battle_start_timestamp"])
|
||||||
timestamp = get_date_str(timestamp, date_format="%Y%m%d_%H%M")
|
# timestamp = get_date_str(timestamp, date_format="%Y%m%d_%H%M")
|
||||||
player = summary["player_name"]
|
# player = summary["player_name"]
|
||||||
arena_id = int(summary["arena_unique_id"])
|
# arena_id = int(summary["arena_unique_id"])
|
||||||
vehicle = self.name2tank_str(summary["vehicle"])
|
# vehicle = self.name2tank_str(summary["vehicle"])
|
||||||
vehicle.replace(" ", "_")
|
# vehicle.replace(" ", "_")
|
||||||
|
|
||||||
return "{:s}_{:s}_{:s}_{:d}.wotbreplay.json".format(
|
# return "{:s}_{:s}_{:s}_{:d}.wotbreplay.json".format(
|
||||||
timestamp, player, vehicle, arena_id
|
# timestamp, player, vehicle, arena_id
|
||||||
)
|
# )
|
||||||
except Exception as err:
|
# except Exception as err:
|
||||||
error("Unexpected Exception", err)
|
# error("Unexpected Exception", err)
|
||||||
return None
|
# return None
|
||||||
|
|
||||||
def get_map_user_strs(self) -> str:
|
# def get_map_user_strs(self) -> str:
|
||||||
return self.maps.keys()
|
# return self.maps.keys()
|
||||||
|
|
||||||
# def tank_str2name(self, tank_str: str) -> str:
|
# def tank_str2name(self, tank_str: str) -> str:
|
||||||
# """Return tank name from short tank string in replays"""
|
# """Return tank name from short tank string in replays"""
|
||||||
|
|||||||
@@ -1,60 +1 @@
|
|||||||
{
|
{"Random": {"key": "Random", "name": "Random map", "id": -1, "mode": 1}, "amigosville": {"key": "amigosville", "name": "Falls Creek", "id": -1, "mode": 1}, "amigosville_02": {"key": "amigosville_02", "name": "Falls Creek - Bridge", "id": -1, "mode": 3}, "amigosville_03": {"key": "amigosville_03", "name": "Falls Creek - Factory", "id": -1, "mode": 3}, "asia": {"key": "asia", "name": "Lost Temple", "id": -1, "mode": 1}, "canal": {"key": "canal", "name": "Canal", "id": -1, "mode": 1}, "canal_01": {"key": "canal_01", "name": "Canal - Factory", "id": -1, "mode": 3}, "canyon": {"key": "canyon", "name": "Canyon", "id": -1, "mode": 1}, "desert_train": {"key": "desert_train", "name": "Desert Sands", "id": -1, "mode": 1}, "desert_train_02": {"key": "desert_train_02", "name": "Desert Sands - Town", "id": -1, "mode": 3}, "desert_train_03": {"key": "desert_train_03", "name": "Desert Sands - Dunes", "id": -1, "mode": 3}, "erlenberg": {"key": "erlenberg", "name": "Middleburg", "id": -1, "mode": 1}, "erlenberg_01": {"key": "erlenberg_01", "name": "Middleburg - Town", "id": -1, "mode": 3}, "erlenberg_02": {"key": "erlenberg_02", "name": "Middleburg - Hill", "id": -1, "mode": 3}, "faust": {"key": "faust", "name": "Faust", "id": -1, "mode": 1}, "forgecity": {"key": "forgecity", "name": "New Bay", "id": -1, "mode": 1}, "fort": {"key": "fort", "name": "Fort Despair", "id": -1, "mode": 1}, "grossberg": {"key": "grossberg", "name": "Dynasty's Pearl", "id": -1, "mode": 1}, "himmelsdorf": {"key": "himmelsdorf", "name": "Himmelsdorf", "id": -1, "mode": 1}, "holland": {"key": "holland", "name": "Molendijk", "id": -1, "mode": 1}, "holmeisk": {"key": "holmeisk", "name": "Wasteland", "id": -1, "mode": 1}, "iceworld": {"key": "iceworld", "name": "Everfrost", "id": -1, "mode": 2}, "idle": {"key": "idle", "name": "Yukon", "id": -1, "mode": 1}, "italy": {"key": "italy", "name": "Vineyards", "id": -1, "mode": 1}, "karelia": {"key": "karelia", "name": "Rockfield", "id": -1, "mode": 1}, "karieri": {"key": "karieri", "name": "Copperfield", "id": -1, "mode": 1}, "lake": {"key": "lake", "name": "Mirage", "id": -1, "mode": 1}, "lumber": {"key": "lumber", "name": "Horrorstadt", "id": -1, "mode": 1}, "lumber_01": {"key": "lumber_01", "name": "Alpenstadt - Town", "id": -1, "mode": 3}, "malinovka": {"key": "malinovka", "name": "Winter Malinovka", "id": -1, "mode": 1}, "medvedkovo": {"key": "medvedkovo", "name": "Dead Rail", "id": -1, "mode": 1}, "medvedkovo_02": {"key": "medvedkovo_02", "name": "Dead Rail - Valley", "id": -1, "mode": 3}, "medvedkovo_03": {"key": "medvedkovo_03", "name": "Dead Rail - Railroad", "id": -1, "mode": 3}, "milbase": {"key": "milbase", "name": "Yamato Harbor", "id": -1, "mode": 1}, "milbase_02": {"key": "milbase_02", "name": "Yamato Harbor - Battleship", "id": -1, "mode": 3}, "milbase_03": {"key": "milbase_03", "name": "Yamato Harbor - Hills", "id": -1, "mode": 3}, "milbase_04": {"key": "milbase_04", "name": "Yamato Harbor - Center", "id": -1, "mode": 3}, "milbase_05": {"key": "milbase_05", "name": "Yamato Harbor - Dock", "id": -1, "mode": 3}, "moon": {"key": "moon", "name": "Sea of Tranquility", "id": -1, "mode": 2}, "mountain": {"key": "mountain", "name": "Black Goldville", "id": -1, "mode": 1}, "neptune": {"key": "neptune", "name": "Normandy", "id": -1, "mode": 1}, "neptune_01": {"key": "neptune_01", "name": "Normandy - Hills", "id": -1, "mode": 3}, "neptune_02": {"key": "neptune_02", "name": "Normandy - Beach", "id": -1, "mode": 3}, "north": {"key": "north", "name": "North", "id": -1, "mode": 1}, "ordeal": {"key": "ordeal", "name": "Trial by Fire", "id": -1, "mode": 1}, "plant": {"key": "plant", "name": "Ghost Factory", "id": -1, "mode": 1}, "pliego": {"key": "pliego", "name": "Castilla", "id": -1, "mode": 1}, "port": {"key": "port", "name": "Port Bay", "id": -1, "mode": 1}, "rift": {"key": "rift", "name": "Hellas", "id": -1, "mode": 1}, "rock": {"key": "rock", "name": "Mayan Ruins", "id": -1, "mode": 1}, "rudniki": {"key": "rudniki", "name": "Mines", "id": -1, "mode": 1}, "rudniki_01": {"key": "rudniki_01", "name": "Mines - Hill", "id": -1, "mode": 3}, "rudniki_02": {"key": "rudniki_02", "name": "Mines - Village", "id": -1, "mode": 3}, "rudniki_03": {"key": "rudniki_03", "name": "Mines - Center", "id": -1, "mode": 3}, "savanna": {"key": "savanna", "name": "Oasis Palms", "id": -1, "mode": 1}, "skit": {"key": "skit", "name": "Naval Frontier", "id": -1, "mode": 1}, "test": {"key": "test", "name": "World of Ducks", "id": -1, "mode": 2}, "tutorial": {"key": "tutorial", "name": "Proving Grounds", "id": -1, "mode": 0}}
|
||||||
"Random": "Random map",
|
|
||||||
"amigosville": "Falls Creek",
|
|
||||||
"amigosville_02": "Falls Creek - Bridge",
|
|
||||||
"amigosville_03": "Falls Creek - Factory",
|
|
||||||
"asia": "Lost Temple",
|
|
||||||
"canal": "Canal",
|
|
||||||
"canal_01": "Canal - Factory",
|
|
||||||
"canyon": "Canyon",
|
|
||||||
"desert_train": "Desert Sands",
|
|
||||||
"desert_train_02": "Desert Sands - Town",
|
|
||||||
"desert_train_03": "Desert Sands - Dunes",
|
|
||||||
"erlenberg": "Middleburg",
|
|
||||||
"erlenberg_01": "Middleburg - Town",
|
|
||||||
"erlenberg_02": "Middleburg - Hill",
|
|
||||||
"faust": "Faust",
|
|
||||||
"forgecity": "New Bay",
|
|
||||||
"fort": "Fort Despair",
|
|
||||||
"grossberg": "Dynasty's Pearl",
|
|
||||||
"himmelsdorf": "Himmelsdorf",
|
|
||||||
"holland": "Molendijk",
|
|
||||||
"holmeisk": "Wasteland",
|
|
||||||
"iceworld": "Everfrost",
|
|
||||||
"idle": "Yukon",
|
|
||||||
"italy": "Vineyards",
|
|
||||||
"karelia": "Rockfield",
|
|
||||||
"karieri": "Copperfield",
|
|
||||||
"lake": "Mirage",
|
|
||||||
"lumber": "Alpenstadt",
|
|
||||||
"lumber_01": "Alpenstadt - Town",
|
|
||||||
"malinovka": "Winter Malinovka",
|
|
||||||
"medvedkovo": "Dead Rail",
|
|
||||||
"medvedkovo_02": "Dead Rail - Valley",
|
|
||||||
"medvedkovo_03": "Dead Rail - Railroad",
|
|
||||||
"milbase": "Yamato Harbor",
|
|
||||||
"milbase_02": "Yamato Harbor - Battleship",
|
|
||||||
"milbase_03": "Yamato Harbor - Hills",
|
|
||||||
"milbase_04": "Yamato Harbor - Center",
|
|
||||||
"milbase_05": "Yamato Harbor - Dock",
|
|
||||||
"moon": "Sea of Tranquility",
|
|
||||||
"mountain": "Black Goldville",
|
|
||||||
"neptune": "Normandy",
|
|
||||||
"neptune_01": "Normandy - Hills",
|
|
||||||
"neptune_02": "Normandy - Beach",
|
|
||||||
"north": "North",
|
|
||||||
"ordeal": "Trial by Fire",
|
|
||||||
"plant": "Ghost Factory",
|
|
||||||
"pliego": "Castilla",
|
|
||||||
"port": "Port Bay",
|
|
||||||
"rift": "Hellas",
|
|
||||||
"rock": "Mayan Ruins",
|
|
||||||
"rudniki": "Mines",
|
|
||||||
"rudniki_01": "Mines - Hill",
|
|
||||||
"rudniki_02": "Mines - Village",
|
|
||||||
"rudniki_03": "Mines - Center",
|
|
||||||
"savanna": "Oasis Palms",
|
|
||||||
"skit": "Naval Frontier",
|
|
||||||
"test": "World of Ducks",
|
|
||||||
"tutorial": "Proving Grounds"
|
|
||||||
}
|
|
||||||
Reference in new issue
Block a user