diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 79e38cd..b5b2936 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -7,9 +7,9 @@ To be released * Fixed ``wbtime`` and ``btime`` for all endpoints returning a ``GameState``. * Added ``sheet`` optional parameter to ``Tournaments.stream_results``, and fix returned typed dict. * Added ``studies.import_pgn`` to import PGN to study +* Added ``tv.stream_current_game_of_channel`` to stream the current TV game of a channel - -Thanks to @nicvagn, @tors42 and @fitztrev for their contributions to this release. +Thanks to @nicvagn, @tors42, @fitztrev and @trevorbayless for their contributions to this release. v0.13.2 (2023-12-04) -------------------- diff --git a/berserk/__init__.py b/berserk/__init__.py index 9c5eb42..ad31f63 100644 --- a/berserk/__init__.py +++ b/berserk/__init__.py @@ -23,6 +23,7 @@ PuzzleRace, SwissInfo, SwissResult, + TVFeed, ) from .session import TokenSession from .session import Requestor @@ -54,4 +55,5 @@ "SwissResult", "Team", "TokenSession", + "TVFeed", ] diff --git a/berserk/clients/tv.py b/berserk/clients/tv.py index f805135..cf60228 100644 --- a/berserk/clients/tv.py +++ b/berserk/clients/tv.py @@ -1,9 +1,10 @@ from __future__ import annotations -from typing import Any, Iterator, Dict, List +from typing import Any, Iterator, Dict, List, cast from .. import models from ..formats import NDJSON_LIST, PGN +from ..types import TVFeed from .base import FmtClient @@ -18,22 +19,24 @@ def get_current_games(self) -> Dict[str, Any]: path = "/api/tv/channels" return self._r.get(path) - def stream_current_game(self) -> Iterator[Dict[str, Any]]: + def stream_current_game(self) -> Iterator[TVFeed]: """Streams the current TV game. :return: positions and moves of the current TV game """ path = "/api/tv/feed" - yield from self._r.get(path, stream=True) + for response in self._r.get(path, stream=True): + yield cast(TVFeed, response) - def stream_current_game_of_channel(self, channel: str) -> Iterator[Dict[str, Any]]: + def stream_current_game_of_channel(self, channel: str) -> Iterator[TVFeed]: """Streams the current TV game of a channel. :param channel: the TV channel to stream. :return: positions and moves of the channels current TV game """ path = f"/api/tv/{channel}/feed" - yield from self._r.get(path, stream=True) + for response in self._r.get(path, stream=True): + yield cast(TVFeed, response) def get_best_ongoing( self, diff --git a/berserk/types/__init__.py b/berserk/types/__init__.py index 5962bb9..52b9ec0 100644 --- a/berserk/types/__init__.py +++ b/berserk/types/__init__.py @@ -14,6 +14,7 @@ from .studies import ChapterIdName from .team import PaginatedTeams, Team from .tournaments import ArenaResult, CurrentTournaments, SwissResult, SwissInfo +from .tv import TVFeed __all__ = [ "AccountInformation", @@ -41,4 +42,5 @@ "SwissResult", "Team", "Variant", + "TVFeed", ] diff --git a/berserk/types/common.py b/berserk/types/common.py index 0ad2b95..dfb818b 100644 --- a/berserk/types/common.py +++ b/berserk/types/common.py @@ -64,6 +64,8 @@ class LightUser(TypedDict): name: str # The title of the user title: NotRequired[Title] + # The flair of the user + flair: NotRequired[str] # The patron of the user patron: NotRequired[bool] diff --git a/berserk/types/tv.py b/berserk/types/tv.py new file mode 100644 index 0000000..67b79b1 --- /dev/null +++ b/berserk/types/tv.py @@ -0,0 +1,33 @@ +from __future__ import annotations + +from typing import List, Literal +from typing_extensions import TypedDict, NotRequired + +from .common import LightUser, Color + + +class Player(TypedDict): + color: Color + user: NotRequired[LightUser] + ai: NotRequired[int] + rating: NotRequired[int] + seconds: int + + +class FeaturedData(TypedDict): + id: str + orientation: Color + players: List[Player] + fen: str + + +class MoveData(TypedDict): + fen: str + lm: str + wc: int + bc: int + + +class TVFeed(TypedDict): + t: Literal["featured", "fen"] + d: FeaturedData | MoveData