Add Routes

This commit is contained in:
洛水居室 2023-05-01 19:24:44 +08:00
parent 73410f136e
commit 7294850914
No known key found for this signature in database
GPG Key ID: C9DE87DA724B88FC

156
simnet/client/routes.py Normal file
View File

@ -0,0 +1,156 @@
from typing import Dict, Union
from urllib.parse import urljoin
from httpx import URL as _URL
from simnet.utils.enum_ import Region, Game
URLTypes = Union["URL", str]
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))))
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
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:
RuntimeError: If the given region is not supported.
"""
if not self.urls[region]:
raise RuntimeError(f"URL does not support {region.name} region.")
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:
RuntimeError: If the given region or game is not supported.
"""
if not self.urls[region]:
raise RuntimeError(f"URL does not support {region.name} region.")
if not self.urls[region][game]:
raise RuntimeError(
f"URL does not support {game.name} game for {region.name} region."
)
return self.urls[region][game]