SIMNet/simnet/client/routes.py

369 lines
11 KiB
Python
Raw Permalink Normal View History

2023-05-01 11:24:44 +00:00
from typing import Dict, Union
from urllib.parse import urljoin
from httpx import URL as _URL
from simnet.errors import RegionNotSupported, NotSupported
2023-12-27 07:09:24 +00:00
from simnet.utils.enums import Region, Game
2023-05-01 11:24:44 +00:00
URLTypes = Union["URL", str]
__all__ = (
"URL",
"BaseRoute",
"Route",
"InternationalRoute",
"GameRoute",
"RECORD_URL",
"GACHA_INFO_URL",
"AUTH_URL",
"PASSPORT_URL",
"WEB_ACCOUNT_URL",
"AUTH_KEY_URL",
"HK4E_LOGIN_URL",
2023-05-05 14:15:40 +00:00
"REWARD_URL",
2023-05-08 02:00:01 +00:00
"TAKUMI_URL",
"CALCULATOR_URL",
2023-06-09 03:48:56 +00:00
"DETAIL_LEDGER_URL",
"INFO_LEDGER_URL",
2023-05-08 02:00:01 +00:00
"HK4E_URL",
"CODE_URL",
2023-09-15 15:19:49 +00:00
"CODE_HOYOLAB_URL",
2023-06-09 11:50:48 +00:00
"YSULOG_URL",
"QRCODE_URL",
2024-01-17 08:47:06 +00:00
"GET_FP_URL",
2024-04-12 14:02:31 +00:00
"BBS_URL",
2024-06-17 16:09:38 +00:00
"SELF_HELP_URL",
)
2023-05-01 11:24:44 +00:00
class URL(_URL):
"""A subclass of httpx's URL class, with additional convenience methods for URL manipulation."""
def join(self, url: URLTypes) -> "URL":
"""
Join the current URL with the given URL.
Args:
url (Union[URL, str]): The URL to join with.
Returns:
URL: A new URL instance representing the joined URL.
"""
return URL(urljoin(str(self), str(URL(url))))
def __truediv__(self, url: URLTypes) -> "URL":
"""
Append the given URL to the current URL using the '/' operator.
Args:
url (Union[URL, str]): The URL to append.
Returns:
URL: A new URL instance representing the joined URL.
"""
return URL(urljoin(str(self) + "/", str(URL(url))))
2023-06-11 14:19:20 +00:00
def __bool__(self):
"""Return True if the URL is not empty.
Returns:
bool: True if the URL is not empty.
"""
return str(self) != ""
def replace(self, old: str, new: str) -> "URL":
"""
Replace a substring in the URL.
Args:
old (str): The substring to replace.
new (str): The new substring to replace with.
Returns:
URL: A new URL instance with the substring replaced.
"""
return URL(str(self).replace(old, new))
2023-05-01 11:24:44 +00:00
class BaseRoute:
"""A base class for defining routes with useful metadata."""
class Route(BaseRoute):
"""A standard route with a single URL."""
url: URL
def __init__(self, url: str) -> None:
"""
Initialize a Route instance.
Args:
url (str): The URL for this route.
"""
self.url = URL(url)
def get_url(self) -> URL:
"""
Get the URL for this route.
Returns:
URL: The URL for this route.
"""
return self.url
def __truediv__(self, other: str) -> URL:
"""
Append the given URL to this route using the '/' operator.
Args:
other (Union[URL, str]): The URL to append.
Returns:
URL: A new URL instance representing the joined URL.
"""
return self.url / other
2023-05-01 11:24:44 +00:00
class InternationalRoute(BaseRoute):
"""A route with URLs for both the overseas and Chinese regions."""
urls: Dict[Region, URL]
def __init__(self, overseas: str, chinese: str) -> None:
"""
Initialize an InternationalRoute instance.
Args:
overseas (str): The URL for the overseas region.
chinese (str): The URL for the Chinese region.
"""
self.urls = {
Region.OVERSEAS: URL(overseas),
Region.CHINESE: URL(chinese),
}
def get_url(self, region: Region) -> URL:
"""
Get the URL for the given region.
Args:
region (Region): The region to get the URL for.
Returns:
URL: The URL for the given region.
Raises:
RegionNotSupported: If the given region is not supported.
2023-05-01 11:24:44 +00:00
"""
if not self.urls[region]:
raise RegionNotSupported(f"URL does not support {region.name} region.")
2023-05-01 11:24:44 +00:00
return self.urls[region]
class GameRoute(BaseRoute):
"""A route with URLs for different games and regions."""
urls: Dict[Region, Dict[Game, URL]]
def __init__(
self,
overseas: Dict[str, str],
chinese: Dict[str, str],
) -> None:
"""
Initialize a GameRoute instance.
Args:
overseas (Dict[str, str]): A dictionary mapping game names to URLs for the overseas region.
chinese (Dict[str, str]): A dictionary mapping game names to URLs for the Chinese region.
"""
self.urls = {
Region.OVERSEAS: {Game(game): URL(url) for game, url in overseas.items()},
Region.CHINESE: {Game(game): URL(url) for game, url in chinese.items()},
}
def get_url(self, region: Region, game: Game) -> URL:
"""
Get the URL for the given region and game.
Args:
region (Region): The region to get the URL for.
game (Game): The game to get the URL for.
Returns:
URL: The URL for the given region and game.
Raises:
RegionNotSupported: If the given region is not supported.
GameNotSupported: If the given game is not supported.
2023-05-01 11:24:44 +00:00
"""
if not self.urls[region]:
raise RegionNotSupported(f"URL does not support {region.name} region.")
2023-05-01 11:24:44 +00:00
if not self.urls[region][game]:
raise NotSupported(f"URL does not support {game.name} game for {region.name} region.")
2023-05-01 11:24:44 +00:00
return self.urls[region][game]
2023-05-01 12:50:48 +00:00
2024-07-05 13:58:00 +00:00
RECORD_URL = GameRoute(
overseas=dict(
genshin="https://bbs-api-os.hoyolab.com/game_record",
hkrpg="https://bbs-api-os.hoyolab.com/game_record",
nap="https://sg-act-nap-api.hoyolab.com/event/game_record_zzz",
),
chinese=dict(
genshin="https://api-takumi-record.mihoyo.com/game_record/app",
hkrpg="https://api-takumi-record.mihoyo.com/game_record/app",
nap="https://api-takumi-record.mihoyo.com/event/game_record_zzz",
),
2023-05-01 12:50:48 +00:00
)
GACHA_INFO_URL = GameRoute(
overseas=dict(
2024-08-07 07:43:04 +00:00
genshin="https://public-operation-hk4e-sg.hoyoverse.com/gacha_info/api",
hkrpg="https://public-operation-hkrpg-sg.hoyoverse.com/common/gacha_record/api/",
2024-07-05 14:26:19 +00:00
nap="https://public-operation-nap-sg.hoyoverse.com/common/gacha_record/api",
2023-05-01 12:50:48 +00:00
),
chinese=dict(
2024-04-24 04:06:56 +00:00
genshin="https://public-operation-hk4e.mihoyo.com/gacha_info/api",
2024-08-07 07:43:04 +00:00
hkrpg="https://public-operation-hkrpg.mihoyo.com/common/gacha_record/api",
2024-07-05 13:58:00 +00:00
nap="https://public-operation-nap.mihoyo.com/common/gacha_record/api",
2023-05-01 12:50:48 +00:00
),
)
2023-05-04 15:51:24 +00:00
AUTH_URL = InternationalRoute(
overseas="https://api-os-takumi.mihoyo.com/auth/api",
2023-05-04 15:51:24 +00:00
chinese="https://api-takumi.mihoyo.com/auth/api",
)
PASSPORT_URL = InternationalRoute(
overseas="https://api-account-os.hoyoverse.com/account/auth/api/",
chinese="https://passport-api.mihoyo.com/account/auth/api/",
2023-05-04 15:51:24 +00:00
)
WEB_ACCOUNT_URL = InternationalRoute(
overseas="https://webapi-os.account.hoyoverse.com/Api/",
chinese="https://webapi.account.mihoyo.com/Api/",
2023-05-04 15:51:24 +00:00
)
2023-09-11 11:32:44 +00:00
AUTH_KEY_URL = InternationalRoute(
overseas="https://sg-public-api.hoyoverse.com/binding/api/genAuthKey",
chinese="https://api-takumi.mihoyo.com/binding/api/genAuthKey",
)
2023-05-04 15:51:24 +00:00
HK4E_LOGIN_URL = InternationalRoute(
overseas="https://sg-public-api.hoyoverse.com/common/badge/v1/login/account",
chinese="https://api-takumi.mihoyo.com/common/badge/v1/login/account",
)
2023-05-05 14:15:40 +00:00
REWARD_URL = GameRoute(
overseas=dict(
2023-07-18 13:27:23 +00:00
genshin="https://sg-hk4e-api.hoyolab.com/event/sol/?act_id=e202102251931481",
honkai3rd="https://sg-public-api.hoyolab.com/event/mani/?act_id=e202110291205111",
2023-05-05 14:15:40 +00:00
hkrpg="https://sg-public-api.hoyolab.com/event/luna/os/?act_id=e202303301540311",
2024-07-05 13:58:00 +00:00
nap="https://sg-act-nap-api.hoyolab.com/event/luna/zzz/os/?act_id=e202406031448091",
2023-05-05 14:15:40 +00:00
),
chinese=dict(
2023-12-01 03:09:32 +00:00
genshin="https://api-takumi.mihoyo.com/event/luna/?act_id=e202311201442471",
2023-05-05 14:15:40 +00:00
honkai3rd="https://api-takumi.mihoyo.com/event/luna/?act_id=e202207181446311",
hkrpg="https://api-takumi.mihoyo.com/event/luna/?act_id=e202304121516551",
2024-07-05 13:58:00 +00:00
nap="https://act-nap-api.mihoyo.com/event/luna/zzz/?act_id=e202406242138391",
2023-05-05 14:15:40 +00:00
),
)
2023-05-08 02:00:01 +00:00
TAKUMI_URL = InternationalRoute(
overseas="https://api-os-takumi.mihoyo.com/",
chinese="https://api-takumi.mihoyo.com/",
)
2024-01-23 09:51:22 +00:00
CALCULATOR_URL = GameRoute(
overseas=dict(
genshin="https://sg-public-api.hoyoverse.com/event/calculateos/",
hkrpg="https://sg-public-api.hoyolab.com/event/rpgcalc/",
),
chinese=dict(
genshin="https://api-takumi.mihoyo.com/event/e20200928calculate/v1/",
hkrpg="https://api-takumi.mihoyo.com/event/rpgcalc/",
),
2023-05-08 02:00:01 +00:00
)
2023-06-11 14:19:20 +00:00
DETAIL_LEDGER_URL = GameRoute(
overseas=dict(
genshin="https://sg-hk4e-api.hoyolab.com/event/ysledgeros/month_detail",
2023-06-23 14:54:42 +00:00
hkrpg="https://sg-public-api.hoyolab.com/event/srledger/month_detail",
2024-09-25 15:14:21 +00:00
nap="https://sg-public-api.hoyolab.com/event/nap_ledger/month_detail",
2023-06-11 14:19:20 +00:00
),
chinese=dict(
genshin="https://hk4e-api.mihoyo.com/event/ys_ledger/monthDetail",
hkrpg="https://api-takumi.mihoyo.com/event/srledger/month_detail",
2024-09-25 15:14:21 +00:00
nap="https://api-takumi.mihoyo.com/event/nap_ledger/month_detail",
2023-06-11 14:19:20 +00:00
),
2023-06-09 03:48:56 +00:00
)
INFO_LEDGER_URL = GameRoute(
overseas=dict(
genshin="https://sg-hk4e-api.hoyolab.com/event/ysledgeros/month_info",
2023-06-23 14:54:42 +00:00
hkrpg="https://sg-public-api.hoyolab.com/event/srledger/month_info",
2024-09-25 15:14:21 +00:00
nap="https://sg-public-api.hoyolab.com/event/nap_ledger/month_info",
2023-06-09 03:48:56 +00:00
),
chinese=dict(
genshin="https://hk4e-api.mihoyo.com/event/ys_ledger/monthInfo",
hkrpg="https://api-takumi.mihoyo.com/event/srledger/month_info",
2024-09-25 15:14:21 +00:00
nap="https://api-takumi.mihoyo.com/event/nap_ledger/month_info",
2023-06-09 03:48:56 +00:00
),
)
2023-06-09 11:50:48 +00:00
YSULOG_URL = InternationalRoute(
2023-07-17 05:14:40 +00:00
overseas="https://hk4e-api-os.hoyoverse.com/common/hk4e_self_help_query/User/",
chinese="https://hk4e-api.mihoyo.com/common/hk4e_self_help_query/User/",
2023-06-09 11:50:48 +00:00
)
2023-05-08 02:00:01 +00:00
HK4E_URL = Route("https://sg-hk4e-api.hoyoverse.com/common/hk4e_global/")
2024-09-10 12:35:09 +00:00
CODE_URL = GameRoute(
overseas=dict(
genshin="https://sg-hk4e-api.hoyoverse.com/common/apicdkey/api/webExchangeCdkey",
hkrpg="https://sg-hkrpg-api.hoyoverse.com/common/apicdkey/api/webExchangeCdkeyRisk",
nap="https://public-operation-nap.hoyoverse.com/common/apicdkey/api/webExchangeCdkey",
),
chinese={},
)
2023-09-15 15:19:49 +00:00
CODE_HOYOLAB_URL = GameRoute(
overseas=dict(
genshin="https://sg-hk4e-api.hoyolab.com/common/apicdkey/api/webExchangeCdkeyHyl",
hkrpg="https://sg-hkrpg-api.hoyolab.com/common/apicdkey/api/webExchangeCdkeyHyl",
2024-07-05 13:58:00 +00:00
nap="https://public-operation-nap.hoyoverse.com/common/apicdkey/api/webExchangeCdkey",
2023-09-15 15:19:49 +00:00
),
2023-09-15 15:24:01 +00:00
chinese={},
2023-09-15 15:19:49 +00:00
)
QRCODE_URL = Route("https://hk4e-sdk.mihoyo.com/hk4e_cn/combo/panda/qrcode")
2024-01-17 08:47:06 +00:00
GET_FP_URL = Route("https://public-data-api.mihoyo.com/device-fp/api/getFp")
2024-04-12 14:02:31 +00:00
BBS_URL = InternationalRoute(
overseas="https://bbs-api-os.hoyolab.com",
chinese="https://bbs-api.miyoushe.com",
)
2024-06-17 16:09:38 +00:00
SELF_HELP_URL = GameRoute(
overseas={},
chinese=dict(
genshin="https://hk4e-api.mihoyo.com/common/hk4e_self_help_query",
hkrpg="https://api-takumi.mihoyo.com/common/hkrpg_self_help_inquiry",
2024-07-06 05:13:17 +00:00
nap="https://public-operation-nap.mihoyo.com/common/nap_self_help_query",
2024-06-17 16:09:38 +00:00
),
)