Module genshin.utility.extdb

External databases for Genshin Impact data.

Functions

async def update_characters_ambr(langs: Sequence[str] = ()) ‑> None
Expand source code
async def update_characters_ambr(langs: typing.Sequence[str] = ()) -> None:
    """Update characters with https://ambr.top/."""
    version = (await _fetch_jsons(AMBR_VERSION_URL))[0]["data"]["vh"]
    langs = langs or list(LANGS.keys())
    urls = [AMBR_URL.format(lang=LANG_MAP[lang]) + f"?vh={version}" for lang in langs]

    characters_list = await _fetch_jsons(*urls)

    for lang, characters in zip(langs, characters_list):
        for strid, char in characters["data"]["items"].items():
            if "-" in strid and "anemo" not in strid:
                continue  # traveler element

            update_character_name(
                lang=lang,
                id=int(strid.split("-")[0]),
                icon_name=char["icon"][len("UI_AvatarIcon_") :],  # noqa: E203
                name=char["name"],
                element=ELEMENTS_MAP[char["element"]],
                rarity=char["rank"],
            )

    CACHE_FILE.write_text(json.dumps(model_constants.CHARACTER_NAMES))

Update characters with https://ambr.top/.

async def update_characters_any(langs: str | Sequence[str] | None = None, *, lenient: bool = False) ‑> None
Expand source code
async def update_characters_any(
    langs: typing.Union[str, typing.Sequence[str], None] = None,
    *,
    lenient: bool = False,
) -> None:
    """Update characters with the most efficient resource.

    Will not re-request data if lenient is True.
    """
    if not langs:
        langs = list(LANGS.keys())
    if isinstance(langs, str):
        langs = [langs]
    if lenient:
        langs = [lang for lang in langs if not model_constants.CHARACTER_NAMES.get(lang)]
        if len(langs) == 0:
            return

    if len(langs) == 1:
        updators = [update_characters_ambr, update_characters_enka]
    else:
        updators = [update_characters_enka, update_characters_ambr]

    updators.append(update_characters_genshindata)

    for updator in updators:
        try:
            await updator(langs)
        except Exception:
            LOGGER_.exception("Failed to update characters with %s", updator.__name__)
        else:
            return

    raise Exception("Failed to update characters, all functions raised an error.")

Update characters with the most efficient resource.

Will not re-request data if lenient is True.

async def update_characters_enka(langs: Sequence[str] = ()) ‑> None
Expand source code
async def update_characters_enka(langs: typing.Sequence[str] = ()) -> None:
    """Update characters with https://github.com/EnkaNetwork/API-docs/."""
    characters, locs = await _fetch_jsons(ENKA_CHARACTERS_URL, ENKA_LOC_URL)

    for strid, char in characters.items():
        if "-" in strid:
            continue  # traveler element

        for short_lang, loc in locs.items():
            if (lang := ENKA_LANG_MAP.get(short_lang)) is None:
                continue
            update_character_name(
                lang=lang,
                id=int(strid),
                icon_name=char["SideIconName"][len("UI_AvatarIcon_Side_") :],  # noqa: E203
                name=loc[str(char["NameTextMapHash"])],
                element=ELEMENTS_MAP[char["Element"]],
                rarity=RARITY_MAP[char["QualityType"]],
            )

    CACHE_FILE.write_text(json.dumps(model_constants.CHARACTER_NAMES))
async def update_characters_genshindata(langs: Sequence[str] = ()) ‑> None
Expand source code
async def update_characters_genshindata(langs: typing.Sequence[str] = ()) -> None:
    """Update characters with https://github.com/Dimbreath/GenshinData/.

    This method requires the download of >20MB per language so it's not recommended.
    """
    langs = langs or list(LANGS.keys())
    urls = [GENSHINDATA_TEXTMAP_URL.format(lang=LANG_MAP[lang].upper()) for lang in langs]

    # I love spamming github
    characters, talent_depot, talents, *textmaps = await _fetch_jsons(
        GENSHINDATA_CHARACTERS_URL,
        GENSHINDATA_TALENT_DEPOT_URL,
        GENSHINDATA_TALENT_URL,
        *urls,
    )

    talent_depot = {talent["id"]: talent for talent in talent_depot}
    talents = {talent["id"]: talent for talent in talents}

    for char in characters:
        for lang, textmap in zip(langs, textmaps):
            if char["skillDepotId"] == 101 or char["iconName"].endswith("_Kate") or str(char["id"])[:2] == "11":
                continue  # test character

            if char["candSkillDepotIds"]:
                raw_element = "Wind"  # traveler
            else:
                talent = talent_depot[char["skillDepotId"]]
                raw_element = talents[talent["energySkill"]]["costElemType"]

            update_character_name(
                lang=lang,
                id=char["id"],
                icon_name=char["iconName"][len("UI_AvatarIcon_") :],  # noqa: E203
                name=textmap[str(char["nameTextMapHash"])],
                element=ELEMENTS_MAP[raw_element],
                rarity=RARITY_MAP[char["qualityType"]],
            )

    CACHE_FILE.write_text(json.dumps(model_constants.CHARACTER_NAMES))

Update characters with https://github.com/Dimbreath/GenshinData/.

This method requires the download of >20MB per language so it's not recommended.