From 6cddc10b26891c7e34dd6f2ba3f2dd2092523ce2 Mon Sep 17 00:00:00 2001 From: Mantou-9487 Date: Fri, 8 Mar 2024 17:14:38 +0800 Subject: [PATCH] feat: Support Get User Data. --- tystream/async_api/twitch.py | 50 ++++++++++++++++++++++++++---------- tystream/data.py | 45 ++++++++++++++++++++++++++++++++ tystream/twitch.py | 43 +++++++++++++++++++++++-------- 3 files changed, 114 insertions(+), 24 deletions(-) diff --git a/tystream/async_api/twitch.py b/tystream/async_api/twitch.py index 20774ba..7f25a1b 100644 --- a/tystream/async_api/twitch.py +++ b/tystream/async_api/twitch.py @@ -5,7 +5,7 @@ from tystream.async_api.oauth import TwitchOauth from tystream.logger import setup_logging -from tystream.data import TwitchStreamData, TwitchVODData +from tystream.data import TwitchStreamData, TwitchVODData, TwitchUserData class Twitch: """ @@ -30,6 +30,31 @@ async def _get_headers(self): } return headers + async def get_user(self, streamer_name: str) -> TwitchUserData: + """ + Get Twitch User Info. + + Parameters + ---------- + streamer_name : :class:`str` + The streamer_name of the Twitch Live channel. + + Returns + ------- + :class:`TwitchUserData` + Twitch User Dataclass. + """ + headers = await self._get_headers() + + async with aiohttp.ClientSession() as session: + async with session.get( + "https://api.twitch.tv/helix/users?login=" + streamer_name, + headers=headers, + timeout=10 + ) as user: + user_data = await user.json()['data'] + return TwitchUserData(**user_data) + async def check_stream_live(self, streamer_name: str) -> TwitchStreamData: """ Check if stream is live. @@ -46,6 +71,8 @@ async def check_stream_live(self, streamer_name: str) -> TwitchStreamData: If the stream is not live, returned False. """ headers = await self._get_headers() + user = await self.get_user(streamer_name) + async with aiohttp.ClientSession() as session: async with session.get( "https://api.twitch.tv/helix/streams?user_login=" + streamer_name, @@ -56,8 +83,9 @@ async def check_stream_live(self, streamer_name: str) -> TwitchStreamData: if not stream_data["data"]: self.logger.log(25, "%s is not live.", streamer_name) return False + self.logger.log(25, "%s is live!", streamer_name) - return TwitchStreamData(**stream_data["data"][0]) + return TwitchStreamData(**stream_data["data"][0], user=user) async def get_stream_vod(self, streamer_name: str) -> TwitchVODData: """ @@ -77,19 +105,13 @@ async def get_stream_vod(self, streamer_name: str) -> TwitchVODData: It is recommended to execute this function\n after the Stream is end in order to retrieve the latest VOD data. """ - headers = self._get_headers() + headers = await self._get_headers() + user = await self.get_user(streamer_name) async with aiohttp.ClientSession() as session: async with session.get( - "https://api.twitch.tv/helix/users?login=" + streamer_name, + f"https://api.twitch.tv/helix/videos?user_id={user.id}&type=archive", headers=headers - ) as user: - user_data = user.json()["data"] - user_id = user_data["id"] - - async with session.get( - f"https://api.twitch.tv/helix/videos?user_id={user_id}&type=archive", - headers=headers - ) as vod: - vod_data = vod.json()["data"][0] - return TwitchVODData(**vod_data) + ) as vod: + vod_data = await vod.json()["data"][0] + return TwitchVODData(**vod_data) diff --git a/tystream/data.py b/tystream/data.py index d9d42f4..95c59fc 100644 --- a/tystream/data.py +++ b/tystream/data.py @@ -46,6 +46,48 @@ class Thumbnails: standard: Thumbnail maxres: Thumbnail +@dataclass +class TwitchUserData: + """ + Twitch User Dataclass. + + Attributes + ---------- + id: :class:`str` + An ID that identifies the user. + login: :class:`str` + The user's login name. + display_name: :class:`str` + The user's display name. + type: :class:`str` + The type of user. + broadcaster_type: :class:`str` + The type of broadcaster. + description: :class:`str` + The user's description of their channel. + profile_image_url: :class:`str` + A URL to the user's profile image. + offline_image_url: :class:`str` + A URL to the user's offline image. + view_count: :class:`int` + This field has been deprecated. don't use it. + email: :class:`str` + The user's verified email address. + created_at: :class:`str` + The UTC date and time that the user's account was created. + """ + id: str + login: str + display_name: str + type: str + broadcaster_type: str + description: str + profile_image_url: str + offline_image_url: str + view_count: int + email: str + created_at: str + @dataclass class TwitchStreamData: """ @@ -86,6 +128,8 @@ class TwitchStreamData: The tags applied to the stream. url: :class:`str` The stream’s url. + user: :class:`TwitchUserData` + The Streamer Info. """ id: int = field(default=None) user_id: int = field(default=None) @@ -102,6 +146,7 @@ class TwitchStreamData: is_mature: bool = field(repr=False, default_factory=bool, default=None) tag_ids: List = field(repr=False, default_factory=list, default=None) # deprecated flag too tags: List[str] = field(default_factory=list, default=None) + user: TwitchUserData = field(default=None) def __post_init__(self): self.url = "https://www.twitch.tv/" + self.user_login diff --git a/tystream/twitch.py b/tystream/twitch.py index 20abd66..5536fb0 100644 --- a/tystream/twitch.py +++ b/tystream/twitch.py @@ -8,7 +8,7 @@ from tystream.oauth import TwitchOauth from tystream.logger import setup_logging -from tystream.data import TwitchStreamData, TwitchVODData +from tystream.data import TwitchStreamData, TwitchVODData, TwitchUserData class Twitch: """ @@ -38,6 +38,32 @@ def _get_headers(self): } return headers + def get_user(self, streamer_name: str) -> TwitchUserData: + """ + Get Twitch User Info. + + Parameters + ---------- + streamer_name : :class:`str` + The streamer_name of the Twitch Live channel. + + Returns + ------- + :class:`TwitchUserData` + Twitch User Dataclass. + """ + headers = self._get_headers() + + user = requests.get( + "https://api.twitch.tv/helix/users?login=" + streamer_name, + headers=headers, + timeout=10 + ) + + user_data = user.json()['data'] + return TwitchUserData(**user_data) + + def check_stream_live(self, streamer_name: str) -> TwitchStreamData: """ Check if stream is live. @@ -54,6 +80,9 @@ def check_stream_live(self, streamer_name: str) -> TwitchStreamData: If the stream is not live, returned False. """ headers = self._get_headers() + + user = self.get_user(streamer_name) + stream = requests.get( "https://api.twitch.tv/helix/streams?user_login=" + streamer_name, headers=headers, @@ -65,7 +94,7 @@ def check_stream_live(self, streamer_name: str) -> TwitchStreamData: self.logger.log(25, "%s is not live.", streamer_name) return False self.logger.log(25, "%s is live!", streamer_name) - return TwitchStreamData(**stream_data["data"][0]) + return TwitchStreamData(**stream_data["data"][0], user=user) def get_stream_vod(self, streamer_name: str) -> TwitchVODData: """ @@ -87,16 +116,10 @@ def get_stream_vod(self, streamer_name: str) -> TwitchVODData: """ headers = self._get_headers() - user = requests.get( - "https://api.twitch.tv/helix/users?login=" + streamer_name, - headers=headers, - timeout=10 - ) - user_data = user.json()['data'] - user_id = user_data['id'] + user = self.get_user(streamer_name) vod = requests.get( - f"https://api.twitch.tv/helix/videos?user_id={user_id}&type=archive", + f"https://api.twitch.tv/helix/videos?user_id={user.id}&type=archive", headers=headers, timeout=10 )