diff --git a/api.md b/api.md index 9eb4b69..9a116ec 100644 --- a/api.md +++ b/api.md @@ -10,8 +10,8 @@ Regions and platforms can be overridden with URL parameters. ### Regions (V3) -In V3, all regions are automatically checked. Data is returned for any regions the user is in. The other regions return -`null`. See V3 results below. +Blizzard has somewhat recently changed regions such that there are no region-specific statistics anymore. All region- +specific endpoints automatically redirect to remove the region, and region data ends up resulting in duplicate data. ### Platforms @@ -21,15 +21,15 @@ You can override the platform with `?platform=`. This defaults to `p The default output is standard JSON, but you can prettify it with `?format=json_pretty` to have it in a more readable format. (The other option is installing a browser plugin, such as -[JSONView](https://jsonview.com/). +[JSONView](https://jsonview.com/)). #### Field formatting Field names inside the inner dict will correspond to all of the cards shown inside the -[PlayOverwatch](https://playoverwatch.com/en-us/career/pc/eu/Downy-2877) pages corresponding to +[PlayOverwatch](https://playoverwatch.com/en-us/career/pc/Downy-2877) pages corresponding to the users, with a slight formatting tweak: - - All nonalphanumeric characters are removed + - All non-alphanumeric characters are removed - All spaces are replaced with underscores - The entire fields are lowercase @@ -62,15 +62,11 @@ Unless otherwise specified, time fields are always in ***hours***. "api_ver": 3, "route": "/api/v3/u/Dad-12262/blob" }, - "kr": null, - "eu": null, - "us": { + "any": { "stats": {}, "heroes": {}, "achievements": {} - }, - "any": null - + } } ``` @@ -99,14 +95,11 @@ Each of these will have several other keys: ```json { - "_request": { "api_ver": 3, "route": "/api/v3/u/Dad-12262/stats" }, - "kr": null, - "eu": null, - "us": { + "any": { "stats": { "competitive": { "overall_stats": { @@ -264,9 +257,7 @@ Each of these will have several other keys: } }, "achievements": { } - }, - "any": null - + } } ``` @@ -283,14 +274,11 @@ This is a mapping of category -> hash which is another mapping of achievement -> ```json { - "_request": { "api_ver": 3, "route": "/api/v3/u/Dad-12262/achievements" }, - "kr": null, - "eu": null, - "us": { + "any": { "stats": { }, "heroes": { "stats": { @@ -377,9 +365,7 @@ This is a mapping of category -> hash which is another mapping of achievement -> "double_cap": true } } - }, - "any": null - + } } ``` @@ -405,14 +391,11 @@ The `heroes` key will contain two subkeys, inside the respective `quickplay` and ```json { - "_request": { "api_ver": 3, "route": "/api/v3/u/Dad-12262/heroes" }, - "kr": null, - "eu": null, - "us": { + "any": { "stats": { }, "heroes": { "stats": { @@ -561,8 +544,6 @@ The `heroes` key will contain two subkeys, inside the respective `quickplay` and } }, "achievements": { } - }, - "any": null - + } } ``` diff --git a/owapi/blizz_interface.py b/owapi/blizz_interface.py index a941219..440da88 100644 --- a/owapi/blizz_interface.py +++ b/owapi/blizz_interface.py @@ -20,13 +20,10 @@ from owapi import util B_BASE_URL = "https://playoverwatch.com/en-us/" -B_PAGE_URL = B_BASE_URL + "career/{platform}{region}/{btag}" +B_PAGE_URL = B_BASE_URL + "career/{platform}/{btag}" B_HEROES_URL = B_BASE_URL + "heroes" B_HERO_URL = B_HEROES_URL + "/{hero}" -# The currently available specific regions. -AVAILABLE_REGIONS = ["/eu", "/us", "/kr"] - logger = logging.getLogger("OWAPI") @@ -73,15 +70,11 @@ def _parse_page_lxml(content: str) -> etree._Element: async def get_user_page(ctx: HTTPRequestContext, battletag: str, platform: str = "pc", - region: str = "us", cache_time=300, cache_404=False) -> etree._Element: """ Downloads the BZ page for a user, and parses it. """ - if platform != "pc": - region = "" - built_url = B_PAGE_URL.format( - region=region, btag=battletag.replace("#", "-"), platform=platform) + built_url = B_PAGE_URL.format(btag=battletag.replace("#", "-"), platform=platform) page_body = await get_page_body(ctx, built_url, cache_time=cache_time, cache_404=cache_404) if not page_body: @@ -106,46 +99,40 @@ async def fetch_all_user_pages(ctx: HTTPRequestContext, battletag: str, *, """ Fetches all user pages for a specified user. - Returns a dictionary in the format of `{region: etree._Element | None}`. + Returns a dictionary in the format of `{"any": etree._Element | None}`. """ if platform != "pc": - coro = get_user_page(ctx, battletag, region="", platform=platform, cache_404=True) + coro = get_user_page(ctx, battletag, platform=platform, cache_404=True) result = await coro if isinstance(result, etree._Element): - return {"any": result, - "eu": None, "us": None, "kr": None} + return {"any": result} else: # Raise a 404. raise NotFound() futures = [] - for region in AVAILABLE_REGIONS: - # Add the get_user_page coroutine. - coro = get_user_page(ctx, battletag, region=region, platform=platform, cache_404=True) - futures.append(coro) + coro = get_user_page(ctx, battletag, platform=platform, cache_404=True) + futures.append(coro) - # Gather all the futures to download paralellely. + # Gather all the futures to download in parallel. results = await asyncio.gather(*futures, return_exceptions=True) - d = {"any": None} + user_data = {"any": None} error = None - for region, result in zip(AVAILABLE_REGIONS, results): - # Remove the `/` from the front of the region. - # This is used internally to make building the URL to get simpler. - region = region[1:] + for key, result in zip(["any"], results): # Make sure it's either a None or an element. if isinstance(result, etree._Element): - d[region] = result + user_data[key] = result elif isinstance(result, Exception): logger.error("Failed to fetch user page!\n{}".format( ''.join(traceback.format_exception(type(result), result, result.__traceback__)) )) error = result - d[region] = None + user_data[key] = None else: - d[region] = None + user_data[key] = None # Check if we should raise or return. - if not any(d[i[1:]] is not None for i in AVAILABLE_REGIONS): + if user_data["any"] is None: if error is not None: e = InternalServerError() e.__cause__ = error @@ -153,34 +140,7 @@ async def fetch_all_user_pages(ctx: HTTPRequestContext, battletag: str, *, raise e raise NotFound() - return d - - -async def region_helper_v2(ctx: HTTPRequestContext, battletag: str, platform="pc", region=None, - extra=""): - """ - Downloads the correct page for a user in the right region. - - This will return either (etree._Element, region) or (None, None). - """ - if region is None: - reg_l = ["/eu", "/us", "/kr"] - else: - if not region.startswith("/"): - # ugh - region = "/" + region - reg_l = [region] - - for reg in reg_l: - # Get the user page. - page = await get_user_page(ctx, battletag, platform=platform, region=reg) - # Check if the page was returned successfully. - # If it was, return it. - if page is not None: - return page, reg[1:] - else: - # Since we continued without returning, give back the None, None. - return None, None + return user_data async def get_hero_data(ctx: HTTPRequestContext, hero: str):