support oversea widget

This commit is contained in:
omg-xtao 2023-08-05 19:00:58 +08:00 committed by GitHub
parent 5c1b70e239
commit 4ebe5e006c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 165 additions and 15 deletions

View File

@ -2,10 +2,11 @@ import asyncio
from typing import Optional, Any, List, Dict
from simnet.client.components.chronicle.base import BaseChronicleClient
from simnet.errors import DataNotPublic, BadRequest, RegionNotSupported
from simnet.client.routes import RECORD_URL
from simnet.errors import DataNotPublic, BadRequest
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, NotesWidget
from simnet.models.genshin.chronicle.notes import Notes, NotesWidget, NotesOverseaWidget
from simnet.models.genshin.chronicle.stats import (
PartialGenshinUserStats,
GenshinUserStats,
@ -278,8 +279,6 @@ class GenshinBattleChronicleClient(BaseChronicleClient):
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.")
@ -288,5 +287,12 @@ class GenshinBattleChronicleClient(BaseChronicleClient):
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))
if self.region == Region.OVERSEAS:
route = RECORD_URL.get_url(self.region) / "../community/apihub/api/widget/data"
params = {"game_id": "2"}
data = await self.request_lab(route, params=params, lang=lang)
model = NotesOverseaWidget
else:
data = await self._request_genshin_record("widget/v2", endpoint_type="aapi", lang=lang)
return NotesWidget(**data)
model = NotesWidget
return model(**data)

View File

@ -1,14 +1,15 @@
import asyncio
from typing import Optional, Mapping, Dict, Any
from typing import Optional, Mapping, Dict, Any, Union
from simnet.client.components.chronicle.base import BaseChronicleClient
from simnet.errors import BadRequest, DataNotPublic, RegionNotSupported
from simnet.client.routes import RECORD_URL
from simnet.errors import BadRequest, DataNotPublic
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, StarRailNoteWidget
from simnet.models.starrail.chronicle.notes import StarRailNote, StarRailNoteWidget, StarRailNoteOverseaWidget
from simnet.models.starrail.chronicle.rogue import StarRailRogue
from simnet.models.starrail.chronicle.stats import StarRailUserStats, StarRailUserInfo
from simnet.utils.enum_ import Game, Region
@ -293,7 +294,7 @@ class StarRailBattleChronicleClient(BaseChronicleClient):
async def get_starrail_notes_by_stoken(
self,
lang: Optional[str] = None,
) -> StarRailNoteWidget:
) -> Union[StarRailNoteWidget, StarRailNoteOverseaWidget]:
"""Get StarRail's real-time notes.
Args:
@ -306,8 +307,6 @@ class StarRailBattleChronicleClient(BaseChronicleClient):
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.")
@ -316,5 +315,11 @@ class StarRailBattleChronicleClient(BaseChronicleClient):
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))
if self.region == Region.OVERSEAS:
route = RECORD_URL.get_url(self.region) / "../community/apihub/api/hsr_widget"
data = await self.request_lab(route, lang=lang)
model = StarRailNoteOverseaWidget
else:
data = await self._request_starrail_record("widget", endpoint_type="aapi", lang=lang)
return StarRailNoteWidget(**data)
model = StarRailNoteWidget
return model(**data)

View File

@ -5,7 +5,15 @@ from pydantic import Field, root_validator
from simnet.models.base import APIModel
__all__ = ("Expedition", "Notes", "ExpeditionWidget", "NotesWidget")
__all__ = [
"Expedition",
"Notes",
"ExpeditionWidget",
"NotesWidget",
"NotesOverseaWidget",
"NotesOverseaWidgetResin",
"NotesOverseaWidgetRealm",
]
def _process_timedelta(time: Union[int, timedelta, datetime]) -> datetime:
@ -236,3 +244,57 @@ class NotesWidget(APIModel):
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
class NotesOverseaWidgetResin(APIModel):
"""The model for real-time notes resin.
Attributes:
current_val (int): The current amount of resin.
max_val (int): The maximum amount of resin.
remaining_resin_recovery_time (timedelta): The remaining time until resin recovery.
"""
current_val: int
max_val: int
remaining_resin_recovery_time: timedelta = Field(alias="recovery_time")
@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
class NotesOverseaWidgetRealm(APIModel):
"""The model for real-time notes realm currency.
Attributes:
current_val (int): The current amount of realm currency.
max_val (int): The maximum amount of realm currency.
remaining_realm_currency_recovery_time (timedelta): The remaining time until realm currency recovery.
"""
current_val: int
max_val: int
remaining_realm_currency_recovery_time: timedelta = Field(alias="recovery_time")
@property
def realm_currency_recovery_time(self) -> datetime:
"""A property that returns the time when realm currency will be fully recovered."""
return datetime.now().astimezone() + self.remaining_realm_currency_recovery_time
class NotesOverseaWidget(APIModel):
"""The model for real-time notes.
Attributes:
resin (NotesOverseaWidgetResin): The resin information.
home_coin (NotesOverseaWidgetRealm): The realm currency information.
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.
"""
resin: NotesOverseaWidgetResin
home_coin: NotesOverseaWidgetRealm

View File

@ -110,3 +110,80 @@ class StarRailNoteWidget(APIModel):
has_signed: bool
"""Whether the user has signed in today"""
class StarRailNoteOverseaWidgetChallenge(APIModel):
"""Represents a StarRail Note.
Attributes:
begin_time (datetime): The time at which the challenge begins.
current_floor (int): The current floor of the challenge.
end_time (datetime): The time at which the challenge ends.
max_floor (int): The max floor of the challenge.
schedule_id (int): The ID of the challenge.
"""
begin_time: datetime
"""The time at which the challenge begins."""
current_floor: int
"""The current floor of the challenge."""
end_time: datetime
"""The time at which the challenge ends."""
max_floor: int
"""The max floor of the challenge."""
schedule_id: int
"""The ID of the challenge."""
class StarRailNoteOverseaWidgetRogue(APIModel):
"""Represents a StarRail Note.
Attributes:
current_rogue_score (int): The current simulated universe weekly points.
max_rogue_score (int): The max simulated universe weekly points.
schedule_end (datetime): The time at which the challenge ends.
schedule_start (datetime): The time at which the challenge begins.
"""
current_rogue_score: int
"""Current simulated universe weekly points"""
max_rogue_score: int
"""Max simulated universe weekly points"""
schedule_end: datetime
"""The time at which the challenge ends."""
schedule_start: datetime
"""The time at which the challenge begins."""
class StarRailNoteOverseaWidget(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.
challenge (StarRailNoteOverseaWidgetChallenge): The challenge widget.
rogue (StarRailNoteOverseaWidgetRogue): The rogue widget.
"""
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"""
challenge: StarRailNoteOverseaWidgetChallenge
"""The challenge widget."""
rogue: StarRailNoteOverseaWidgetRogue
"""The rogue widget."""