Support starrail player_card stats

This commit is contained in:
xtaodada 2023-05-22 21:30:36 +08:00
parent 243472d91d
commit d35a88ef11
Signed by: xtaodada
GPG Key ID: 4CBB3F4FA8C85659
4 changed files with 53 additions and 6 deletions

View File

@ -40,6 +40,21 @@ class Relic(BaseModel):
Type: int
class Property(BaseModel):
name: str
base: str
addition: Optional[str]
@property
def total(self):
if not self.addition:
return self.base
percent = "%" in self.base
real_base = float(self.base.replace("%", "")) if percent else int(self.base)
real_addition = float(self.base.replace("%", "")) if percent else int(self.base)
return f"{real_base + real_addition}{'%' if percent else ''}"
class Avatar(BaseModel):
AvatarID: int
BehaviorList: List[Behavior]
@ -48,6 +63,7 @@ class Avatar(BaseModel):
Promotion: Optional[int] = 4
Rank: Optional[int] = 0
RelicList: Optional[List[Relic]]
property: Optional[List[Property]]
class ChallengeData(BaseModel):
@ -85,6 +101,7 @@ class PlayerCardsError(Exception):
class PlayerCards:
url = "https://api.mihomo.me/sr_info/"
url2 = "https://api.mihomo.me/sr_info_parsed/"
prop_url = f"{WikiModel.BASE_URL}relic_config.json"
def __init__(self, redis):
@ -105,12 +122,29 @@ class PlayerCards:
self.relic_datas_map[i["id"]] = RelicAffixAll(**i)
self.init = True
async def get_property(self, uid: str) -> Dict[int, List[Dict]]:
final_data: Dict[int, List[Dict]] = {}
try:
user = await self.client.get(self.url2 + uid, timeout=30, headers=self.headers)
if user.status_code != 200:
raise PlayerCardsError("请求异常,错误代码 %s" % user.status_code)
data = ujson.loads(user.text)
characters = data.get("characters", [])
for character in characters:
cid = int(character.get("id", 0))
if not cid:
continue
final_data[cid] = character.get("property", [])
except (TimeoutException, PlayerCardsError):
pass
return final_data
async def update_data(self, uid: str) -> Union[PlayerInfo, str]:
try:
data = await self.cache.get(uid)
if data is not None:
return PlayerInfo.parse_obj(data)
user = await self.client.get(self.url + uid, timeout=15, headers=self.headers)
user = await self.client.get(self.url + uid, timeout=30, headers=self.headers)
if user.status_code != 200:
raise PlayerCardsError(f"请求异常,错误代码 {user.status_code}")
data = ujson.loads(user.text)
@ -118,7 +152,8 @@ class PlayerCards:
if error_code:
raise PlayerCardsError(f"请求异常,错误代码 {error_code}")
data = data.get("PlayerDetailInfo", {})
data = await self.player_cards_file.merge_info(uid, data)
props = await self.get_property(uid)
data = await self.player_cards_file.merge_info(uid, data, props)
await self.cache.set(uid, data)
return PlayerInfo.parse_obj(data)
except TimeoutException:

View File

@ -59,6 +59,7 @@ class PlayerCardsFile:
self,
uid: Union[str, int],
data: Dict,
props: Dict,
) -> Dict:
async with self._lock:
old_data = await self.load_history_info(uid)
@ -83,5 +84,7 @@ class PlayerCardsFile:
for i in old_data.get("AvatarList", []):
if i.get("AvatarID", 0) not in avatar_ids:
data["AvatarList"].append(i)
for i in data["AvatarList"]:
i["property"] = props.get(i.get("AvatarID", 0), [])
await self.save_json(self.get_file_path(uid), data)
return data

View File

@ -60,7 +60,7 @@
<!-- Character Background -->
<div
class="absolute w-full h-full -left-1/4 opacity-80 bg-no-repeat bg-center"
style="background-image: url('{{ images.banner_url }}'); background-size: auto 200%;"
style="background-image: url('{{ images.banner_url }}'); background-size: auto 130%;"
></div>
<div class="relative w-full flex p-5 space-x-8">
{% include 'starrail/player_card/constellations.html' %}
@ -79,13 +79,13 @@
</div>
{% include 'starrail/player_card/skills.html' %}
{% include 'starrail/player_card/stats.html' %}
<div class="flex flex-col space-y-2">
{% if weapon != none %}
{% include 'starrail/player_card/weapon.html' %}
{% endif %}
{% include 'starrail/player_card/score.html' %}
</div>
{% include 'starrail/player_card/stats.html' %}
</div>
</div>
</div>
@ -100,7 +100,7 @@
<!-- Logo -->
<div class="mt-4 relative">
<div class="text-gray-300 text-center opacity-70 text-lg">
Inspired by Miao-Plugin
Inspired by Miao-Plugin & Data by MiHoMo.Me
</div>
</div>
</div>

View File

@ -1,3 +1,12 @@
{% if character.property != none %}
<div class="rounded-lg bg-black bg-opacity-20">
{% for prop in character.property %}
<div
class="px-7 py-1.5 flex justify-between even:bg-white even:bg-opacity-10"
>
<div>{{ prop.name }}</div>
<div class="italic">{{ prop.total }}</div>
</div>
{% endfor %}
</div>
{% endif %}