-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* style: Format pyproject.toml * Move asset stuff to gi folder * chore(ruff): Update config Add docs rules * chore(deps): Update ruff and pytest * Move models to gi folder * chore: Add vscode config * Add some models * Update ruff config * Move enums around * Change stuff * Update docstrings and organize imports * Add vscode config * Fix import errors * Add element and path enums * Update * Update * chore(ver): Bump to v2.0.0
- Loading branch information
Showing
41 changed files
with
1,765 additions
and
592 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"python.analysis.typeCheckingMode": "standard", | ||
"python.analysis.importFormat": "relative", | ||
"python.analysis.diagnosticMode": "workspace" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,2 @@ | ||
from .client import * | ||
from .constants import * | ||
from .enums import * | ||
from .exceptions import * | ||
from . import errors, gi, hsr, utils | ||
from .clients import GenshinClient, HSRClient |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
import contextlib | ||
from typing import Any | ||
|
||
import aiofiles | ||
import orjson | ||
|
||
|
||
class AssetData: | ||
"""Base class for asset data.""" | ||
|
||
def __init__(self) -> None: | ||
self._data: dict[str, Any] | None = None | ||
|
||
def __getitem__(self, key: str) -> Any: | ||
if self._data is None: | ||
msg = f"{self.__class__.__name__} not loaded" | ||
raise RuntimeError(msg) | ||
|
||
text = self._data.get(str(key)) | ||
if text is None: | ||
msg = f"Cannot find text for key {key!r} in `{self.__class__.__name__}._data`, consider calling `update_assets` to update the assets" | ||
raise KeyError(msg) | ||
|
||
return text | ||
|
||
def __iter__(self) -> Any: | ||
if self._data is None: | ||
msg = f"{self.__class__.__name__} not loaded" | ||
raise RuntimeError(msg) | ||
|
||
return iter(self._data) | ||
|
||
def values(self) -> Any: | ||
"""Get the values of the data.""" | ||
if self._data is None: | ||
msg = f"{self.__class__.__name__} not loaded" | ||
raise RuntimeError(msg) | ||
|
||
return self._data.values() | ||
|
||
def items(self) -> Any: | ||
"""Get the items of the data.""" | ||
if self._data is None: | ||
msg = f"{self.__class__.__name__} not loaded" | ||
raise RuntimeError(msg) | ||
|
||
return self._data.items() | ||
|
||
async def _open_json(self, path: str) -> dict[str, Any] | None: | ||
with contextlib.suppress(FileNotFoundError): | ||
async with aiofiles.open(path, encoding="utf-8") as f: | ||
return orjson.loads(await f.read()) | ||
return None | ||
|
||
def get(self, key: str, default: Any = None) -> str | Any: | ||
"""Get a text by key. | ||
Args: | ||
key (str): The key to get the text for. | ||
default (Any): The default value to return if the key is not found. | ||
Returns: | ||
str | Any: The text or the default value. | ||
""" | ||
if self._data is None: | ||
msg = f"{self.__class__.__name__} not loaded" | ||
raise RuntimeError(msg) | ||
|
||
text = self._data.get(str(key)) | ||
if text is None: | ||
return default | ||
|
||
return text |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
ASSET_PATH = ".enka_py/assets" | ||
|
||
TEXT_MAP_PATH = f"{ASSET_PATH}/text_map.json" | ||
CHARACTER_DATA_PATH = f"{ASSET_PATH}/characters.json" | ||
NAMECARD_DATA_PATH = f"{ASSET_PATH}/namecards.json" | ||
CONSTS_DATA_PATH = f"{ASSET_PATH}/consts.json" | ||
TALENTS_DATA_PATH = f"{ASSET_PATH}/talents.json" | ||
PFPS_DATA_PATH = f"{ASSET_PATH}/pfps.json" | ||
|
||
SOURCE_TO_PATH = { | ||
"https://raw.githubusercontent.com/seriaati/enka-py-assets/main/data/text_map.json": TEXT_MAP_PATH, | ||
"https://raw.githubusercontent.com/seriaati/enka-py-assets/main/data/characters.json": CHARACTER_DATA_PATH, | ||
"https://raw.githubusercontent.com/EnkaNetwork/API-docs/master/store/namecards.json": NAMECARD_DATA_PATH, | ||
"https://raw.githubusercontent.com/seriaati/enka-py-assets/main/data/consts.json": CONSTS_DATA_PATH, | ||
"https://raw.githubusercontent.com/seriaati/enka-py-assets/main/data/talents.json": TALENTS_DATA_PATH, | ||
"https://raw.githubusercontent.com/EnkaNetwork/API-docs/master/store/pfps.json": PFPS_DATA_PATH, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
from typing import TYPE_CHECKING | ||
|
||
from ..data import AssetData | ||
from .file_paths import ( | ||
CHARACTER_DATA_PATH, | ||
CONSTS_DATA_PATH, | ||
NAMECARD_DATA_PATH, | ||
PFPS_DATA_PATH, | ||
TALENTS_DATA_PATH, | ||
TEXT_MAP_PATH, | ||
) | ||
|
||
if TYPE_CHECKING: | ||
from ...enums.gi import Language | ||
|
||
__all__ = ("AssetManager",) | ||
|
||
|
||
class AssetManager: | ||
"""Genshin Impact asset manager.""" | ||
|
||
def __init__(self, lang: "Language") -> None: | ||
self._lang = lang | ||
self.text_map = TextMap(lang) | ||
self.character_data = CharacterData() | ||
self.namecard_data = NamecardData() | ||
self.consts_data = ConstsData() | ||
self.talents_data = TalentsData() | ||
self.pfps_data = PfpsData() | ||
|
||
async def load(self) -> bool: | ||
"""Load all assets. | ||
Returns: | ||
bool: Whether all assets were loaded successfully. | ||
""" | ||
return ( | ||
await self.text_map.load() | ||
and await self.character_data.load() | ||
and await self.namecard_data.load() | ||
and await self.consts_data.load() | ||
and await self.talents_data.load() | ||
and await self.pfps_data.load() | ||
) | ||
|
||
|
||
class TextMap(AssetData): | ||
def __init__(self, lang: "Language") -> None: | ||
super().__init__() | ||
self._lang = lang | ||
|
||
async def load(self) -> bool: | ||
text_map = await self._open_json(TEXT_MAP_PATH) | ||
if text_map is not None: | ||
self._data = text_map[self._lang.value] | ||
return self._data is not None | ||
|
||
|
||
class CharacterData(AssetData): | ||
async def load(self) -> bool: | ||
self._data = await self._open_json(CHARACTER_DATA_PATH) | ||
return self._data is not None | ||
|
||
|
||
class NamecardData(AssetData): | ||
async def load(self) -> bool: | ||
self._data = await self._open_json(NAMECARD_DATA_PATH) | ||
return self._data is not None | ||
|
||
|
||
class ConstsData(AssetData): | ||
async def load(self) -> bool: | ||
self._data = await self._open_json(CONSTS_DATA_PATH) | ||
return self._data is not None | ||
|
||
|
||
class TalentsData(AssetData): | ||
async def load(self) -> bool: | ||
self._data = await self._open_json(TALENTS_DATA_PATH) | ||
return self._data is not None | ||
|
||
|
||
class PfpsData(AssetData): | ||
async def load(self) -> bool: | ||
self._data = await self._open_json(PFPS_DATA_PATH) | ||
return self._data is not None |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
ASSET_PATH = ".enka_py/assets/hsr" | ||
|
||
TEXT_MAP_PATH = f"{ASSET_PATH}/text_map.json" | ||
CHARACTER_DATA_PATH = f"{ASSET_PATH}/characters.json" | ||
LIGHT_CONE_DATA_PATH = f"{ASSET_PATH}/light_cone.json" | ||
RELIC_DATA_PATH = f"{ASSET_PATH}/relic.json" | ||
SKILL_TREE_DATA_PATH = f"{ASSET_PATH}/skill_tree.json" | ||
META_DATA_PATH = f"{ASSET_PATH}/promotions.json" | ||
AVATAR_DATA_PATH = f"{ASSET_PATH}/avatars.json" | ||
PROPERTY_CONFIG_PATH = f"{ASSET_PATH}/property_config.json" | ||
|
||
ENKA_API_DOCS = "https://raw.githubusercontent.com/EnkaNetwork/API-docs/master/store/hsr" | ||
ENKA_PY_ASSETS = "https://raw.githubusercontent.com/seriaati/enka-py-assets/main/data/hsr" | ||
|
||
SOURCE_TO_PATH = { | ||
f"{ENKA_API_DOCS}/hsr.json": TEXT_MAP_PATH, | ||
f"{ENKA_API_DOCS}/honker_characters.json": CHARACTER_DATA_PATH, | ||
f"{ENKA_API_DOCS}/honker_weps.json": LIGHT_CONE_DATA_PATH, | ||
f"{ENKA_API_DOCS}/honker_relics.json": RELIC_DATA_PATH, | ||
f"{ENKA_API_DOCS}/honker_meta.json": META_DATA_PATH, | ||
f"{ENKA_API_DOCS}/honker_avatars.json": AVATAR_DATA_PATH, | ||
f"{ENKA_PY_ASSETS}/skill_tree.json": SKILL_TREE_DATA_PATH, | ||
f"{ENKA_PY_ASSETS}/property_config.json": PROPERTY_CONFIG_PATH, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
from typing import TYPE_CHECKING | ||
|
||
from ..data import AssetData | ||
from .file_paths import ( | ||
AVATAR_DATA_PATH, | ||
CHARACTER_DATA_PATH, | ||
LIGHT_CONE_DATA_PATH, | ||
META_DATA_PATH, | ||
PROPERTY_CONFIG_PATH, | ||
RELIC_DATA_PATH, | ||
SKILL_TREE_DATA_PATH, | ||
TEXT_MAP_PATH, | ||
) | ||
|
||
if TYPE_CHECKING: | ||
from ...enums.hsr import Language | ||
|
||
__all__ = ("AssetManager",) | ||
|
||
|
||
class AssetManager: | ||
"""Honkai Star Rail asset manager.""" | ||
|
||
def __init__(self, lang: "Language") -> None: | ||
self._lang = lang | ||
|
||
self.text_map = TextMap(lang) | ||
self.character_data = CharacterData() | ||
self.skill_tree_data = SkillTreeData() | ||
self.light_cones_data = LightConesData() | ||
self.relic_data = RelicData() | ||
self.meta_data = MetaData() | ||
self.avatar_data = AvatarData() | ||
self.property_config_data = PropertyConfigData() | ||
|
||
async def load(self) -> bool: | ||
"""Load all assets. | ||
Returns: | ||
bool: Whether all assets were loaded successfully. | ||
""" | ||
return ( | ||
await self.text_map.load() | ||
and await self.character_data.load() | ||
and await self.skill_tree_data.load() | ||
and await self.light_cones_data.load() | ||
and await self.relic_data.load() | ||
and await self.meta_data.load() | ||
and await self.avatar_data.load() | ||
and await self.property_config_data.load() | ||
) | ||
|
||
|
||
class TextMap(AssetData): | ||
def __init__(self, lang: "Language") -> None: | ||
super().__init__() | ||
self._lang = lang | ||
|
||
async def load(self) -> bool: | ||
text_map = await self._open_json(TEXT_MAP_PATH) | ||
if text_map is not None: | ||
self._data = text_map[self._lang.value] | ||
return self._data is not None | ||
|
||
|
||
class CharacterData(AssetData): | ||
async def load(self) -> bool: | ||
self._data = await self._open_json(CHARACTER_DATA_PATH) | ||
return self._data is not None | ||
|
||
|
||
class SkillTreeData(AssetData): | ||
async def load(self) -> bool: | ||
self._data = await self._open_json(SKILL_TREE_DATA_PATH) | ||
return self._data is not None | ||
|
||
|
||
class LightConesData(AssetData): | ||
async def load(self) -> bool: | ||
self._data = await self._open_json(LIGHT_CONE_DATA_PATH) | ||
return self._data is not None | ||
|
||
|
||
class RelicData(AssetData): | ||
async def load(self) -> bool: | ||
self._data = await self._open_json(RELIC_DATA_PATH) | ||
return self._data is not None | ||
|
||
|
||
class MetaData(AssetData): | ||
async def load(self) -> bool: | ||
self._data = await self._open_json(META_DATA_PATH) | ||
return self._data is not None | ||
|
||
|
||
class AvatarData(AssetData): | ||
async def load(self) -> bool: | ||
self._data = await self._open_json(AVATAR_DATA_PATH) | ||
return self._data is not None | ||
|
||
|
||
class PropertyConfigData(AssetData): | ||
async def load(self) -> bool: | ||
self._data = await self._open_json(PROPERTY_CONFIG_PATH) | ||
return self._data is not None |
Oops, something went wrong.