From 14190bea74aeb00fc8e0d6b6934e97fd6775083e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergio=20=C3=81lvarez?= Date: Fri, 14 May 2021 00:34:22 +0200 Subject: [PATCH] updated codebase --- .gitignore | 1 + updater.py | 135 +++++++++++++++++++++++++---------------------------- 2 files changed, 64 insertions(+), 72 deletions(-) diff --git a/.gitignore b/.gitignore index bd59350..411d538 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ .credentials +/__pycache__/ diff --git a/updater.py b/updater.py index 957b4e1..5d0d38f 100644 --- a/updater.py +++ b/updater.py @@ -3,85 +3,76 @@ import os import errno import requests import json +import datetime -""" -https://develop.battle.net/documentation/guides/regionality-and-apis -""" -regions = [ - {'code': 'us', 'locales': ['en_US', 'es_MX', 'pt_BR']}, - {'code': 'eu', 'locales': ['en_GB', 'es_ES', 'fr_FR', 'ru_RU', 'de_DE', 'pt_PT', 'it_IT']}, - {'code': 'kr', 'locales': ['ko_KR']}, - {'code': 'tw', 'locales': ['zh_TW']}, - #{'code': 'cn', 'locales': ['zh_CN']} -] +import config +import blizzard +import spec -""" -https://develop.battle.net/documentation/world-of-warcraft/game-data-apis -""" -apis = [ - {'path': '/data/wow/achievement-category/index', 'namespaces': ['static']}, - {'path': '/data/wow/achievement/index', 'namespaces': ['static']}, - {'path': '/data/wow/connected-realm/index', 'namespaces': ['dynamic']}, - {'path': '/data/wow/covenant/index', 'namespaces': ['static']}, - {'path': '/data/wow/covenant/soulbind/index', 'namespaces': ['static']}, - {'path': '/data/wow/covenant/conduit/index', 'namespaces': ['static']}, - {'path': '/data/wow/creature-family/index', 'namespaces': ['static']}, - {'path': '/data/wow/creature-type/index', 'namespaces': ['static']}, - {'path': '/data/wow/item-class/index', 'namespaces': ['static']}, - {'path': '/data/wow/item-set/index', 'namespaces': ['static']}, - {'path': '/data/wow/journal-expansion/index', 'namespaces': ['static']}, - {'path': '/data/wow/journal-encounter/index', 'namespaces': ['static']}, - {'path': '/data/wow/journal-instance/index', 'namespaces': ['static']}, - {'path': '/data/wow/modified-crafting/index', 'namespaces': ['static']}, - {'path': '/data/wow/modified-crafting/category/index', 'namespaces': ['static']}, - {'path': '/data/wow/modified-crafting/reagent-slot-type/index', 'namespaces': ['static']}, - {'path': '/data/wow/mount/index', 'namespaces': ['static']}, - {'path': '/data/wow/keystone-affix/index', 'namespaces': ['static']}, - {'path': '/data/wow/mythic-keystone/dungeon/index', 'namespaces': ['dynamic']}, - {'path': '/data/wow/mythic-keystone/index', 'namespaces': ['dynamic']}, - {'path': '/data/wow/mythic-keystone/period/index', 'namespaces': ['dynamic']}, -] +def log(*data): + print(datetime.datetime.now(), '|', *data) -credentials = open('.credentials').read().strip().split(':') -cache = './cache' +class Updater(object): + def __init__(self): + self.http = requests.Session() + self.credentials = blizzard.get_credentials(config.pwd) -def getApiHost(region): - return f"{region}.api.blizzard.com" if region != 'cn' else 'gateway.battlenet.com.cn' + def region_oauth(self, region: str) -> dict: + api = self.http.post(f"{blizzard.get_bnet_host(region)}/oauth/token", data={'grant_type': 'client_credentials'}, auth=self.credentials) + oauth = api.json() + #log(region, oauth) + api.raise_for_status() + return oauth -def getBnetHost(region): - region = region if region not in ['tw', 'kr'] else 'apac' - return f"{region}.battle.net" if region != 'cn' else 'www.battlenet.com.cn' + def api_call(self, url: str) -> requests.Response: + api = self.http.get(url) #, headers={'Authorization': f"Authorization: Token {access_token}"}) + api.raise_for_status() + return api -s = requests.Session() + def create_dst(self, dst: str): + try: + os.makedirs(os.path.dirname(dst)) + except OSError as e: + if e.errno != errno.EEXIST: + raise -for region in regions: - try: - r = s.post(f"https://{getBnetHost(region['code'])}/oauth/token", data={'grant_type': 'client_credentials'}, auth=(credentials[0], credentials[1])) - oauth = r.json() - #print(region, oauth) - r.raise_for_status() - except requests.exceptions.HTTPError as e: - print(region, e) - continue + def save(self, dst, content): + with open(dst, 'w+') as f: + f.write(json.dumps(content.json(), indent=4)) - for api in apis: - for locale in region['locales']: - for namespace in api['namespaces']: - try: - url = f"https://{getApiHost(region['code'])}{api['path']}?namespace={namespace}-{region['code']}&locale={locale}&access_token={oauth['access_token']}" - r = s.get(url) #, headers={'Authorization': f"Authorization: Token {oauth['access_token']}"}) - #print(r.request.headers, r.status_code, r.reason, r.headers, url) - print(region['code'], locale, r.status_code, api['path']) - r.raise_for_status() + def iterate_index(self): + for region in spec.regions: + # access token for region + try: + oauth = self.region_oauth(region['code']) + access_token = oauth['access_token'] + except (requests.exceptions.HTTPError, KeyError) as e: + log(region, type(e), e) + continue - dst = f"{cache}/{region['code']}/{locale}/{api['path'].replace('/', '_')}.{namespace}.json" - try: - os.makedirs(os.path.dirname(dst)) - except OSError as e: - if e.errno != errno.EEXIST: - raise - - open(dst, 'w+').write(json.dumps(r.json(), indent=4)) - except requests.exceptions.HTTPError as e: - print(e) + # loop every api + for api in spec.apis: + if not 'index' in api or not api['index']: continue + + for locale in region['locales']: + # retail or classic + for namespace in api['namespaces']: + try: + dst = f"{config.raw}/{region['code']}/{locale}/{api['path'].replace('/', '_')}.{namespace}.json" + + url = f"{blizzard.get_api_host(region['code'])}{api['path']}" + url += f"?namespace={namespace}-{region['code']}&locale={locale}&access_token={access_token}" + response = self.api_call(url) + + self.create_dst(dst) + self.save(dst, response) + + except requests.exceptions.HTTPError as e: + log(e) + continue + +if __name__ == "__main__": + updater = Updater() + updater.iterate_index() + #updater.iterate_links()