diff --git a/enkanetwork/__init__.py b/enkanetwork/__init__.py index c46eac9..6498fc9 100644 --- a/enkanetwork/__init__.py +++ b/enkanetwork/__init__.py @@ -1,8 +1,8 @@ -from .client import * -from .exception import * -from .model import * -from .utils import * -from .info import * +from .client import * # noqa: F403 +from .exception import * # noqa: F403 +from .model import * # noqa: F403 +from .utils import * # noqa: F403 +from .info import * # noqa: F403 -__VERSION__ = VERSION -__AUTHOR__ = AUTHOR \ No newline at end of file +__VERSION__ = VERSION # noqa: F405 +__AUTHOR__ = AUTHOR # noqa: F405 diff --git a/enkanetwork/assets.py b/enkanetwork/assets.py index 979e34b..836f682 100644 --- a/enkanetwork/assets.py +++ b/enkanetwork/assets.py @@ -13,14 +13,10 @@ PATH = os.path.dirname(os.path.abspath(__file__)) LOGGER = logging.getLogger(__name__) + class Assets: - # Characters & Skills DATA: Dict[str, dict] = {} - - # Hash Map HASH_MAP: Dict[str, dict] = {} - - # Language LANGS: Language = Language.EN def __init__(self, lang: Language = Language.EN) -> None: @@ -49,7 +45,7 @@ class Assets: }) @classmethod - def constellations(cls, id: int) -> Union[assets.CharacterConstellationsAsset, None]: + def constellations(cls, id: int) -> Union[assets.CharacterConstellationsAsset, None]: # noqa: E501 LOGGER.debug(f"Getting character constellations assets with id: {id}") data = cls.DATA["constellations"].get(str(id)) if not data: @@ -68,7 +64,7 @@ class Assets: data = cls.DATA["skills"].get(str(id)) if not data: LOGGER.error(f"Character skills not found with id: {id}") - return + return return assets.CharacterSkillAsset.parse_obj({ "id": id, @@ -94,14 +90,14 @@ class Assets: @classmethod def get_hash_map(cls, hash_id: str) -> Union[str, None]: - LOGGER.debug(f"Getting nameTextMapHash {hash_id} with language: {cls.LANGS}") + LOGGER.debug(f"Getting nameTextMapHash {hash_id} with language: {cls.LANGS}") # noqa: E501 for key in cls.HASH_MAP: if str(hash_id) in cls.HASH_MAP[key]: val = cls.HASH_MAP[key][str(hash_id)][cls.LANGS] - LOGGER.debug(f"Got nameTextMapHash {hash_id} with language: {key} (Value '{val}')") + LOGGER.debug(f"Got nameTextMapHash {hash_id} with language: {key} (Value '{val}')") # noqa: E501 return val - LOGGER.error(f"nameTextMapHash {hash_id} not found with language: {cls.LANGS}") + LOGGER.error(f"nameTextMapHash {hash_id} not found with language: {cls.LANGS}") # noqa: E501 return @classmethod @@ -117,7 +113,7 @@ class Assets: return assets.CharacterIconAsset( icon=create_ui_path(path.replace("_Side", "")), side=create_ui_path(path), - banner=create_ui_path(path.replace("AvatarIcon_Side", "Gacha_AvatarImg")) + banner=create_ui_path(path.replace("AvatarIcon_Side", "Gacha_AvatarImg")) # noqa: E501 ) @staticmethod @@ -128,7 +124,7 @@ class Assets: def _set_language(cls, lang: Language) -> None: # Check language if not lang.split("-")[0].lower() in list(Language): - raise ValueError("Language not supported. Please check your language.") + raise ValueError("Language not supported. Please check your language.") # noqa: E501 LOGGER.debug(f"Set language to {lang}.") cls.LANGS = lang.upper() @@ -146,7 +142,7 @@ class Assets: FILE_LANG = os.listdir(_PATH) for FILENAME in FILE_LANG: LOGGER.debug(f"Loading language file {FILENAME}...") - cls.HASH_MAP[FILENAME.split(".")[0]] = json.load(cls.__load(os.path.join(_PATH, FILENAME))) + cls.HASH_MAP[FILENAME.split(".")[0]] = json.load(cls.__load(os.path.join(_PATH, FILENAME))) # noqa: E501 @classmethod def __load_assets_data(cls) -> None: @@ -154,7 +150,7 @@ class Assets: FILE_DATA = os.listdir(_PATH) for FILENAME in FILE_DATA: LOGGER.debug(f"Loading data file {FILENAME}...") - cls.DATA[FILENAME.split(".")[0]] = json.load(cls.__load(os.path.join(_PATH, FILENAME))) - + cls.DATA[FILENAME.split(".")[0]] = json.load(cls.__load(os.path.join(_PATH, FILENAME))) # noqa: E501 + def __load(path: str) -> TextIOWrapper: return open(path, "r", encoding="utf-8") diff --git a/enkanetwork/client.py b/enkanetwork/client.py index 6b3aff7..1010229 100644 --- a/enkanetwork/client.py +++ b/enkanetwork/client.py @@ -10,16 +10,15 @@ from .assets import Assets from .utils import create_path, validate_uid, request from .enum import Language + class EnkaNetworkAPI: LOGGER = logging.getLogger(__name__) + RAWDATA = "https://raw.githubusercontent.com/mrwan200/enkanetwork.py-data/{PATH}" # noqa: E501 - # JSON Data & Language - RAWDATA = "https://raw.githubusercontent.com/mrwan200/enkanetwork.py-data/{PATH}" - - def __init__(self, lang: str = "en", debug: bool = False, key: str = "") -> None: + def __init__(self, lang: str = "en", debug: bool = False, key: str = "") -> None: # noqa: E501 # Logging logging.basicConfig() - logging.getLogger("enkanetwork").setLevel(logging.DEBUG if debug else logging.ERROR) + logging.getLogger("enkanetwork").setLevel(logging.DEBUG if debug else logging.ERROR) # noqa: E501 # Set language and load config self.assets = Assets(lang) @@ -41,11 +40,11 @@ class EnkaNetworkAPI: async def fetch_user(self, uid: Union[str, int]) -> EnkaNetworkResponse: self.LOGGER.debug(f"Validating with UID {uid}...") if not validate_uid(str(uid)): - raise VaildateUIDError("Validate UID failed. Please check your UID.") - + raise VaildateUIDError("Validate UID failed. Please check your UID.") # noqa: E501 + self.LOGGER.debug(f"Fetching user with UID {uid}...") - resp = await request(url=create_path(f"u/{uid}/__data.json" + ("?key={key}" if self.__key else ""))) + resp = await request(url=create_path(f"u/{uid}/__data.json" + ("?key={key}" if self.__key else ""))) # noqa: E501 # Check if status code is not 200 (Ex. 500) if resp["status"] != 200: @@ -53,7 +52,7 @@ class EnkaNetworkAPI: # Parse JSON data data = resp["content"] - + if not data: raise UIDNotFounded(f"UID {uid} not found.") @@ -71,12 +70,12 @@ class EnkaNetworkAPI: for filename in os.listdir(_PATH[folder]): self.LOGGER.debug(f"Downloading {folder} file {filename}...") _json = await request( - url=self.RAWDATA.format(PATH=f"master/exports/{folder}/{filename}") + url=self.RAWDATA.format(PATH=f"master/exports/{folder}/{filename}") # noqa: E501 ) self.LOGGER.debug(f"Writing {folder} file {filename}...") - with open(os.path.join(_PATH[folder], filename), "w", encoding="utf-8") as f: - json.dump(_json["content"], f, ensure_ascii=False, indent=4) + with open(os.path.join(_PATH[folder], filename), "w", encoding="utf-8") as f: # noqa: E501 + json.dump(_json["content"], f, ensure_ascii=False, indent=4) # noqa: E501 # Reload config - self.assets.reload_assets() \ No newline at end of file + self.assets.reload_assets() diff --git a/enkanetwork/enum.py b/enkanetwork/enum.py index b9a0a5d..eeb9e4f 100644 --- a/enkanetwork/enum.py +++ b/enkanetwork/enum.py @@ -1,9 +1,10 @@ from enum import Enum + class Language(str, Enum): EN = "en" - RU = "ru" - VI = "vi" + RU = "ru" + VI = "vi" TH = "th" PT = "pt" KR = "kr" @@ -12,7 +13,7 @@ class Language(str, Enum): FR = "fr" ES = "es" DE = "de" - + """ zh-CN: CHT zh-TW: CHS @@ -22,15 +23,18 @@ class Language(str, Enum): CHT = "cht" CHS = "chs" + class EquipmentsType(int, Enum): UNKNOWN = -1 ARTIFACT = 0 WEAPON = 1 + class DigitType(int, Enum): NUMBER = 0 PERCENT = 1 - + + class ElementType(str, Enum): Unknown = "Unknown" Cryo = "Ice" @@ -40,10 +44,11 @@ class ElementType(str, Enum): Geo = "Rock" Electro = "Electric" + class EquipType(str, Enum): Unknown = "UNKNOWN" Flower = "EQUIP_BRACER" Feather = "EQUIP_NECKLACE" Sands = "EQUIP_SHOES" Goblet = "EQUIP_RING" - Circlet = "EQUIP_DRESS" \ No newline at end of file + Circlet = "EQUIP_DRESS" diff --git a/enkanetwork/exception.py b/enkanetwork/exception.py index 4f459e9..9c451d3 100644 --- a/enkanetwork/exception.py +++ b/enkanetwork/exception.py @@ -1,5 +1,6 @@ class VaildateUIDError(Exception): pass + class UIDNotFounded(Exception): - pass \ No newline at end of file + pass diff --git a/enkanetwork/info.py b/enkanetwork/info.py index 383a431..ac8b5c8 100644 --- a/enkanetwork/info.py +++ b/enkanetwork/info.py @@ -1,2 +1,2 @@ VERSION = "1.2.9dev2" -AUTHOR = "M-307" \ No newline at end of file +AUTHOR = "M-307" diff --git a/enkanetwork/model/__init__.py b/enkanetwork/model/__init__.py index 98b15ae..2927633 100644 --- a/enkanetwork/model/__init__.py +++ b/enkanetwork/model/__init__.py @@ -4,7 +4,8 @@ from typing import List from .players import PlayerInfo from .character import CharacterInfo + class EnkaNetworkResponse(BaseModel): player: PlayerInfo = Field(None, alias="playerInfo") characters: List[CharacterInfo] = Field(None, alias="avatarInfoList") - ttl: int = 0 \ No newline at end of file + ttl: int = 0 diff --git a/enkanetwork/model/assets.py b/enkanetwork/model/assets.py index d59dc7c..0027f65 100644 --- a/enkanetwork/model/assets.py +++ b/enkanetwork/model/assets.py @@ -3,6 +3,7 @@ from typing import List, Any from ..enum import ElementType + class NamecardAsset(BaseModel): id: int = 0 hash_id: str = Field("", alias="nameTextMapHash") @@ -10,25 +11,24 @@ class NamecardAsset(BaseModel): banner: str = "" navbar: str = "" + class CharacterIconAsset(BaseModel): icon: str = "" side: str = "" banner: str = "" + class CharacterSkillAsset(BaseModel): id: int = 0 hash_id: str = Field("", alias="nameTextMapHash") icon: str = Field(None, alias="skillIcon") + class CharacterConstellationsAsset(BaseModel): id: int = 0 hash_id: str = Field("", alias="nameTextMapHash") icon: str = Field(None, alias="icon") -class CharacterSkillAsset(BaseModel): - id: int = 0 - hash_id: str = Field("", alias="nameTextMapHash") - icon: str = Field(None, alias="skillIcon") class CharacterAsset(BaseModel): id: int = 0 @@ -44,4 +44,4 @@ class CharacterAsset(BaseModel): def __init__(__pydantic_self__, **data: Any) -> None: super().__init__(**data) - __pydantic_self__.element = ElementType(data["costElemType"]) if data["costElemType"] != "" else ElementType.Unknown.name + __pydantic_self__.element = ElementType(data["costElemType"]) if data["costElemType"] != "" else ElementType.Unknown.name # noqa: E501 diff --git a/enkanetwork/model/character.py b/enkanetwork/model/character.py index 5042190..4969b47 100644 --- a/enkanetwork/model/character.py +++ b/enkanetwork/model/character.py @@ -13,17 +13,20 @@ from ..enum import ElementType LOGGER = logging.getLogger(__name__) + class CharacterSkill(BaseModel): id: int = 0 name: str = "" icon: str = "" level: int = 0 + class CharacterConstellations(BaseModel): id: int = 0 - name: str = "" + name: str = "" icon: str = "" - unlocked: bool = False # If character has this constellation. + unlocked: bool = False # If character has this constellation. + class CharacterInfo(BaseModel): """ @@ -38,7 +41,7 @@ class CharacterInfo(BaseModel): """ Custom data """ - name: str = "" # Get from name hash map + name: str = "" # Get from name hash map friendship_level: int = 1 element: ElementType = ElementType.Unknown image: CharacterIconAsset = CharacterIconAsset() @@ -46,33 +49,38 @@ class CharacterInfo(BaseModel): constellations: List[CharacterConstellations] = [] # Prop Maps - xp: int = 0 # AKA. propMap 1001 - ascension: int = 0 # AKA. propMap 4001 - level: int = 0 # AKA. propMap 1002 + xp: int = 0 # AKA. propMap 1001 + ascension: int = 0 # AKA. propMap 4001 + level: int = 0 # AKA. propMap 1002 # Other max_level: int = 20 - constellations_unlocked: int = 0 # Constellation is unlocked count + constellations_unlocked: int = 0 # Constellation is unlocked count def __init__(__pydantic_self__, **data: Any) -> None: super().__init__(**data) - + # Friendship level __pydantic_self__.friendship_level = data["fetterInfo"]["expLevel"] # Get prop map - __pydantic_self__.xp = int(data["propMap"]["1001"]["ival"]) if "1001" in data["propMap"] else 0 - __pydantic_self__.ascension = int(data["propMap"]["1002"]["ival"]) if "1002" in data["propMap"] else 0 - __pydantic_self__.level = int(data["propMap"]["4001"]["ival"]) if "4001" in data["propMap"] else 0 + __pydantic_self__.xp = int( + data["propMap"]["1001"]["ival"]) if "1001" in data["propMap"] else 0 # noqa: E501 + __pydantic_self__.ascension = int( + data["propMap"]["1002"]["ival"]) if "1002" in data["propMap"] else 0 # noqa: E501 + __pydantic_self__.level = int( + data["propMap"]["4001"]["ival"]) if "4001" in data["propMap"] else 0 # noqa: E501 # Constellation unlocked count - __pydantic_self__.constellations_unlocked = len(data["talentIdList"]) if "talentIdList" in data else 0 + __pydantic_self__.constellations_unlocked = len( + data["talentIdList"]) if "talentIdList" in data else 0 # Get max character level - __pydantic_self__.max_level = (__pydantic_self__.ascension * 10) + (10 if __pydantic_self__.ascension > 0 else 0) + 20 + __pydantic_self__.max_level = ( + __pydantic_self__.ascension * 10) + (10 if __pydantic_self__.ascension > 0 else 0) + 20 # noqa: E501 # Get character - LOGGER.debug(f"=== Character Data ===") + LOGGER.debug("=== Character Data ===") character = Assets.character(str(data["avatarId"])) # Check if character is founded @@ -84,9 +92,9 @@ class CharacterInfo(BaseModel): # Get element __pydantic_self__.element = ElementType(character.element).name - + # Load constellation - LOGGER.debug(f"=== Constellation ===") + LOGGER.debug("=== Constellation ===") for constellation in character.constellations: _constellation = Assets.constellations(constellation) if not _constellation: @@ -102,11 +110,12 @@ class CharacterInfo(BaseModel): id=int(constellation), name=_name, icon=_constellation.icon, - unlocked=int(constellation) in data["talentIdList"] if "talentIdList" in data else False + unlocked=int( + constellation) in data["talentIdList"] if "talentIdList" in data else False # noqa: E501 )) - - # Load skills - LOGGER.debug(f"=== Skills ===") + + # Load skills + LOGGER.debug("=== Skills ===") for skill in character.skills: _skill = Assets.skills(skill) @@ -126,7 +135,7 @@ class CharacterInfo(BaseModel): level=data["skillLevelMap"].get(str(skill), 0) )) - LOGGER.debug(f"=== Character Name ===") + LOGGER.debug("=== Character Name ===") _name = Assets.get_hash_map(str(character.hash_id)) if _name is None: @@ -134,6 +143,6 @@ class CharacterInfo(BaseModel): # Get name from hash map __pydantic_self__.name = _name - + class Config: - use_enum_values = True \ No newline at end of file + use_enum_values = True diff --git a/enkanetwork/model/equipments.py b/enkanetwork/model/equipments.py index 51b219c..ccf8778 100644 --- a/enkanetwork/model/equipments.py +++ b/enkanetwork/model/equipments.py @@ -9,6 +9,7 @@ from ..utils import create_ui_path LOGGER = logging.getLogger(__name__) + class EquipmentsStats(BaseModel): prop_id: str = "" type: DigitType = DigitType.NUMBER @@ -23,7 +24,7 @@ class EquipmentsStats(BaseModel): __pydantic_self__.value = data["statValue"] - LOGGER.debug(f"=== Fight prop ===") + LOGGER.debug("=== Fight prop ===") if "mainPropId" in data: __pydantic_self__.prop_id = str(data["mainPropId"]) @@ -37,14 +38,15 @@ class EquipmentsStats(BaseModel): __pydantic_self__.name = fight_prop + class EquipmentsDetail(BaseModel): """ Custom data """ - name: str = "" # Get from name hash map - artifact_name_set: str = "" # Name set artifacts - artifact_type: EquipType = EquipType.Unknown # Type of artifact - icon: str = "" + name: str = "" # Get from name hash map + artifact_name_set: str = "" # Name set artifacts + artifact_type: EquipType = EquipType.Unknown # Type of artifact + icon: str = "" rarity: int = Field(0, alias="rankLevel") mainstats: EquipmentsStats = Field(None, alias="reliquaryMainstat") substats: List[EquipmentsStats] = [] @@ -52,34 +54,38 @@ class EquipmentsDetail(BaseModel): def __init__(__pydantic_self__, **data: Any) -> None: super().__init__(**data) - if data["itemType"] == "ITEM_RELIQUARY": # AKA. Artifact - LOGGER.debug(f"=== Artifact ===") + if data["itemType"] == "ITEM_RELIQUARY": # AKA. Artifact + LOGGER.debug("=== Artifact ===") __pydantic_self__.icon = Assets.create_icon_path(data["icon"]) __pydantic_self__.artifact_type = EquipType(data["equipType"]).name # Sub Stats for stats in data["reliquarySubstats"]: - __pydantic_self__.substats.append(EquipmentsStats.parse_obj(stats)) + __pydantic_self__.substats.append( + EquipmentsStats.parse_obj(stats)) - if data["itemType"] == "ITEM_WEAPON": # AKA. Weapon - LOGGER.debug(f"=== Weapon ===") + if data["itemType"] == "ITEM_WEAPON": # AKA. Weapon + LOGGER.debug("=== Weapon ===") __pydantic_self__.icon = create_ui_path(data["icon"]) # Main and Sub Stats - __pydantic_self__.mainstats = EquipmentsStats.parse_obj(data["weaponStats"][0]) + __pydantic_self__.mainstats = EquipmentsStats.parse_obj( + data["weaponStats"][0]) for stats in data["weaponStats"][1:]: - __pydantic_self__.substats.append(EquipmentsStats.parse_obj(stats)) + __pydantic_self__.substats.append( + EquipmentsStats.parse_obj(stats)) _name = Assets.get_hash_map(str(data["nameTextMapHash"])) if "setNameTextMapHash" in data: - _artifact_name_set = Assets.get_hash_map(str(data["setNameTextMapHash"])) + _artifact_name_set = Assets.get_hash_map( + str(data["setNameTextMapHash"])) __pydantic_self__.artifact_name_set = _artifact_name_set or "" - - __pydantic_self__.name = _name if not _name is None else "" - + + __pydantic_self__.name = _name if _name is not None else "" class Config: use_enum_values = True + class Equipments(BaseModel): """ API Response data @@ -90,10 +96,11 @@ class Equipments(BaseModel): """ Custom data """ - level: int = 0 # Get form key "reliquary" and "weapon" - type: EquipmentsType = EquipmentsType.UNKNOWN # Type of equipments (Ex. Artifact, Weapon) - refinement: int = 0 # Refinement of equipments (Weapon only) - ascension: int = 0 # Ascension (Weapon only) + level: int = 0 # Get form key "reliquary" and "weapon" + # Type of equipments (Ex. Artifact, Weapon) + type: EquipmentsType = EquipmentsType.UNKNOWN + refinement: int = 0 # Refinement of equipments (Weapon only) + ascension: int = 0 # Ascension (Weapon only) class Config: use_enum_values = True @@ -101,14 +108,15 @@ class Equipments(BaseModel): def __init__(__pydantic_self__, **data: Any) -> None: super().__init__(**data) - if data["flat"]["itemType"] == "ITEM_RELIQUARY": # AKA. Artifact + if data["flat"]["itemType"] == "ITEM_RELIQUARY": # AKA. Artifact __pydantic_self__.type = EquipmentsType.ARTIFACT __pydantic_self__.level = data["reliquary"]["level"] - 1 - - if data["flat"]["itemType"] == "ITEM_WEAPON": # AKA. Weapon + + if data["flat"]["itemType"] == "ITEM_WEAPON": # AKA. Weapon __pydantic_self__.type = EquipmentsType.WEAPON __pydantic_self__.level = data["weapon"]["level"] if "affixMap" in data["weapon"]: - __pydantic_self__.refinement = data["weapon"]["affixMap"][list(data["weapon"]["affixMap"].keys())[0]] + 1 + __pydantic_self__.refinement = data["weapon"]["affixMap"][list( + data["weapon"]["affixMap"].keys())[0]] + 1 if "promoteLevel" in data["weapon"]: __pydantic_self__.ascension = data["weapon"]["promoteLevel"] diff --git a/enkanetwork/model/players.py b/enkanetwork/model/players.py index de481e6..53e00f1 100644 --- a/enkanetwork/model/players.py +++ b/enkanetwork/model/players.py @@ -4,9 +4,10 @@ from pydantic import BaseModel, Field from typing import List, Any from ..assets import Assets -from ..utils import create_ui_path LOGGER = logging.getLogger(__name__) + + class ProfilePicture(BaseModel): """ API Response data @@ -22,14 +23,15 @@ class ProfilePicture(BaseModel): super().__init__(**data) # Get character - LOGGER.debug(f"=== Avatar ===") + LOGGER.debug("=== Avatar ===") icon = Assets.character_icon(str(data["avatarId"])) if not icon: return - + __pydantic_self__.url = icon.icon + class showAvatar(BaseModel): """ API Response data @@ -47,7 +49,7 @@ class showAvatar(BaseModel): super().__init__(**data) # Get character - LOGGER.debug(f"=== Character preview ===") + LOGGER.debug("=== Character preview ===") character_preview = Assets.character(str(data["avatarId"])) if not character_preview: @@ -59,10 +61,10 @@ class showAvatar(BaseModel): _name = Assets.get_hash_map(str(character_preview.hash_id)) if _name is None: - return + return __pydantic_self__.name = _name - + class Namecard(BaseModel): id: int = 0 @@ -75,7 +77,7 @@ class Namecard(BaseModel): super().__init__(**data) if __pydantic_self__.id > 0: - LOGGER.debug(f"=== Namecard ===") + LOGGER.debug("=== Namecard ===") # Get name card namecard = Assets.namecards(str(__pydantic_self__.id)) @@ -88,10 +90,11 @@ class Namecard(BaseModel): _name = Assets.get_hash_map(str(namecard.hash_id)) if _name is None: - return + return __pydantic_self__.name = _name + class PlayerInfo(BaseModel): """ API Response data @@ -104,7 +107,8 @@ class PlayerInfo(BaseModel): world_level: int = Field(1, alias="worldLevel") icon: ProfilePicture = Field(None, alias="profilePicture") # Avatars - characters_preview: List[showAvatar] = Field([], alias="showAvatarInfoList") + characters_preview: List[showAvatar] = Field( + [], alias="showAvatarInfoList") # Abyss floor abyss_floor: int = Field(0, alias="towerFloorIndex") abyss_room: int = Field(0, alias="towerLevelIndex") @@ -112,11 +116,12 @@ class PlayerInfo(BaseModel): """ Custom data """ - namecard: Namecard = Namecard() # Profile namecard - namecards: List[Namecard] = [] # List namecard preview in profile + namecard: Namecard = Namecard() # Profile namecard + namecards: List[Namecard] = [] # List namecard preview in profile def __init__(__pydantic_self__, **data: Any) -> None: super().__init__(**data) - + __pydantic_self__.namecard = Namecard(id=data["nameCardId"]) - __pydantic_self__.namecards = [Namecard(id=namecard) for namecard in (data["showNameCardIdList"])] if "showNameCardIdList" in data else [] \ No newline at end of file + __pydantic_self__.namecards = [Namecard(id=namecard) for namecard in ( + data["showNameCardIdList"])] if "showNameCardIdList" in data else [] # noqa: E501 diff --git a/enkanetwork/model/stats.py b/enkanetwork/model/stats.py index 5be1a97..9c792c8 100644 --- a/enkanetwork/model/stats.py +++ b/enkanetwork/model/stats.py @@ -4,6 +4,7 @@ from pydantic import BaseModel from typing import Any + class Stats(BaseModel): id: int = 0 value: float = 0 @@ -11,6 +12,7 @@ class Stats(BaseModel): def to_rounded(self) -> float: return math.ceil(self.value) + class StatsPercentage(BaseModel): id: int = 0 value: float = 0.0 @@ -21,6 +23,7 @@ class StatsPercentage(BaseModel): def to_percentage_symbol(self) -> str: return f"{self.to_percentage()}%" + class CharacterStats(BaseModel): BASE_HP: Stats = Stats(id=1, value=0) FIGHT_PROP_HP: Stats = Stats(id=2, value=0) @@ -30,7 +33,7 @@ class CharacterStats(BaseModel): FIGHT_PROP_ATTACK_PERCENT: StatsPercentage = StatsPercentage(id=6, value=0) FIGHT_PROP_BASE_DEFENSE: Stats = Stats(id=7, value=0) FIGHT_PROP_DEFENSE: Stats = Stats(id=8, value=0) - FIGHT_PROP_DEFENSE_PERCENT: StatsPercentage = StatsPercentage(id=9, value=0) + FIGHT_PROP_DEFENSE_PERCENT: StatsPercentage = StatsPercentage(id=9, value=0) # noqa: E501 FIGHT_PROP_BASE_SPEED: Stats = Stats(id=10, value=0) FIGHT_PROP_SPEED_PERCENT: StatsPercentage = StatsPercentage(id=11, value=0) FIGHT_PROP_HP_MP_PERCENT: StatsPercentage = StatsPercentage(id=12, value=0) @@ -38,28 +41,28 @@ class CharacterStats(BaseModel): FIGHT_PROP_CRITICAL: StatsPercentage = StatsPercentage(id=20, value=0) FIGHT_PROP_ANTI_CRITICAL: StatsPercentage = StatsPercentage(id=21, value=0) FIGHT_PROP_CRITICAL_HURT: StatsPercentage = StatsPercentage(id=22, value=0) - FIGHT_PROP_CHARGE_EFFICIENCY: StatsPercentage = StatsPercentage(id=23, value=0) + FIGHT_PROP_CHARGE_EFFICIENCY: StatsPercentage = StatsPercentage(id=23, value=0) # noqa: E501 FIGHT_PROP_ADD_HURT: StatsPercentage = StatsPercentage(id=24, value=0) FIGHT_PROP_SUB_HURT: StatsPercentage = StatsPercentage(id=25, value=0) FIGHT_PROP_HEAL_ADD: StatsPercentage = StatsPercentage(id=26, value=0) FIGHT_PROP_HEALED_ADD: StatsPercentage = StatsPercentage(id=27, value=0) FIGHT_PROP_ELEMENT_MASTERY: Stats = Stats(id=28, value=0) - FIGHT_PROP_PHYSICAL_SUB_HURT: StatsPercentage = StatsPercentage(id=29, value=0) - FIGHT_PROP_PHYSICAL_ADD_HURT: StatsPercentage = StatsPercentage(id=30, value=0) + FIGHT_PROP_PHYSICAL_SUB_HURT: StatsPercentage = StatsPercentage(id=29, value=0) # noqa: E501 + FIGHT_PROP_PHYSICAL_ADD_HURT: StatsPercentage = StatsPercentage(id=30, value=0) # noqa: E501 FIGHT_PROP_DEFENCE_IGNORE_RATIO: Stats = Stats(id=31, value=0) FIGHT_PROP_DEFENCE_IGNORE_DELTA: Stats = Stats(id=32, value=0) FIGHT_PROP_FIRE_ADD_HURT: StatsPercentage = StatsPercentage(id=40, value=0) FIGHT_PROP_ELEC_ADD_HURT: StatsPercentage = StatsPercentage(id=41, value=0) - FIGHT_PROP_WATER_ADD_HURT: StatsPercentage = StatsPercentage(id=42, value=0) - FIGHT_PROP_GRASS_ADD_HURT: StatsPercentage = StatsPercentage(id=43, value=0) + FIGHT_PROP_WATER_ADD_HURT: StatsPercentage = StatsPercentage(id=42, value=0) # noqa: E501 + FIGHT_PROP_GRASS_ADD_HURT: StatsPercentage = StatsPercentage(id=43, value=0) # noqa: E501 FIGHT_PROP_WIND_ADD_HURT: StatsPercentage = StatsPercentage(id=44, value=0) FIGHT_PROP_ROCK_ADD_HURT: StatsPercentage = StatsPercentage(id=45, value=0) - FIGHT_PROP_ICE_ADD_HURT: StatsPercentage = StatsPercentage(id=46, value=0) - FIGHT_PROP_HIT_HEAD_ADD_HURT: StatsPercentage = StatsPercentage(id=47, value=0) + FIGHT_PROP_ICE_ADD_HURT: StatsPercentage = StatsPercentage(id=46, value=0) # noqa: E501 + FIGHT_PROP_HIT_HEAD_ADD_HURT: StatsPercentage = StatsPercentage(id=47, value=0) # noqa: E501 FIGHT_PROP_FIRE_SUB_HURT: StatsPercentage = StatsPercentage(id=50, value=0) FIGHT_PROP_ELEC_SUB_HURT: StatsPercentage = StatsPercentage(id=51, value=0) - FIGHT_PROP_WATER_SUB_HURT: StatsPercentage = StatsPercentage(id=52, value=0) - FIGHT_PROP_GRASS_SUB_HURT: StatsPercentage = StatsPercentage(id=53, value=0) + FIGHT_PROP_WATER_SUB_HURT: StatsPercentage = StatsPercentage(id=52, value=0) # noqa: E501 + FIGHT_PROP_GRASS_SUB_HURT: StatsPercentage = StatsPercentage(id=53, value=0) # noqa: E501 FIGHT_PROP_WIND_SUB_HURT: StatsPercentage = StatsPercentage(id=54, value=0) FIGHT_PROP_ROCK_SUB_HURT: StatsPercentage = StatsPercentage(id=55, value=0) FIGHT_PROP_ICE_SUB_HURT: StatsPercentage = StatsPercentage(id=56, value=0) @@ -80,7 +83,7 @@ class CharacterStats(BaseModel): FIGHT_PROP_MAX_ROCK_ENERGY: Stats = Stats(id=76, value=0) FIGHT_PROP_SKILL_CD_MINUS_RATIO: Stats = Stats(id=80, value=0) FIGHT_PROP_SHIELD_COST_MINUS_RATIO: Stats = Stats(id=81, value=0) - + FIGHT_PROP_CUR_FIRE_ENERGY: Stats = Stats(id=1000, value=0) FIGHT_PROP_CUR_ELEC_ENERGY: Stats = Stats(id=1001, value=0) FIGHT_PROP_CUR_WATER_ENERGY: Stats = Stats(id=1002, value=0) @@ -95,35 +98,35 @@ class CharacterStats(BaseModel): FIGHT_PROP_CUR_DEFENSE: Stats = Stats(id=2002, value=0) FIGHT_PROP_CUR_SPEED: Stats = Stats(id=2003, value=0) - FIGHT_PROP_NONEXTRA_ATTACK: Stats = Stats(id=3000, value=0) + FIGHT_PROP_NONEXTRA_ATTACK: Stats = Stats(id=3000, value=0) # noqa: E501 FIGHT_PROP_NONEXTRA_DEFENSE: Stats = Stats(id=3001, value=0) - FIGHT_PROP_NONEXTRA_CRITICAL: StatsPercentage = StatsPercentage(id=3002, value=0) + FIGHT_PROP_NONEXTRA_CRITICAL: StatsPercentage = StatsPercentage(id=3002, value=0) # noqa: E501 FIGHT_PROP_CUR_SPEED: Stats = Stats(id=3003, value=0) - FIGHT_PROP_NONEXTRA_CRITICAL_HURT: StatsPercentage = StatsPercentage(id=3004, value=0) - FIGHT_PROP_NONEXTRA_CHARGE_EFFICIENCY: StatsPercentage = StatsPercentage(id=3005, value=0) + FIGHT_PROP_NONEXTRA_CRITICAL_HURT: StatsPercentage = StatsPercentage(id=3004, value=0) # noqa: E501 + FIGHT_PROP_NONEXTRA_CHARGE_EFFICIENCY: StatsPercentage = StatsPercentage(id=3005, value=0) # noqa: E501 FIGHT_PROP_NONEXTRA_ELEMENT_MASTERY: Stats = Stats(id=3006, value=0) - FIGHT_PROP_NONEXTRA_PHYSICAL_SUB_HURT: StatsPercentage = StatsPercentage(id=3007, value=0) - FIGHT_PROP_NONEXTRA_FIRE_ADD_HURT: StatsPercentage = StatsPercentage(id=3008, value=0) - FIGHT_PROP_NONEXTRA_ELEC_ADD_HURT: StatsPercentage = StatsPercentage(id=3009, value=0) - FIGHT_PROP_NONEXTRA_WATER_ADD_HURT: StatsPercentage = StatsPercentage(id=3010, value=0) - FIGHT_PROP_NONEXTRA_GRASS_ADD_HURT: StatsPercentage = StatsPercentage(id=3011, value=0) - FIGHT_PROP_NONEXTRA_WIND_ADD_HURT: StatsPercentage = StatsPercentage(id=3012, value=0) - FIGHT_PROP_NONEXTRA_ROCK_ADD_HURT: StatsPercentage = StatsPercentage(id=3013, value=0) - FIGHT_PROP_NONEXTRA_ICE_ADD_HURT: StatsPercentage = StatsPercentage(id=3014, value=0) - FIGHT_PROP_NONEXTRA_FIRE_SUB_HURT: StatsPercentage = StatsPercentage(id=3015, value=0) - FIGHT_PROP_NONEXTRA_ELEC_SUB_HURT: StatsPercentage = StatsPercentage(id=3016, value=0) - FIGHT_PROP_NONEXTRA_WATER_SUB_HURT: StatsPercentage = StatsPercentage(id=3017, value=0) - FIGHT_PROP_NONEXTRA_GRASS_SUB_HURT: StatsPercentage = StatsPercentage(id=3018, value=0) - FIGHT_PROP_NONEXTRA_WIND_SUB_HURT: StatsPercentage = StatsPercentage(id=3019, value=0) - FIGHT_PROP_NONEXTRA_ROCK_SUB_HURT: StatsPercentage = StatsPercentage(id=3020, value=0) - FIGHT_PROP_NONEXTRA_ICE_SUB_HURT: StatsPercentage = StatsPercentage(id=3021, value=0) + FIGHT_PROP_NONEXTRA_PHYSICAL_SUB_HURT: StatsPercentage = StatsPercentage(id=3007, value=0) # noqa: E501 + FIGHT_PROP_NONEXTRA_FIRE_ADD_HURT: StatsPercentage = StatsPercentage(id=3008, value=0) # noqa: E501 + FIGHT_PROP_NONEXTRA_ELEC_ADD_HURT: StatsPercentage = StatsPercentage(id=3009, value=0) # noqa: E501 + FIGHT_PROP_NONEXTRA_WATER_ADD_HURT: StatsPercentage = StatsPercentage(id=3010, value=0) # noqa: E501 + FIGHT_PROP_NONEXTRA_GRASS_ADD_HURT: StatsPercentage = StatsPercentage(id=3011, value=0) # noqa: E501 + FIGHT_PROP_NONEXTRA_WIND_ADD_HURT: StatsPercentage = StatsPercentage(id=3012, value=0) # noqa: E501 + FIGHT_PROP_NONEXTRA_ROCK_ADD_HURT: StatsPercentage = StatsPercentage(id=3013, value=0) # noqa: E501 + FIGHT_PROP_NONEXTRA_ICE_ADD_HURT: StatsPercentage = StatsPercentage(id=3014, value=0) # noqa: E501 + FIGHT_PROP_NONEXTRA_FIRE_SUB_HURT: StatsPercentage = StatsPercentage(id=3015, value=0) # noqa: E501 + FIGHT_PROP_NONEXTRA_ELEC_SUB_HURT: StatsPercentage = StatsPercentage(id=3016, value=0) # noqa: E501 + FIGHT_PROP_NONEXTRA_WATER_SUB_HURT: StatsPercentage = StatsPercentage(id=3017, value=0) # noqa: E501 + FIGHT_PROP_NONEXTRA_GRASS_SUB_HURT: StatsPercentage = StatsPercentage(id=3018, value=0) # noqa: E501 + FIGHT_PROP_NONEXTRA_WIND_SUB_HURT: StatsPercentage = StatsPercentage(id=3019, value=0) # noqa: E501 + FIGHT_PROP_NONEXTRA_ROCK_SUB_HURT: StatsPercentage = StatsPercentage(id=3020, value=0) # noqa: E501 + FIGHT_PROP_NONEXTRA_ICE_SUB_HURT: StatsPercentage = StatsPercentage(id=3021, value=0) # noqa: E501 FIGHT_PROP_NONEXTRA_SKILL_CD_MINUS_RATIO: Stats = Stats(id=3022, value=0) - FIGHT_PROP_NONEXTRA_SHIELD_COST_MINUS_RATIO: Stats = Stats(id=3023, value=0) - FIGHT_PROP_NONEXTRA_PHYSICAL_ADD_HURT: StatsPercentage = StatsPercentage(id=3024, value=0) + FIGHT_PROP_NONEXTRA_SHIELD_COST_MINUS_RATIO: Stats = Stats(id=3023, value=0) # noqa: E501 + FIGHT_PROP_NONEXTRA_PHYSICAL_ADD_HURT: StatsPercentage = StatsPercentage(id=3024, value=0) # noqa: E501 def __init__(__pydantic_self__, **data: Any) -> None: super().__init__(**data) _stats = __pydantic_self__.__dict__ for key in _stats: - _stats[key].value = data[str(_stats[key].id)] if str(_stats[key].id) in data else 0 \ No newline at end of file + _stats[key].value = data[str(_stats[key].id)] if str(_stats[key].id) in data else 0 # noqa: E501 diff --git a/enkanetwork/utils.py b/enkanetwork/utils.py index 854b159..5881333 100644 --- a/enkanetwork/utils.py +++ b/enkanetwork/utils.py @@ -16,30 +16,35 @@ BASE_URL = "https://enka.network/{PATH}" CHUNK_SIZE = 1024 * 1024 * 1 RETRY_MAX = 10 + def create_path(path: str) -> str: return BASE_URL.format(PATH=path) + def create_ui_path(filename: str) -> str: return create_path(f"ui/{filename}.png") + def validate_uid(uid: str) -> bool: """ Validate UID """ - return len(uid) == 9 and uid.isdigit() and re.match(r"([1,2,5-9])\d{8}", uid) + return len(uid) == 9 and uid.isdigit() and re.match(r"([1,2,5-9])\d{8}", uid) # noqa: E501 + def get_default_header(): - # Get python version - python_version = sys.version_info + # Get python version + python_version = sys.version_info + + return { + "User-Agent": "EnkaNetwork.py/{version} (Python {major}.{minor}.{micro})".format( # noqa: E501 + version=VERSION, + major=python_version.major, + minor=python_version.minor, + micro=python_version.micro + ), + } - return { - "User-Agent": "EnkaNetwork.py/{version} (Python {major}.{minor}.{micro})".format( - version=VERSION, - major=python_version.major, - minor=python_version.minor, - micro=python_version.micro - ), - } async def request(url: str, headers: dict = None) -> dict: _url = url.strip(" ") @@ -49,30 +54,30 @@ async def request(url: str, headers: dict = None) -> dict: retry = 0 async with aiohttp.ClientSession() as session: """ - From https://gist.github.com/foobarna/19c132304e140bf5031c273f6dc27ece + From https://gist.github.com/foobarna/19c132304e140bf5031c273f6dc27ece # noqa: E501 """ while True: - response = await session.request("GET", _url, headers={**get_default_header(), **headers}) + response = await session.request("GET", _url, headers={**get_default_header(), **headers}) # noqa: E501 if response.status >= 400: - LOGGER.warning(f"Failure to fetch {_url} ({response.status}) Retry {retry} / {RETRY_MAX}") + LOGGER.warning(f"Failure to fetch {_url} ({response.status}) Retry {retry} / {RETRY_MAX}") # noqa: E501 retry += 1 if retry > RETRY_MAX: raise Exception(f"Failed to download {url}") await asyncio.sleep(1) continue - - break - + + break + data = bytearray() data_to_read = True while data_to_read: red = 0 while red < CHUNK_SIZE: chunk = await response.content.read(CHUNK_SIZE - red) - + if not chunk: data_to_read = False break @@ -83,4 +88,4 @@ async def request(url: str, headers: dict = None) -> dict: return { "status": response.status, "content": json.loads(data) - } \ No newline at end of file + }