diff --git a/modules/apihelper/abyss_team.py b/modules/apihelper/abyss_team.py index 7170a9e6..700e0563 100644 --- a/modules/apihelper/abyss_team.py +++ b/modules/apihelper/abyss_team.py @@ -1,5 +1,5 @@ import time -from typing import List, Optional +from typing import List, Optional, Any import httpx from pydantic import BaseModel, parse_obj_as, validator @@ -14,25 +14,41 @@ class Member(BaseModel): class TeamRate(BaseModel): rate: float formation: List[Member] - ownerNum: Optional[int] + owner_num: Optional[int] @validator('rate', pre=True) def str2float(cls, v): # pylint: disable=R0201 return float(v.replace('%', '')) / 100.0 if isinstance(v, str) else v +class FullTeamRate(BaseModel): + up: TeamRate + down: TeamRate + owner_num: Optional[int] + + @property + def rate(self) -> float: + return self.up.rate + self.down.rate + + class TeamRateResult(BaseModel): - rateListUp: List[TeamRate] - rateListDown: List[TeamRate] - userCount: int + rate_list_up: List[TeamRate] + rate_list_down: List[TeamRate] + rate_list_full: List[FullTeamRate] = [] + user_count: int + + def __init__(self, **data: Any): + super().__init__(**data) + for team_up in self.rate_list_up: + for team_down in self.rate_list_down: + if {member.name for member in team_up.formation} & {member.name for member in team_down.formation}: + continue + self.rate_list_full.append(FullTeamRate(up=team_up, down=team_down)) def sort(self, characters: List[str]): - for team in self.rateListUp: - team.ownerNum = len(set(characters) & {member.name for member in team.formation}) - for team in self.rateListDown: - team.ownerNum = len(set(characters) & {member.name for member in team.formation}) - self.rateListUp.sort(key=lambda x: (x.ownerNum / 4 * x.rate), reverse=True) - self.rateListDown.sort(key=lambda x: (x.ownerNum / 4 * x.rate), reverse=True) + for team in self.rate_list_full: + team.owner_num = sum(member.name in characters for member in team.up.formation + team.down.formation) + self.rate_list_full.sort(key=lambda x: (x.owner_num / 8 * x.rate), reverse=True) class AbyssTeamData: @@ -58,9 +74,9 @@ class AbyssTeamData: data_up_json = data_up.json()["result"] data_down = await self.client.post(self.TEAM_RATE_API, json={"version": self.VERSION, "layer": 2}) data_down_json = data_down.json()["result"] - self.data = TeamRateResult(rateListUp=parse_obj_as(List[TeamRate], data_up_json["rateList"]), - rateListDown=parse_obj_as(List[TeamRate], data_down_json["rateList"]), - userCount=data_up_json["userCount"]) + self.data = TeamRateResult(rate_list_up=parse_obj_as(List[TeamRate], data_up_json["rateList"]), + rate_list_down=parse_obj_as(List[TeamRate], data_down_json["rateList"]), + user_count=data_up_json["userCount"]) self.time = time.time() return self.data.copy(deep=True) diff --git a/plugins/genshin/abyss_team.py b/plugins/genshin/abyss_team.py index df009558..9481c03f 100644 --- a/plugins/genshin/abyss_team.py +++ b/plugins/genshin/abyss_team.py @@ -65,7 +65,7 @@ class AbyssTeam(Plugin, BasePlugin): "up": [], "down": [] } - for i in team_data.rateListUp[0].formation: + for i in team_data.rate_list_full[0].up.formation: temp = { "icon": (await self.assets_service.avatar(roleToId(i.name)).icon()).as_uri(), "name": i.name, @@ -73,7 +73,7 @@ class AbyssTeam(Plugin, BasePlugin): "hava": (i.name in user_data) if user_data else True, } abyss_team_data["up"].append(temp) - for i in team_data.rateListDown[0].formation: + for i in team_data.rate_list_full[0].down.formation: temp = { "icon": (await self.assets_service.avatar(roleToId(i.name)).icon()).as_uri(), "name": i.name, diff --git a/tests/test_abyss_team_data.py b/tests/test_abyss_team_data.py index 93564ed7..e6ecfb05 100644 --- a/tests/test_abyss_team_data.py +++ b/tests/test_abyss_team_data.py @@ -4,7 +4,7 @@ import pytest import pytest_asyncio from flaky import flaky -from modules.apihelper.abyss_team import AbyssTeamData, TeamRateResult, TeamRate +from modules.apihelper.abyss_team import AbyssTeamData, TeamRateResult, TeamRate, FullTeamRate LOGGER = logging.getLogger(__name__) @@ -22,12 +22,18 @@ async def abyss_team_data(): async def test_abyss_team_data(abyss_team_data: AbyssTeamData): team_data = await abyss_team_data.get_data() assert isinstance(team_data, TeamRateResult) - assert isinstance(team_data.rateListUp[0], TeamRate) - assert isinstance(team_data.rateListUp[-1], TeamRate) - assert isinstance(team_data.rateListDown[0], TeamRate) - assert isinstance(team_data.rateListDown[-1], TeamRate) - assert team_data.userCount > 0 - for i in team_data.rateListUp[0].formation: + assert isinstance(team_data.rate_list_up[0], TeamRate) + assert isinstance(team_data.rate_list_up[-1], TeamRate) + assert isinstance(team_data.rate_list_down[0], TeamRate) + assert isinstance(team_data.rate_list_down[-1], TeamRate) + assert team_data.user_count > 0 + team_data.sort(["迪奥娜", "芭芭拉", "凯亚", "琴"]) + assert isinstance(team_data.rate_list_full[0], FullTeamRate) + assert isinstance(team_data.rate_list_full[-1], FullTeamRate) + memberUp = {i.name for i in team_data.rate_list_full[0].up.formation} + memberDown = {i.name for i in team_data.rate_list_full[0].down.formation} + assert not memberUp & memberDown + for i in team_data.rate_list_full[0].down.formation: LOGGER.info("rate down info:name %s star %s", i.name, i.star) - for i in team_data.rateListDown[0].formation: + for i in team_data.rate_list_full[0].up.formation: LOGGER.info("rate up info:name %s star %s", i.name, i.star)