from __future__ import annotations
import datetime
from typing import Dict, List, Optional, TYPE_CHECKING
if TYPE_CHECKING:
from .types import (
BadgePayload,
GamemodePayload,
GamemodePlayerPayload,
OverallPlayerPayload,
PlayerPayload,
RankingPayload,
Region,
TestPayload,
TestPlayerPayload,
)
[docs]
class Badge:
__slots__ = (
"desc",
"title",
)
[docs]
def __init__(self, data: BadgePayload) -> None:
self.title: str = data["title"]
self.desc: str = data["desc"]
def __repr__(self) -> str:
return f"<Badge title={self.title!r}>"
[docs]
class Gamemode:
__slots__ = (
"discord_url",
"info_text",
"kit_image",
"slug",
"title",
)
[docs]
def __init__(
self,
*,
slug: str,
data: GamemodePayload,
) -> None:
self.slug: str = slug
self.title: str = data["title"]
self.info_text: Optional[str] = data.get("info_text")
self.kit_image: Optional[str] = data.get("kit_image")
self.discord_url: Optional[str] = data.get("discord_url")
def __repr__(self) -> str:
return f"<Gamemode slug={self.slug!r} title={self.title!r}>"
[docs]
class Ranking:
__slots__ = (
"attained",
"gamemode",
"peak_pos",
"peak_tier",
"pos",
"retired",
"tier",
)
[docs]
def __init__(
self,
*,
gamemode: str,
data: RankingPayload,
) -> None:
self.gamemode: str = gamemode
self.tier: int = data["tier"]
self.pos: int = data["pos"]
self.retired: bool = data["retired"]
self.attained: Optional[int] = data.get("attained")
self.peak_tier: Optional[int] = data["peak_tier"]
self.peak_pos: Optional[int] = data["peak_pos"]
def __repr__(self) -> str:
return (
f"<Ranking gamemode={self.gamemode!r} tier={self.tier} "
f"pos={self.pos} retired={self.retired}>"
)
@property
def is_high(self) -> bool:
return self.pos == 0
@property
def attained_at(self) -> Optional[datetime.datetime]:
if self.attained is None:
return None
return datetime.datetime.fromtimestamp(
self.attained,
datetime.timezone.utc
)
[docs]
class TestPlayer:
__slots__ = (
"discord_id",
"name",
"uuid",
)
[docs]
def __init__(self, data: TestPlayerPayload) -> None:
self.uuid: str = data["uuid"]
self.name: str = data["name"]
self.discord_id: Optional[str] = data.get("discord_id")
def __repr__(self) -> str:
return f"<TestPlayer uuid={self.uuid!r} name={self.name!r}>"
[docs]
class Test:
__slots__ = (
"at",
"gamemode",
"player",
"prev_pos",
"prev_tier",
"result_pos",
"result_tier",
"tester",
)
[docs]
def __init__(self, data: TestPayload) -> None:
self.gamemode: str = data["gamemode"]
self.at: int = data["at"]
self.result_tier: int = data["result_tier"]
self.result_pos: int = data["result_pos"]
self.prev_tier: Optional[int] = data.get("prev_tier")
self.prev_pos: Optional[int] = data.get("prev_pos")
player = data.get("player")
tester = data.get("tester")
self.player: Optional[TestPlayer] = TestPlayer(player) if player else None
self.tester: Optional[TestPlayer] = TestPlayer(tester) if tester else None
def __repr__(self) -> str:
return (
f"<Test gamemode={self.gamemode!r} result_tier={self.result_tier} "
f"result_pos={self.result_pos}>"
)
@property
def occurred_at(self) -> datetime.datetime:
return datetime.datetime.fromtimestamp(
self.at,
datetime.timezone.utc
)
class _RankedPlayer:
__slots__ = (
"name",
"rankings",
"region",
"uuid",
)
if TYPE_CHECKING:
region: Region
def _update_ranked_player(
self,
data: OverallPlayerPayload,
) -> None:
self.uuid: str = data["uuid"]
self.name: str = data["name"]
self.region = data["region"]
self.rankings: Dict[str, Ranking] = {
gamemode: Ranking(
gamemode=gamemode,
data=ranking
)
for gamemode, ranking in data.get("rankings", {}).items()
}
[docs]
class OverallPlayer(_RankedPlayer):
__slots__ = (
"points",
)
[docs]
def __init__(self, data: OverallPlayerPayload) -> None:
self._update_ranked_player(data)
self.points: int = data["points"]
def __repr__(self) -> str:
return (
f"<OverallPlayer uuid={self.uuid!r} name={self.name!r} "
f"points={self.points}>"
)
[docs]
class GamemodePlayer:
__slots__ = (
"name",
"pos",
"region",
"uuid",
)
if TYPE_CHECKING:
region: Region
[docs]
def __init__(self, data: GamemodePlayerPayload) -> None:
self.uuid: str = data["uuid"]
self.name: str = data["name"]
self.region = data["region"]
self.pos: int = data["pos"]
def __repr__(self) -> str:
return (
f"<GamemodePlayer uuid={self.uuid!r} name={self.name!r} "
f"pos={self.pos}>"
)
@property
def is_high(self) -> bool:
return self.pos == 0
[docs]
class Player(_RankedPlayer):
__slots__ = (
"badges",
"discord_id",
"overall",
"points",
"tests",
)
[docs]
def __init__(self, data: PlayerPayload) -> None:
self._update_ranked_player(data)
self.overall: int = data["overall"]
self.points: int = data["points"]
self.discord_id: Optional[str] = data.get("discord_id")
self.tests: List[Test] = [
Test(test)
for test in data.get("tests", [])
]
self.badges: List[Badge] = [
Badge(badge)
for badge in data.get("badges", [])
]
def __repr__(self) -> str:
return (
f"<Player uuid={self.uuid!r} name={self.name!r} "
f"overall={self.overall} points={self.points}>"
)