🚧 building...

This commit is contained in:
Karako 2023-04-15 13:09:56 +08:00
parent 191cda9fe1
commit f945711cea
No known key found for this signature in database
GPG Key ID: 5920831B0095D4A0
17 changed files with 914 additions and 2 deletions

2
.gitignore vendored
View File

@ -125,5 +125,5 @@ venv.bak/
.dmypy.json
dmypy.json
# Pyre type checker
# Pyre item_type checker
.pyre/

0
models/__init__.py Normal file
View File

8
models/_base.py Normal file
View File

@ -0,0 +1,8 @@
from humps import camelize
from utils.model import BaseConfig, BaseModel
class DataModel(BaseModel):
class Config(BaseConfig):
alias_generator = lambda x: camelize(x.removesuffix("TextHashMap"))

70
models/avatar.py Normal file
View File

@ -0,0 +1,70 @@
from typing import TYPE_CHECKING
from models.enums import AvatarQuality, WeaponType
from utils.model import BaseModel
if TYPE_CHECKING:
from models.item import Item
class AvatarBirth(BaseModel):
month: int
""""""
day: int
""""""
class AvatarInfo(BaseModel):
title: str
"""称号"""
birth: AvatarBirth
"""生日"""
occupation: str
"""所属"""
vision: str
"""神之眼"""
constellation: str
"""星座"""
description: str
"""描述"""
cn_cv: str
jp_cv: str
en_cv: str
kr_cv: str
class AvatarItem(BaseModel):
item: "Item"
"""物品"""
count: int
"""数量"""
class AvatarPromote(BaseModel):
required_level: int = 0
"""突破所需等级"""
promote_level: int = 0
"""突破等级"""
max_level: int
"""解锁的等级上限"""
coin: int = 0
"""摩拉"""
items: list[AvatarItem]
"""突破所需材料"""
class Avatar(BaseModel):
id: int
"""角色ID"""
name: str
"""名称"""
quality: AvatarQuality
"""品质"""
weapon: WeaponType
"""武器类型"""
information: AvatarInfo
"""角色信息"""
promote: AvatarPromote
"""角色突破数据"""

88
models/enums.py Normal file
View File

@ -0,0 +1,88 @@
from enum import StrEnum
class AvatarQuality(StrEnum):
Orange = "ORANGE"
"""五星"""
Purple = "PURPLE"
"""四星"""
Special = "SPECIAL"
"""特殊"""
class WeaponType(StrEnum):
Sword = "SWORD"
"""单手剑"""
Claymore = "CLAYMORE"
"""双手剑"""
Bow = "BOW"
""""""
Catalyst = "CATALYST"
"""法器"""
Polearm = "POLEARM"
"""长柄武器"""
class Element(StrEnum):
Pyro = "PYRO"
""""""
Hydro = "HYDRO"
""""""
Anemo = "ANEMO"
""""""
Electro = "ELECTRO"
""""""
Dendro = "DENDRO"
""""""
Cryo = "CRYO"
""""""
Geo = "GEO"
""""""
Null = "NULL"
""""""
class PropType(StrEnum):
HP = "HP"
"""生命值"""
HP_P = "HPPercent"
"""生命值百分比"""
Defense = "Defense"
"""防御力"""
Defense_P = "DefensePercent"
"""防御力百分比"""
Attack = "Attack"
"""攻击力"""
Attack_P = "AttackPercent"
"""攻击力百分比"""
Critical = "Critical"
"""暴击率"""
CriticalHurt = "CriticalHurt"
"""暴击伤害"""
Heal = "HealAdd"
"""治疗加成"""
Element = "ElementMastery"
"""元素精通"""
Charge = "ChargeEfficiency"
"""元素充能效率"""
Physical = "PhysicalAddHurt"
"""物理伤害加成"""
Pyro = "PyroAddHurt"
"""火元素伤害加成"""
Hydro = "HydroAddHurt"
"""水元素伤害加成"""
Anemo = "AnemoAddHurt"
"""风元素伤害加成"""
Electro = "ElectroAddHurt"
"""雷元素伤害加成"""
Dendro = "DendroAddHurt"
"""草元素伤害加成"""
Cryo = "CryoAddHurt"
"""冰元素伤害加成"""
Geo = "GeoAddHurt"
"""岩元素伤害加成"""

90
models/item.py Normal file
View File

