mirror of
https://github.com/PaiGramTeam/SIMNet.git
synced 2024-11-22 06:17:57 +00:00
✨ support aapi
This commit is contained in:
parent
2e50bf2081
commit
d3b3a4b62e
@ -24,6 +24,7 @@ class BaseChronicleClient(BaseClient):
|
|||||||
async def request_game_record(
|
async def request_game_record(
|
||||||
self,
|
self,
|
||||||
endpoint: str,
|
endpoint: str,
|
||||||
|
endpoint_type: str = "api",
|
||||||
data: Optional[Any] = None,
|
data: Optional[Any] = None,
|
||||||
params: Optional[QueryParamTypes] = None,
|
params: Optional[QueryParamTypes] = None,
|
||||||
lang: Optional[str] = None,
|
lang: Optional[str] = None,
|
||||||
@ -34,6 +35,7 @@ class BaseChronicleClient(BaseClient):
|
|||||||
|
|
||||||
Args:
|
Args:
|
||||||
endpoint (str): The endpoint to send the request to.
|
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.
|
data (Optional[Any], optional): The request payload.
|
||||||
params (Optional[QueryParamTypes], optional): The query parameters for the request.
|
params (Optional[QueryParamTypes], optional): The query parameters for the request.
|
||||||
lang (Optional[str], optional): The language for the response.
|
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)
|
base_url = RECORD_URL.get_url(region or self.region)
|
||||||
|
|
||||||
if game:
|
if game:
|
||||||
base_url = base_url / game.value / "api"
|
base_url = base_url / game.value / endpoint_type
|
||||||
|
|
||||||
url = base_url / endpoint
|
url = base_url / endpoint
|
||||||
new_ds = self.region == Region.CHINESE
|
new_ds = self.region == Region.CHINESE
|
||||||
|
@ -2,17 +2,17 @@ import asyncio
|
|||||||
from typing import Optional, Any, List, Dict
|
from typing import Optional, Any, List, Dict
|
||||||
|
|
||||||
from simnet.client.components.chronicle.base import BaseChronicleClient
|
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.abyss import SpiralAbyss, SpiralAbyssPair
|
||||||
from simnet.models.genshin.chronicle.characters import Character
|
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 (
|
from simnet.models.genshin.chronicle.stats import (
|
||||||
PartialGenshinUserStats,
|
PartialGenshinUserStats,
|
||||||
GenshinUserStats,
|
GenshinUserStats,
|
||||||
FullGenshinUserStats,
|
FullGenshinUserStats,
|
||||||
)
|
)
|
||||||
from simnet.models.lab.record import RecordCard
|
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
|
from simnet.utils.player import recognize_genshin_server, recognize_region
|
||||||
|
|
||||||
__all__ = ("GenshinBattleChronicleClient",)
|
__all__ = ("GenshinBattleChronicleClient",)
|
||||||
@ -30,6 +30,7 @@ class GenshinBattleChronicleClient(BaseChronicleClient):
|
|||||||
endpoint: str,
|
endpoint: str,
|
||||||
player_id: Optional[int] = None,
|
player_id: Optional[int] = None,
|
||||||
method: str = "GET",
|
method: str = "GET",
|
||||||
|
endpoint_type: str = "api",
|
||||||
lang: Optional[str] = None,
|
lang: Optional[str] = None,
|
||||||
payload: Optional[Dict[str, Any]] = None,
|
payload: Optional[Dict[str, Any]] = None,
|
||||||
):
|
):
|
||||||
@ -37,6 +38,7 @@ class GenshinBattleChronicleClient(BaseChronicleClient):
|
|||||||
|
|
||||||
Args:
|
Args:
|
||||||
endpoint (str): The endpoint of the object to retrieve.
|
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.
|
player_id (Optional[int], optional): The player ID. Defaults to None.
|
||||||
method (str, optional): The HTTP method to use. Defaults to "GET".
|
method (str, optional): The HTTP method to use. Defaults to "GET".
|
||||||
lang (Optional[str], optional): The language of the data. Defaults to None.
|
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(
|
return await self.request_game_record(
|
||||||
endpoint,
|
endpoint,
|
||||||
|
endpoint_type=endpoint_type,
|
||||||
lang=lang,
|
lang=lang,
|
||||||
game=Game.GENSHIN,
|
game=Game.GENSHIN,
|
||||||
region=recognize_region(player_id, 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.
|
autoauth (bool, optional): Whether to automatically authenticate the user. Defaults to True.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
StarRailNote: The requested real-time notes.
|
Notes: The requested real-time notes.
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
BadRequest: If the request is invalid.
|
BadRequest: If the request is invalid.
|
||||||
@ -258,3 +261,32 @@ class GenshinBattleChronicleClient(BaseChronicleClient):
|
|||||||
return record_card
|
return record_card
|
||||||
|
|
||||||
return None
|
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)
|
||||||
|
@ -2,16 +2,16 @@ import asyncio
|
|||||||
from typing import Optional, Mapping, Dict, Any
|
from typing import Optional, Mapping, Dict, Any
|
||||||
|
|
||||||
from simnet.client.components.chronicle.base import BaseChronicleClient
|
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.lab.record import RecordCard
|
||||||
from simnet.models.starrail.chronicle.activity import StarRailActivity
|
from simnet.models.starrail.chronicle.activity import StarRailActivity
|
||||||
from simnet.models.starrail.chronicle.challenge import StarRailChallenge
|
from simnet.models.starrail.chronicle.challenge import StarRailChallenge
|
||||||
from simnet.models.starrail.chronicle.characters import StarRailDetailCharacters
|
from simnet.models.starrail.chronicle.characters import StarRailDetailCharacters
|
||||||
from simnet.models.starrail.chronicle.museum import StarRailMuseumBasic, StarRailMuseumDetail
|
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.rogue import StarRailRogue
|
||||||
from simnet.models.starrail.chronicle.stats import StarRailUserStats, StarRailUserInfo
|
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
|
from simnet.utils.player import recognize_starrail_server, recognize_region
|
||||||
|
|
||||||
__all__ = ("StarRailBattleChronicleClient",)
|
__all__ = ("StarRailBattleChronicleClient",)
|
||||||
@ -28,6 +28,7 @@ class StarRailBattleChronicleClient(BaseChronicleClient):
|
|||||||
self,
|
self,
|
||||||
endpoint: str,
|
endpoint: str,
|
||||||
player_id: Optional[int] = None,
|
player_id: Optional[int] = None,
|
||||||
|
endpoint_type: str = "api",
|
||||||
method: str = "GET",
|
method: str = "GET",
|
||||||
lang: Optional[str] = None,
|
lang: Optional[str] = None,
|
||||||
payload: Optional[Dict[str, Any]] = None,
|
payload: Optional[Dict[str, Any]] = None,
|
||||||
@ -61,6 +62,7 @@ class StarRailBattleChronicleClient(BaseChronicleClient):
|
|||||||
|
|
||||||
return await self.request_game_record(
|
return await self.request_game_record(
|
||||||
endpoint,
|
endpoint,
|
||||||
|
endpoint_type=endpoint_type,
|
||||||
lang=lang,
|
lang=lang,
|
||||||
game=Game.STARRAIL,
|
game=Game.STARRAIL,
|
||||||
region=recognize_region(player_id, 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)
|
data = await self._request_starrail_record("activity", uid, lang=lang)
|
||||||
return StarRailActivity(**data)
|
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)
|
||||||
|
@ -11,7 +11,6 @@ from simnet.client.components.wish.genshin import GenshinWishClient
|
|||||||
from simnet.utils.enum_ import Region
|
from simnet.utils.enum_ import Region
|
||||||
from simnet.utils.types import CookieTypes, HeaderTypes, TimeoutTypes
|
from simnet.utils.types import CookieTypes, HeaderTypes, TimeoutTypes
|
||||||
|
|
||||||
|
|
||||||
class GenshinClient(
|
class GenshinClient(
|
||||||
CalculatorClient,
|
CalculatorClient,
|
||||||
GenshinBattleChronicleClient,
|
GenshinBattleChronicleClient,
|
||||||
|
@ -9,7 +9,6 @@ from simnet.client.components.wish.starrail import StarRailWishClient
|
|||||||
from simnet.utils.enum_ import Region
|
from simnet.utils.enum_ import Region
|
||||||
from simnet.utils.types import CookieTypes, HeaderTypes, TimeoutTypes
|
from simnet.utils.types import CookieTypes, HeaderTypes, TimeoutTypes
|
||||||
|
|
||||||
|
|
||||||
class StarRailClient(
|
class StarRailClient(
|
||||||
StarRailBattleChronicleClient, StarRailWishClient, StarrailDiaryClient, DailyRewardClient, AuthClient, LabClient
|
StarRailBattleChronicleClient, StarRailWishClient, StarrailDiaryClient, DailyRewardClient, AuthClient, LabClient
|
||||||
):
|
):
|
||||||
|
@ -5,7 +5,7 @@ from pydantic import Field, root_validator
|
|||||||
|
|
||||||
from simnet.models.base import APIModel
|
from simnet.models.base import APIModel
|
||||||
|
|
||||||
__all__ = ("Expedition", "Notes")
|
__all__ = ("Expedition", "Notes", "ExpeditionWidget", "NotesWidget")
|
||||||
|
|
||||||
|
|
||||||
def _process_timedelta(time: Union[int, timedelta, datetime]) -> datetime:
|
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.")
|
raise ValueError("Transformer recovery time cannot exceed 7 days.")
|
||||||
|
|
||||||
return values
|
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
|
||||||
|
@ -72,3 +72,41 @@ class StarRailNote(APIModel):
|
|||||||
"""Remaining echo of war rewards"""
|
"""Remaining echo of war rewards"""
|
||||||
max_weekly_discounts: int = Field(alias="weekly_cocoon_limit")
|
max_weekly_discounts: int = Field(alias="weekly_cocoon_limit")
|
||||||
"""Echo of war attempt 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"""
|
||||||
|
Loading…
Reference in New Issue
Block a user