support aapi

This commit is contained in:
omg-xtao 2023-07-23 17:41:26 +08:00 committed by GitHub
parent 2e50bf2081
commit d3b3a4b62e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 164 additions and 11 deletions

View File

@ -24,6 +24,7 @@ class BaseChronicleClient(BaseClient):
async def request_game_record(
self,
endpoint: str,
endpoint_type: str = "api",
data: Optional[Any] = None,
params: Optional[QueryParamTypes] = None,
lang: Optional[str] = None,
@ -34,6 +35,7 @@ class BaseChronicleClient(BaseClient):
Args:
endpoint (str): The endpoint to send the request to.
endpoint_type (str, optional): The type of endpoint to send the request to.
data (Optional[Any], optional): The request payload.
params (Optional[QueryParamTypes], optional): The query parameters for the request.
lang (Optional[str], optional): The language for the response.
@ -51,7 +53,7 @@ class BaseChronicleClient(BaseClient):
base_url = RECORD_URL.get_url(region or self.region)
if game:
base_url = base_url / game.value / "api"
base_url = base_url / game.value / endpoint_type
url = base_url / endpoint
new_ds = self.region == Region.CHINESE

View File

@ -2,17 +2,17 @@ import asyncio
from typing import Optional, Any, List, Dict
from simnet.client.components.chronicle.base import BaseChronicleClient
from simnet.errors import DataNotPublic, BadRequest
from simnet.errors import DataNotPublic, BadRequest, RegionNotSupported
from simnet.models.genshin.chronicle.abyss import SpiralAbyss, SpiralAbyssPair
from simnet.models.genshin.chronicle.characters import Character
from simnet.models.genshin.chronicle.notes import Notes
from simnet.models.genshin.chronicle.notes import Notes, NotesWidget
from simnet.models.genshin.chronicle.stats import (
PartialGenshinUserStats,
GenshinUserStats,
FullGenshinUserStats,
)
from simnet.models.lab.record import RecordCard
from simnet.utils.enum_ import Game
from simnet.utils.enum_ import Game, Region
from simnet.utils.player import recognize_genshin_server, recognize_region
__all__ = ("GenshinBattleChronicleClient",)
@ -30,6 +30,7 @@ class GenshinBattleChronicleClient(BaseChronicleClient):
endpoint: str,
player_id: Optional[int] = None,
method: str = "GET",
endpoint_type: str = "api",
lang: Optional[str] = None,
payload: Optional[Dict[str, Any]] = None,
):
@ -37,6 +38,7 @@ class GenshinBattleChronicleClient(BaseChronicleClient):
Args:
endpoint (str): The endpoint of the object to retrieve.
endpoint_type (str, optional): The type of endpoint to send the request to.
player_id (Optional[int], optional): The player ID. Defaults to None.
method (str, optional): The HTTP method to use. Defaults to "GET".
lang (Optional[str], optional): The language of the data. Defaults to None.
@ -68,6 +70,7 @@ class GenshinBattleChronicleClient(BaseChronicleClient):
return await self.request_game_record(
endpoint,
endpoint_type=endpoint_type,
lang=lang,
game=Game.GENSHIN,
region=recognize_region(player_id, game=Game.GENSHIN),
@ -172,7 +175,7 @@ class GenshinBattleChronicleClient(BaseChronicleClient):
autoauth (bool, optional): Whether to automatically authenticate the user. Defaults to True.
Returns:
StarRailNote: The requested real-time notes.
Notes: The requested real-time notes.
Raises:
BadRequest: If the request is invalid.
@ -258,3 +261,32 @@ class GenshinBattleChronicleClient(BaseChronicleClient):
return record_card
return None
async def get_genshin_notes_by_stoken(
self,
lang: Optional[str] = None,
) -> NotesWidget:
"""Get Genshin's real-time notes.
Args:
lang (Optional[str], optional): The language of the data. Defaults to None.
Returns:
NotesWidget: The requested real-time notes.
Raises:
RegionNotSupported: If the region is not supported.
BadRequest: If the request is invalid.
"""
if self.region == Region.OVERSEAS:
raise RegionNotSupported("Notes widget is not supported in overseas region.")
stoken = self.cookies.get("stoken")
if stoken is None:
raise ValueError("stoken not found in cookies.")
stuid = self.cookies.get("stuid")
if stuid is None and self.account_id is None:
raise ValueError("account_id or stuid not found")
if self.account_id is not None and stuid is None:
self.cookies.set("stuid", str(self.account_id))
data = await self._request_genshin_record("widget/v2", endpoint_type="aapi", lang=lang)
return NotesWidget(**data)

View File

@ -2,16 +2,16 @@ import asyncio
from typing import Optional, Mapping, Dict, Any
from simnet.client.components.chronicle.base import BaseChronicleClient
from simnet.errors import BadRequest, DataNotPublic
from simnet.errors import BadRequest, DataNotPublic, RegionNotSupported
from simnet.models.lab.record import RecordCard
from simnet.models.starrail.chronicle.activity import StarRailActivity
from simnet.models.starrail.chronicle.challenge import StarRailChallenge
from simnet.models.starrail.chronicle.characters import StarRailDetailCharacters
from simnet.models.starrail.chronicle.museum import StarRailMuseumBasic, StarRailMuseumDetail
from simnet.models.starrail.chronicle.notes import StarRailNote
from simnet.models.starrail.chronicle.notes import StarRailNote, StarRailNoteWidget
from simnet.models.starrail.chronicle.rogue import StarRailRogue
from simnet.models.starrail.chronicle.stats import StarRailUserStats, StarRailUserInfo
from simnet.utils.enum_ import Game
from simnet.utils.enum_ import Game, Region
from simnet.utils.player import recognize_starrail_server, recognize_region
__all__ = ("StarRailBattleChronicleClient",)
@ -28,6 +28,7 @@ class StarRailBattleChronicleClient(BaseChronicleClient):
self,
endpoint: str,
player_id: Optional[int] = None,
endpoint_type: str = "api",
method: str = "GET",
lang: Optional[str] = None,
payload: Optional[Dict[str, Any]] = None,
@ -61,6 +62,7 @@ class StarRailBattleChronicleClient(BaseChronicleClient):
return await self.request_game_record(
endpoint,
endpoint_type=endpoint_type,
lang=lang,
game=Game.STARRAIL,
region=recognize_region(player_id, game=Game.STARRAIL),
@ -287,3 +289,32 @@ class StarRailBattleChronicleClient(BaseChronicleClient):
"""
data = await self._request_starrail_record("activity", uid, lang=lang)
return StarRailActivity(**data)
async def get_starrail_notes_by_stoken(
self,
lang: Optional[str] = None,
) -> StarRailNoteWidget:
"""Get StarRail's real-time notes.
Args:
lang (Optional[str], optional): The language of the data. Defaults to None.
Returns:
StarRailNoteWidget: The requested real-time notes.
Raises:
RegionNotSupported: If the region is not supported.
BadRequest: If the request is invalid.
"""
if self.region == Region.OVERSEAS:
raise RegionNotSupported("Notes widget is not supported in overseas region.")
stoken = self.cookies.get("stoken")
if stoken is None:
raise ValueError("stoken not found in cookies.")
stuid = self.cookies.get("stuid")
if stuid is None and self.account_id is None:
raise ValueError("account_id or stuid not found")
if self.account_id is not None and stuid is None:
self.cookies.set("stuid", str(self.account_id))
data = await self._request_starrail_record("widget", endpoint_type="aapi", lang=lang)
return StarRailNoteWidget(**data)

View File

@ -11,7 +11,6 @@ from simnet.client.components.wish.genshin import GenshinWishClient
from simnet.utils.enum_ import Region
from simnet.utils.types import CookieTypes, HeaderTypes, TimeoutTypes
class GenshinClient(
CalculatorClient,
GenshinBattleChronicleClient,

View File

@ -9,7 +9,6 @@ from simnet.client.components.wish.starrail import StarRailWishClient
from simnet.utils.enum_ import Region
from simnet.utils.types import CookieTypes, HeaderTypes, TimeoutTypes
class StarRailClient(
StarRailBattleChronicleClient, StarRailWishClient, StarrailDiaryClient, DailyRewardClient, AuthClient, LabClient
):

View File

@ -5,7 +5,7 @@ from pydantic import Field, root_validator
from simnet.models.base import APIModel
__all__ = ("Expedition", "Notes")
__all__ = ("Expedition", "Notes", "ExpeditionWidget", "NotesWidget")
def _process_timedelta(time: Union[int, timedelta, datetime]) -> datetime:
@ -184,3 +184,55 @@ class Notes(APIModel):
raise ValueError("Transformer recovery time cannot exceed 7 days.")
return values
class ExpeditionWidget(APIModel):
"""The model for a real-time expedition.
Attributes:
character (str): The expedition character icon url.
status (Literal["Ongoing", "Finished"]): The status of the expedition.
"""
character: str = Field(alias="avatar_side_icon")
status: Literal["Ongoing", "Finished"]
class NotesWidget(APIModel):
"""The model for real-time notes.
Attributes:
current_resin (int): The current amount of resin.
max_resin (int): The maximum amount of resin.
remaining_resin_recovery_time (timedelta): The remaining time until resin recovery.
current_realm_currency (int): The current amount of realm currency.
max_realm_currency (int): The maximum amount of realm currency.
completed_commissions (int): The number of completed commissions.
max_commissions (int): The maximum number of commissions.
claimed_commission_reward (bool): Whether the commission reward has been claimed.
expeditions (List[Expedition]): The list of expeditions.
max_expeditions (int): The maximum number of expeditions.
Raises:
ValueError: If the remaining resin recovery time is less than 0 or greater than 8 hours,
or if the remaining realm currency recovery time is less than 0 or greater than 24 hours.
"""
current_resin: int
max_resin: int
remaining_resin_recovery_time: timedelta = Field(alias="resin_recovery_time")
current_realm_currency: int = Field(alias="current_home_coin")
max_realm_currency: int = Field(alias="max_home_coin")
completed_commissions: int = Field(alias="finished_task_num")
max_commissions: int = Field(alias="total_task_num")
claimed_commission_reward: bool = Field(alias="is_extra_task_reward_received")
expeditions: List[ExpeditionWidget]
max_expeditions: int = Field(alias="max_expedition_num")
@property
def resin_recovery_time(self) -> datetime:
"""A property that returns the time when resin will be fully recovered."""
return datetime.now().astimezone() + self.remaining_resin_recovery_time

View File

@ -72,3 +72,41 @@ class StarRailNote(APIModel):
"""Remaining echo of war rewards"""
max_weekly_discounts: int = Field(alias="weekly_cocoon_limit")
"""Echo of war attempt limit"""
class StarRailNoteWidget(APIModel):
"""Represents a StarRail Note.
Attributes:
current_stamina (int): The current stamina of the user.
max_stamina (int): The maximum stamina of the user.
stamina_recover_time (timedelta): The time it takes for one stamina to recover.
accepted_expedition_num (int): The number of expeditions the user has accepted.
total_expedition_num (int): The total number of expeditions the user has participated in.
expeditions (Sequence[StarRailExpedition]): A list of expeditions the user has participated in.
current_train_score (int): The current daily training activity.
max_train_score (int): The max daily training activity.
current_rogue_score (int): The current simulated universe weekly points.
max_rogue_score (int): The max simulated universe weekly points.
has_signed (bool): Whether the user has signed in today.
"""
current_stamina: int
max_stamina: int
stamina_recover_time: timedelta
accepted_expedition_num: int
total_expedition_num: int
expeditions: Sequence[StarRailExpedition]
current_train_score: int
"""Current daily training activity"""
max_train_score: int
"""Max daily training activity"""
current_rogue_score: int
"""Current simulated universe weekly points"""
max_rogue_score: int
"""Max simulated universe weekly points"""
has_signed: bool
"""Whether the user has signed in today"""