@ -0,0 +1,90 @@
from enum import StrEnum
from utils.model import BaseModel
class ItemType(StrEnum):
...
class Item(BaseModel):
id: int
"""ID"""
name: str
"""名称"""
family: str
"""种类"""
type: str | None
"""类型"""
icon: str
"""图标名"""
rarity: int | None
"""星级"""
description: str
"""描述"""
special_description: str | None
"""特殊描述"""
class MaterialType(StrEnum):
ADSORBATE = "Adsorbate"
FAKE_ABSORBATE = "Fake_Absorbate"
CONSUME = "消费物"
TALENT = "天赋"
AVATAR = "角色"
CHEST = "宝箱"
NOTICE_ADD_HP = "NOTICE_ADD_HP"
EXCHANGE = "交换物"
WOOD = "木材"
QUEST = "任务"
CRICKET = "蟋蟀"
WIDGET = "Widget"
ELEM_CRYSTAL = "Elem_Crystal"
SPICE_FOOD = "Spice_Food"
ACTIVITY_GEAR = "Activity_Gear"
ACTIVITY_ROBOT = "Activity_Robot"
ACTIVITY_JIGSAW = "Activity_Jigsaw"
FOOD = "Food"
EXP_FRUIT = "Exp_Fruit"
WEAPON_EXP_STONE = "Weapon_Exp_Stone"
AVATAR_MATERIAL = "Avatar_Material"
RELIQUARY_MATERIAL = "Reliquary_Material"
CONSUME_BATCH_USE = "Consume_Batch_Use"
FISH_BAIT = "Fish_Bait"
CHEST_BATCH_USE = "Chest_Batch_Use"
SELECTABLE_CHEST = "Selectable_Chest"
HOME_SEED = "Home_Seed"
FLYCLOAK = "Flycloak"
BGM = "Bgm"
SEA_LAMP = "Sea_Lamp"
CHANNELLER_SLAB_BUFF = "Channeller_Slab_Buff"
FISH_ROD = "Fish_Rod"
NAMECARD = "Namecard"
ARANARA = "Aranara"
DESHRET_MANUAL = "Deshret_Manual"
FIREWORKS = "Fireworks"
COSTUME = "Costume"
FURNITURE_SUITE_FORMULA = "Furniture_Suite_Formula"
FURNITURE_FORMULA = "Furniture_Formula"
class Material(Item):
material_type: MaterialType
"""材料类型"""
class FoodQuality(StrEnum):
STRANGE = "Strange"
"""奇怪的"""
ORDINARY = "Ordinary"
"""普通的"""
DELICIOUS = "Delicious"
"""美味的"""
class Food(Item):
quality: FoodQuality | None
"""食物质量"""
effect: str
"""效果"""

304
poetry.lock generated
View File

@ -15,6 +15,18 @@ files = [
[package.dependencies]
pycares = ">=4.0.0"
[[package]]
name = "aiofiles"
version = "23.1.0"
description = "File support for asyncio."
category = "main"
optional = false
python-versions = ">=3.7,<4.0"
files = [
{file = "aiofiles-23.1.0-py3-none-any.whl", hash = "sha256:9312414ae06472eb6f1d163f555e466a23aed1c8f60c30cccf7121dba2e53eb2"},
{file = "aiofiles-23.1.0.tar.gz", hash = "sha256:edd247df9a19e0db16534d4baaf536d6609a43e1de5401d7a4c1c148753a1635"},
]
[[package]]
name = "aiohttp"
version = "3.8.4"
@ -141,6 +153,45 @@ files = [
[package.dependencies]
frozenlist = ">=1.1.0"
[[package]]
name = "anyio"
version = "3.6.2"
description = "High level compatibility layer for multiple asynchronous event loop implementations"
category = "main"
optional = false
python-versions = ">=3.6.2"
files = [
{file = "anyio-3.6.2-py3-none-any.whl", hash = "sha256:fbbe32bd270d2a2ef3ed1c5d45041250284e31fc0a4df4a5a6071842051a51e3"},
{file = "anyio-3.6.2.tar.gz", hash = "sha256:25ea0d673ae30af41a0c442f81cf3b38c7e79fdc7b60335a4c14e05eb0947421"},
]
[package.dependencies]
idna = ">=2.8"
sniffio = ">=1.1"
[package.extras]
doc = ["packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"]
test = ["contextlib2", "coverage[toml] (>=4.5)", "hypothesis (>=4.0)", "mock (>=4)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (<0.15)", "uvloop (>=0.15)"]
trio = ["trio (>=0.16,<0.22)"]
[[package]]
name = "arko-wrapper"
version = "0.2.8"
description = "给你的Python迭代器加上魔法"
category = "main"
optional = false
python-versions = ">=3.7"
files = [
{file = "arko-wrapper-0.2.8.tar.gz", hash = "sha256:85167bc6f1dd48e3415a23a7f2f193c1544a450fd6d219ce28043af796c9b4c3"},
{file = "arko_wrapper-0.2.8-py3-none-any.whl", hash = "sha256:c56b8cdbbd273cc1b7737667374ee600766e9e7f9f9546871b20912024aa0fb2"},
]
[package.dependencies]
typing-extensions = "*"
[package.extras]
test = ["pytest", "pytest-rerunfailures"]
[[package]]
name = "async-timeout"
version = "4.0.2"
@ -264,6 +315,18 @@ files = [
{file = "Brotli-1.0.9.zip", hash = "sha256:4d1b810aa0ed773f81dceda2cc7b403d01057458730e309856356d4ef4188438"},
]
[[package]]
name = "certifi"
version = "2022.12.7"
description = "Python package for providing Mozilla's CA Bundle."
category = "main"
optional = false
python-versions = ">=3.6"
files = [
{file = "certifi-2022.12.7-py3-none-any.whl", hash = "sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18"},
{file = "certifi-2022.12.7.tar.gz", hash = "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3"},
]
[[package]]
name = "cffi"
version = "1.15.1"
@ -547,6 +610,105 @@ files = [
{file = "frozenlist-1.3.3.tar.gz", hash = "sha256:58bcc55721e8a90b88332d6cd441261ebb22342e238296bb330968952fbb3a6a"},
]
[[package]]
name = "h11"
version = "0.14.0"
description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1"
category = "main"
optional = false
python-versions = ">=3.7"
files = [
{file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"},
{file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"},
]
[[package]]
name = "h2"
version = "4.1.0"
description = "HTTP/2 State-Machine based protocol implementation"
category = "main"
optional = false
python-versions = ">=3.6.1"
files = [
{file = "h2-4.1.0-py3-none-any.whl", hash = "sha256:03a46bcf682256c95b5fd9e9a99c1323584c3eec6440d379b9903d709476bc6d"},
{file = "h2-4.1.0.tar.gz", hash = "sha256:a83aca08fbe7aacb79fec788c9c0bac936343560ed9ec18b82a13a12c28d2abb"},
]
[package.dependencies]
hpack = ">=4.0,<5"
hyperframe = ">=6.0,<7"
[[package]]
name = "hpack"
version = "4.0.0"
description = "Pure-Python HPACK header compression"
category = "main"
optional = false
python-versions = ">=3.6.1"
files = [
{file = "hpack-4.0.0-py3-none-any.whl", hash = "sha256:84a076fad3dc9a9f8063ccb8041ef100867b1878b25ef0ee63847a5d53818a6c"},
{file = "hpack-4.0.0.tar.gz", hash = "sha256:fc41de0c63e687ebffde81187a948221294896f6bdc0ae2312708df339430095"},
]
[[package]]
name = "httpcore"
version = "0.16.3"
description = "A minimal low-level HTTP client."
category = "main"
optional = false
python-versions = ">=3.7"
files = [
{file = "httpcore-0.16.3-py3-none-any.whl", hash = "sha256:da1fb708784a938aa084bde4feb8317056c55037247c787bd7e19eb2c2949dc0"},
{file = "httpcore-0.16.3.tar.gz", hash = "sha256:c5d6f04e2fc530f39e0c077e6a30caa53f1451096120f1f38b954afd0b17c0cb"},
]
[package.dependencies]
anyio = ">=3.0,<5.0"
certifi = "*"
h11 = ">=0.13,<0.15"
sniffio = ">=1.0.0,<2.0.0"
[package.extras]
http2 = ["h2 (>=3,<5)"]
socks = ["socksio (>=1.0.0,<2.0.0)"]
[[package]]
name = "httpx"
version = "0.23.3"
description = "The next generation HTTP client."
category = "main"
optional = false
python-versions = ">=3.7"
files = [
{file = "httpx-0.23.3-py3-none-any.whl", hash = "sha256:a211fcce9b1254ea24f0cd6af9869b3d29aba40154e947d2a07bb499b3e310d6"},
{file = "httpx-0.23.3.tar.gz", hash = "sha256:9818458eb565bb54898ccb9b8b251a28785dd4a55afbc23d0eb410754fe7d0f9"},
]
[package.dependencies]
certifi = "*"
h2 = {version = ">=3,<5", optional = true, markers = "extra == \"http2\""}
httpcore = ">=0.15.0,<0.17.0"
rfc3986 = {version = ">=1.3,<2", extras = ["idna2008"]}
sniffio = "*"
[package.extras]
brotli = ["brotli", "brotlicffi"]
cli = ["click (>=8.0.0,<9.0.0)", "pygments (>=2.0.0,<3.0.0)", "rich (>=10,<13)"]
http2 = ["h2 (>=3,<5)"]
socks = ["socksio (>=1.0.0,<2.0.0)"]
[[package]]
name = "hyperframe"
version = "6.0.1"
description = "HTTP/2 framing layer for Python"
category = "main"
optional = false
python-versions = ">=3.6.1"
files = [
{file = "hyperframe-6.0.1-py3-none-any.whl", hash = "sha256:0ec6bafd80d8ad2195c4f03aacba3a8265e57bc4cff261e802bf39970ed02a15"},
{file = "hyperframe-6.0.1.tar.gz", hash = "sha256:ae510046231dc8e9ecb1a6586f63d2347bf4c8905914aa84ba585ae85f28a914"},
]
[[package]]
name = "idna"
version = "3.4"
@ -837,6 +999,18 @@ typing-extensions = ">=4.2.0"
dotenv = ["python-dotenv (>=0.10.4)"]
email = ["email-validator (>=1.0.3)"]
[[package]]
name = "pyhumps"
version = "3.8.0"
description = "🐫 Convert strings (and dictionary keys) between snake case, camel case and pascal case in Python. Inspired by Humps for Node"
category = "main"
optional = false
python-versions = "*"
files = [
{file = "pyhumps-3.8.0-py3-none-any.whl", hash = "sha256:060e1954d9069f428232a1adda165db0b9d8dfdce1d265d36df7fbff540acfd6"},
{file = "pyhumps-3.8.0.tar.gz", hash = "sha256:498026258f7ee1a8e447c2e28526c0bea9407f9a59c03260aee4bd6c04d681a3"},
]
[[package]]
name = "python-dotenv"
version = "1.0.0"
@ -852,6 +1026,134 @@ files = [
[package.extras]
cli = ["click (>=5.0)"]
[[package]]
name = "regex"
version = "2022.10.31"
description = "Alternative regular expression module, to replace re."
category = "main"
optional = false
python-versions = ">=3.6"
files = [
{file = "regex-2022.10.31-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a8ff454ef0bb061e37df03557afda9d785c905dab15584860f982e88be73015f"},
{file = "regex-2022.10.31-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1eba476b1b242620c266edf6325b443a2e22b633217a9835a52d8da2b5c051f9"},
{file = "regex-2022.10.31-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0e5af9a9effb88535a472e19169e09ce750c3d442fb222254a276d77808620b"},
{file = "regex-2022.10.31-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d03fe67b2325cb3f09be029fd5da8df9e6974f0cde2c2ac6a79d2634e791dd57"},
{file = "regex-2022.10.31-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a9d0b68ac1743964755ae2d89772c7e6fb0118acd4d0b7464eaf3921c6b49dd4"},
{file = "regex-2022.10.31-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8a45b6514861916c429e6059a55cf7db74670eaed2052a648e3e4d04f070e001"},
{file = "regex-2022.10.31-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8b0886885f7323beea6f552c28bff62cbe0983b9fbb94126531693ea6c5ebb90"},
{file = "regex-2022.10.31-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5aefb84a301327ad115e9d346c8e2760009131d9d4b4c6b213648d02e2abe144"},
{file = "regex-2022.10.31-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:702d8fc6f25bbf412ee706bd73019da5e44a8400861dfff7ff31eb5b4a1276dc"},
{file = "regex-2022.10.31-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a3c1ebd4ed8e76e886507c9eddb1a891673686c813adf889b864a17fafcf6d66"},
{file = "regex-2022.10.31-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:50921c140561d3db2ab9f5b11c5184846cde686bb5a9dc64cae442926e86f3af"},
{file = "regex-2022.10.31-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:7db345956ecce0c99b97b042b4ca7326feeec6b75facd8390af73b18e2650ffc"},
{file = "regex-2022.10.31-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:763b64853b0a8f4f9cfb41a76a4a85a9bcda7fdda5cb057016e7706fde928e66"},
{file = "regex-2022.10.31-cp310-cp310-win32.whl", hash = "sha256:44136355e2f5e06bf6b23d337a75386371ba742ffa771440b85bed367c1318d1"},
{file = "regex-2022.10.31-cp310-cp310-win_amd64.whl", hash = "sha256:bfff48c7bd23c6e2aec6454aaf6edc44444b229e94743b34bdcdda2e35126cf5"},
{file = "regex-2022.10.31-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4b4b1fe58cd102d75ef0552cf17242705ce0759f9695334a56644ad2d83903fe"},
{file = "regex-2022.10.31-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:542e3e306d1669b25936b64917285cdffcd4f5c6f0247636fec037187bd93542"},
{file = "regex-2022.10.31-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c27cc1e4b197092e50ddbf0118c788d9977f3f8f35bfbbd3e76c1846a3443df7"},
{file = "regex-2022.10.31-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8e38472739028e5f2c3a4aded0ab7eadc447f0d84f310c7a8bb697ec417229e"},
{file = "regex-2022.10.31-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:76c598ca73ec73a2f568e2a72ba46c3b6c8690ad9a07092b18e48ceb936e9f0c"},
{file = "regex-2022.10.31-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c28d3309ebd6d6b2cf82969b5179bed5fefe6142c70f354ece94324fa11bf6a1"},
{file = "regex-2022.10.31-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9af69f6746120998cd9c355e9c3c6aec7dff70d47247188feb4f829502be8ab4"},
{file = "regex-2022.10.31-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a5f9505efd574d1e5b4a76ac9dd92a12acb2b309551e9aa874c13c11caefbe4f"},
{file = "regex-2022.10.31-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:5ff525698de226c0ca743bfa71fc6b378cda2ddcf0d22d7c37b1cc925c9650a5"},
{file = "regex-2022.10.31-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:4fe7fda2fe7c8890d454f2cbc91d6c01baf206fbc96d89a80241a02985118c0c"},
{file = "regex-2022.10.31-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:2cdc55ca07b4e70dda898d2ab7150ecf17c990076d3acd7a5f3b25cb23a69f1c"},
{file = "regex-2022.10.31-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:44a6c2f6374e0033873e9ed577a54a3602b4f609867794c1a3ebba65e4c93ee7"},
{file = "regex-2022.10.31-cp311-cp311-win32.whl", hash = "sha256:d8716f82502997b3d0895d1c64c3b834181b1eaca28f3f6336a71777e437c2af"},
{file = "regex-2022.10.31-cp311-cp311-win_amd64.whl", hash = "sha256:61edbca89aa3f5ef7ecac8c23d975fe7261c12665f1d90a6b1af527bba86ce61"},
{file = "regex-2022.10.31-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:0a069c8483466806ab94ea9068c34b200b8bfc66b6762f45a831c4baaa9e8cdd"},
{file = "regex-2022.10.31-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d26166acf62f731f50bdd885b04b38828436d74e8e362bfcb8df221d868b5d9b"},
{file = "regex-2022.10.31-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac741bf78b9bb432e2d314439275235f41656e189856b11fb4e774d9f7246d81"},
{file = "regex-2022.10.31-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75f591b2055523fc02a4bbe598aa867df9e953255f0b7f7715d2a36a9c30065c"},
{file = "regex-2022.10.31-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b30bddd61d2a3261f025ad0f9ee2586988c6a00c780a2fb0a92cea2aa702c54"},
{file = "regex-2022.10.31-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef4163770525257876f10e8ece1cf25b71468316f61451ded1a6f44273eedeb5"},
{file = "regex-2022.10.31-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7b280948d00bd3973c1998f92e22aa3ecb76682e3a4255f33e1020bd32adf443"},
{file = "regex-2022.10.31-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:d0213671691e341f6849bf33cd9fad21f7b1cb88b89e024f33370733fec58742"},
{file = "regex-2022.10.31-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:22e7ebc231d28393dfdc19b185d97e14a0f178bedd78e85aad660e93b646604e"},
{file = "regex-2022.10.31-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:8ad241da7fac963d7573cc67a064c57c58766b62a9a20c452ca1f21050868dfa"},
{file = "regex-2022.10.31-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:586b36ebda81e6c1a9c5a5d0bfdc236399ba6595e1397842fd4a45648c30f35e"},
{file = "regex-2022.10.31-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:0653d012b3bf45f194e5e6a41df9258811ac8fc395579fa82958a8b76286bea4"},
{file = "regex-2022.10.31-cp36-cp36m-win32.whl", hash = "sha256:144486e029793a733e43b2e37df16a16df4ceb62102636ff3db6033994711066"},
{file = "regex-2022.10.31-cp36-cp36m-win_amd64.whl", hash = "sha256:c14b63c9d7bab795d17392c7c1f9aaabbffd4cf4387725a0ac69109fb3b550c6"},
{file = "regex-2022.10.31-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4cac3405d8dda8bc6ed499557625585544dd5cbf32072dcc72b5a176cb1271c8"},
{file = "regex-2022.10.31-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23cbb932cc53a86ebde0fb72e7e645f9a5eec1a5af7aa9ce333e46286caef783"},
{file = "regex-2022.10.31-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:74bcab50a13960f2a610cdcd066e25f1fd59e23b69637c92ad470784a51b1347"},
{file = "regex-2022.10.31-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:78d680ef3e4d405f36f0d6d1ea54e740366f061645930072d39bca16a10d8c93"},
{file = "regex-2022.10.31-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce6910b56b700bea7be82c54ddf2e0ed792a577dfaa4a76b9af07d550af435c6"},
{file = "regex-2022.10.31-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:659175b2144d199560d99a8d13b2228b85e6019b6e09e556209dfb8c37b78a11"},
{file = "regex-2022.10.31-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1ddf14031a3882f684b8642cb74eea3af93a2be68893901b2b387c5fd92a03ec"},
{file = "regex-2022.10.31-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b683e5fd7f74fb66e89a1ed16076dbab3f8e9f34c18b1979ded614fe10cdc4d9"},
{file = "regex-2022.10.31-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2bde29cc44fa81c0a0c8686992c3080b37c488df167a371500b2a43ce9f026d1"},
{file = "regex-2022.10.31-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:4919899577ba37f505aaebdf6e7dc812d55e8f097331312db7f1aab18767cce8"},
{file = "regex-2022.10.31-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:9c94f7cc91ab16b36ba5ce476f1904c91d6c92441f01cd61a8e2729442d6fcf5"},
{file = "regex-2022.10.31-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ae1e96785696b543394a4e3f15f3f225d44f3c55dafe3f206493031419fedf95"},
{file = "regex-2022.10.31-cp37-cp37m-win32.whl", hash = "sha256:c670f4773f2f6f1957ff8a3962c7dd12e4be54d05839b216cb7fd70b5a1df394"},
{file = "regex-2022.10.31-cp37-cp37m-win_amd64.whl", hash = "sha256:8e0caeff18b96ea90fc0eb6e3bdb2b10ab5b01a95128dfeccb64a7238decf5f0"},
{file = "regex-2022.10.31-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:131d4be09bea7ce2577f9623e415cab287a3c8e0624f778c1d955ec7c281bd4d"},
{file = "regex-2022.10.31-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e613a98ead2005c4ce037c7b061f2409a1a4e45099edb0ef3200ee26ed2a69a8"},
{file = "regex-2022.10.31-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:052b670fafbe30966bbe5d025e90b2a491f85dfe5b2583a163b5e60a85a321ad"},
{file = "regex-2022.10.31-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aa62a07ac93b7cb6b7d0389d8ef57ffc321d78f60c037b19dfa78d6b17c928ee"},
{file = "regex-2022.10.31-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5352bea8a8f84b89d45ccc503f390a6be77917932b1c98c4cdc3565137acc714"},
{file = "regex-2022.10.31-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20f61c9944f0be2dc2b75689ba409938c14876c19d02f7585af4460b6a21403e"},
{file = "regex-2022.10.31-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:29c04741b9ae13d1e94cf93fca257730b97ce6ea64cfe1eba11cf9ac4e85afb6"},
{file = "regex-2022.10.31-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:543883e3496c8b6d58bd036c99486c3c8387c2fc01f7a342b760c1ea3158a318"},
{file = "regex-2022.10.31-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b7a8b43ee64ca8f4befa2bea4083f7c52c92864d8518244bfa6e88c751fa8fff"},
{file = "regex-2022.10.31-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:6a9a19bea8495bb419dc5d38c4519567781cd8d571c72efc6aa959473d10221a"},
{file = "regex-2022.10.31-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:6ffd55b5aedc6f25fd8d9f905c9376ca44fcf768673ffb9d160dd6f409bfda73"},
{file = "regex-2022.10.31-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:4bdd56ee719a8f751cf5a593476a441c4e56c9b64dc1f0f30902858c4ef8771d"},
{file = "regex-2022.10.31-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8ca88da1bd78990b536c4a7765f719803eb4f8f9971cc22d6ca965c10a7f2c4c"},
{file = "regex-2022.10.31-cp38-cp38-win32.whl", hash = "sha256:5a260758454580f11dd8743fa98319bb046037dfab4f7828008909d0aa5292bc"},
{file = "regex-2022.10.31-cp38-cp38-win_amd64.whl", hash = "sha256:5e6a5567078b3eaed93558842346c9d678e116ab0135e22eb72db8325e90b453"},
{file = "regex-2022.10.31-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5217c25229b6a85049416a5c1e6451e9060a1edcf988641e309dbe3ab26d3e49"},
{file = "regex-2022.10.31-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4bf41b8b0a80708f7e0384519795e80dcb44d7199a35d52c15cc674d10b3081b"},
{file = "regex-2022.10.31-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cf0da36a212978be2c2e2e2d04bdff46f850108fccc1851332bcae51c8907cc"},
{file = "regex-2022.10.31-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d403d781b0e06d2922435ce3b8d2376579f0c217ae491e273bab8d092727d244"},
{file = "regex-2022.10.31-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a37d51fa9a00d265cf73f3de3930fa9c41548177ba4f0faf76e61d512c774690"},
{file = "regex-2022.10.31-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4f781ffedd17b0b834c8731b75cce2639d5a8afe961c1e58ee7f1f20b3af185"},
{file = "regex-2022.10.31-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d243b36fbf3d73c25e48014961e83c19c9cc92530516ce3c43050ea6276a2ab7"},
{file = "regex-2022.10.31-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:370f6e97d02bf2dd20d7468ce4f38e173a124e769762d00beadec3bc2f4b3bc4"},
{file = "regex-2022.10.31-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:597f899f4ed42a38df7b0e46714880fb4e19a25c2f66e5c908805466721760f5"},
{file = "regex-2022.10.31-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7dbdce0c534bbf52274b94768b3498abdf675a691fec5f751b6057b3030f34c1"},
{file = "regex-2022.10.31-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:22960019a842777a9fa5134c2364efaed5fbf9610ddc5c904bd3a400973b0eb8"},
{file = "regex-2022.10.31-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:7f5a3ffc731494f1a57bd91c47dc483a1e10048131ffb52d901bfe2beb6102e8"},
{file = "regex-2022.10.31-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7ef6b5942e6bfc5706301a18a62300c60db9af7f6368042227ccb7eeb22d0892"},
{file = "regex-2022.10.31-cp39-cp39-win32.whl", hash = "sha256:395161bbdbd04a8333b9ff9763a05e9ceb4fe210e3c7690f5e68cedd3d65d8e1"},
{file = "regex-2022.10.31-cp39-cp39-win_amd64.whl", hash = "sha256:957403a978e10fb3ca42572a23e6f7badff39aa1ce2f4ade68ee452dc6807692"},
{file = "regex-2022.10.31.tar.gz", hash = "sha256:a3a98921da9a1bf8457aeee6a551948a83601689e5ecdd736894ea9bbec77e83"},
]
[[package]]
name = "rfc3986"
version = "1.5.0"
description = "Validating URI References per RFC 3986"
category = "main"
optional = false
python-versions = "*"
files = [
{file = "rfc3986-1.5.0-py2.py3-none-any.whl", hash = "sha256:a86d6e1f5b1dc238b218b012df0aa79409667bb209e58da56d0b94704e712a97"},
{file = "rfc3986-1.5.0.tar.gz", hash = "sha256:270aaf10d87d0d4e095063c65bf3ddbc6ee3d0b226328ce21e036f946e421835"},
]
[package.dependencies]
idna = {version = "*", optional = true, markers = "extra == \"idna2008\""}
[package.extras]
idna2008 = ["idna"]
[[package]]
name = "sniffio"
version = "1.3.0"
description = "Sniff out which async library your code is running under"
category = "main"
optional = false
python-versions = ">=3.7"
files = [
{file = "sniffio-1.3.0-py3-none-any.whl", hash = "sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384"},
{file = "sniffio-1.3.0.tar.gz", hash = "sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101"},
]
[[package]]
name = "typing-extensions"
version = "4.5.0"
@ -1030,4 +1332,4 @@ multidict = ">=4.0"
[metadata]
lock-version = "2.0"
python-versions = "^3.11"
content-hash = "043085936cf3935b690f67dd9a0350953a4f7e9e7aed7b23a40d74f4208bd55f"
content-hash = "7b099d3f7d122dc03ac646e52c3680b9cf29c2e96a41ea937716a3452b76d689"

View File

@ -12,6 +12,12 @@ ujson = "^5.7.0"
orjson = "^3.8.8"
aiohttp = {extras = ["speedups"], version = "^3.8.4"}
pydantic = {extras = ["dotenv", "email"], version = "^1.10.6"}
aiofiles = "^23.1.0"
regex = "^2022.10.31"
pyhumps = "^3.8.0"
httpx = {extras = ["http2"], version = "^0.23.3"}
arko-wrapper = "^0.2.8"
[build-system]

90
run.py Normal file
View File

@ -0,0 +1,90 @@
import asyncio
from utils.const import PROJECT_ROOT
from utils.context import ContextManager
from utils.manager import ResourceManager
from utils.text import Text
from utils.typedefs import Lang
import ujson as json
OUTPUT_DIR = PROJECT_ROOT / "data"
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
# noinspection PyShadowingBuiltins
async def parse_item_data(resource: ResourceManager):
from models.item import Food, FoodQuality, Item
json_data = resource.fetch("MaterialExcelConfigData")
data_list = []
for item_data in json_data:
id = item_data["id"]
name = Text(item_data["nameTextMapHash"])
family = item_data.get("materialType", "")
rarity = item_data.get("rankLevel")
type = Text(item_data["typeDescTextMapHash"])
icon = item_data["icon"]
description = Text(item_data["descTextMapHash"])
special = Text(item_data["specialDescTextMapHash"]) or None
base_kwargs = {
"id": id,
"name": name,
"family": family,
"rarity": rarity,
"type": type,
"icon": icon,
"description": description,
}
if special is not None:
base_kwargs["special_description"] = special
if "materialType" in item_data: # 材料
material_type = item_data["materialType"]
elif "foodQuality" in item_data: # 食物
quality = FoodQuality(
item_data["foodQuality"].removeprefix("FOOD_QUALITY_").title()
)
effect = Text(item_data["effectDescTextMapHash"])
item = Food(quality=quality, effect=effect, **base_kwargs)
else:
item = Item(**base_kwargs)
data_list.append(item.dict(exclude_none=True))
item_data_file = OUTPUT_DIR / "item.json"
with open(item_data_file, "w", encoding="utf-8") as f:
f.write(json.dumps(data_list, ensure_ascii=False))
breakpoint()
async def fetch_parse_data(lang: Lang):
with ContextManager().with_context(
"resource_manager", ResourceManager(lang=lang)
) as resource_manager:
await parse_item_data(resource_manager)
async def main():
task_list = []
for lang in Lang.__args__:
task = asyncio.create_task(fetch_parse_data(lang=lang))
task_list.append(task)
await asyncio.gather(*task_list)
def __main__():
import asyncio
import sys
if (3, 10) >= sys.version_info >= (3, 8) and sys.platform.startswith("win"):
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
loop = asyncio.new_event_loop()
loop.run_until_complete(main())
if __name__ == "__main__":
__main__()

0
utils/__init__.py Normal file
View File

5
utils/const.py Normal file
View File

@ -0,0 +1,5 @@
from pathlib import Path
PROJECT_ROOT = Path(__file__).joinpath("../../").resolve()
DATA_DIR = PROJECT_ROOT.joinpath("data")
DATA_DIR.mkdir(parents=True, exist_ok=True)

46
utils/context.py Normal file
View File

@ -0,0 +1,46 @@
from contextlib import contextmanager
from contextvars import ContextVar, Token
from typing import TypeVar
from utils.single import Singleton
__all__ = ("ContextManager",)
T = TypeVar("T")
_values: dict[str, ContextVar] = {}
class ContextManager(Singleton):
_values: dict[str, ContextVar] = {}
def get_context(self, name: str) -> ContextVar[T]:
if name in self._values:
return self._values[name]
else:
result = ContextVar(name)
self._values[name] = result
return result
def get_value(self, name: str) -> T:
return self.get_context(name).get()
def set_context(self, name: str, value: T) -> Token:
context: ContextVar[T] = self.get_context(name)
return context.set(value)
def reset_context(self, name: str, token: Token) -> None:
context: ContextVar[T] = self.get_context(name)
context.reset(token)
@contextmanager
def with_context(self, name: str, value: T) -> T:
context: ContextVar[T] = self.get_context(name)
token: Token = context.set(value)
try:
yield value
finally:
context.reset(token)
def __getitem__(self, item: str) -> ContextVar[T]:
return self.get_context(item)

78
utils/manager.py Normal file
View File

@ -0,0 +1,78 @@
import os
import ssl
from functools import lru_cache
import ujson as json
from httpx import Client
from pydantic import Json
from yarl import URL
from utils.const import DATA_DIR
from utils.single import Singleton
from utils.typedefs import Lang
__all__ = "ResourceManager"
ssl_context = ssl.SSLContext()
class ResourceManager(Singleton):
_lang: Lang
_base_url: URL
_client: Client | None = None
_lang_data: dict[str, str] | None = None
def __init__(self, base_url: str | None = None, lang: Lang | None = None):
self._base_url = URL(
base_url
or "https://git.neeemooo.com/githubbackup/GenshinData/-/raw/master/"
)
self._lang = lang or "chs"
@property
def lang(self) -> Lang:
return self._lang
@property
def client(self) -> Client:
with self._lock:
if self._client is None or self._client.is_closed:
self._client = Client(verify=ssl_context)
return self._client
def refresh(self) -> None:
"""删除缓存数据的文件夹,需要数据时会重新从网络上下载,达到刷新缓存数据的目的"""
if self._client is not None:
if not self._client.is_closed:
self._client.close()
self._client = None
if DATA_DIR.exists():
os.remove(DATA_DIR)
DATA_DIR.mkdir(parents=True, exist_ok=True)
@lru_cache(128, typed=True)
def get_text(self, text_id: int | str | None) -> str | None:
if text_id is None:
return None
if self._lang_data is None:
self._lang_data = self.fetch("TextMap" + self.lang.upper(), "TextMap")
result = self._lang_data.get(str(text_id), None)
if result is not None:
return result.replace("\\n", "\n")
return result
@lru_cache()
def fetch(self, name: str, file_dir: str = "ExcelBinOutput") -> Json:
file_path = DATA_DIR.joinpath(file_dir).joinpath(name).with_suffix(".json")
file_path.parent.mkdir(exist_ok=True, parents=True)
if not file_path.exists() or os.stat(file_path) == 0:
response = self.client.get(str(self._base_url / file_dir / file_path.name))
response.raise_for_status()
with open(file_path, encoding="utf-8", mode="w") as file:
file.write(content := response.text)
return json.loads(content)
with open(file_path, encoding="utf-8", mode="r") as file:
return json.loads(file.read())

35
utils/model.py Normal file
View File

@ -0,0 +1,35 @@
from typing import Type, TypeVar
import ujson as json
from pydantic import (
BaseConfig as PydanticBaseConfig,
BaseModel as PydanticBaseModel,
BaseSettings as PydanticBaseSettings,
)
__all__ = ("BaseConfig", "BaseSettings", "BaseModel")
T = TypeVar("T")
class BaseConfig(PydanticBaseConfig):
json_dumps = json.dumps
json_loads = json.loads
class BaseSettings(PydanticBaseSettings):
def __new__(cls: Type[T], *args, **kwargs) -> T:
cls.update_forward_refs()
return super(PydanticBaseSettings, cls).__new__(cls)
class Config(BaseConfig):
pass
class BaseModel(PydanticBaseModel):
def __new__(cls: Type[T], *args, **kwargs) -> T:
cls.update_forward_refs()
return super(PydanticBaseModel, cls).__new__(cls)
class Config(BaseConfig):
pass

55
utils/single.py Normal file
View File

@ -0,0 +1,55 @@
from multiprocessing import RLock as Lock
from typing import (
ClassVar,
Generic,
Optional,
TYPE_CHECKING,
Type,
TypeVar,
)
from typing_extensions import Self
if TYPE_CHECKING:
from multiprocessing.synchronize import RLock as LockType
__all__ = ["singleton", "Singleton"]
T = TypeVar("T")
class _Singleton(Generic[T]):
lock: ClassVar["LockType"] = Lock()
__slots__ = "cls", "instance"
cls: Type[T]
instance: Optional[T]
def __init__(self, cls: Type[T]):
self.cls = cls
self.instance = None
def __call__(self, *args, **kwargs) -> T:
with self.lock:
if self.instance is None or args or kwargs:
self.instance = self.cls(*args, **kwargs)
return self.instance
def singleton(cls: Optional[Type[T]] = None) -> Type[T]:
def wrap(_cls: Type[T]) -> _Singleton[T]:
return _Singleton(_cls)
return wrap if cls is None else wrap(cls)
class Singleton(object):
_lock: ClassVar["LockType"] = Lock()
_instance: ClassVar[Optional[Self]] = None
def __new__(cls: Type[T], *args, **kwargs) -> T:
with cls._lock:
if cls._instance is None:
cls._instance = object.__new__(cls)
return cls._instance

20
utils/text.py Normal file
View File

@ -0,0 +1,20 @@
from utils.context import ContextManager
__all__ = ("Text",)
class Text(str):
def __new__(cls, string: str | int) -> "Text":
_id = None
if isinstance(string, str):
try:
_id = int(string)
except ValueError:
_id = None
elif isinstance(string, int):
_id = string
if _id is not None:
string = (
ContextManager().get_value("resource_manager").get_text(_id) or ""
).replace("\\n", "\n")
return str.__new__(cls, string)

19
utils/typedefs.py Normal file
View File

@ -0,0 +1,19 @@
from typing import Literal
Lang = Literal[
"chs",
"cht",
"de",
"en",
"es",
"fr",
"id",
"it",
"jp",
"kr",
"pt",
"ru",
"th",
"tr",
"vi",
]