From a9facd46ac1f2d084db8796a935b2388633df4d6 Mon Sep 17 00:00:00 2001 From: Ivan Habunek Date: Tue, 2 Apr 2024 09:44:20 +0200 Subject: [PATCH] Add Clip typed dict --- twitchdl/commands/clips.py | 12 +++++------- twitchdl/commands/download.py | 4 ++-- twitchdl/commands/info.py | 5 +++-- twitchdl/output.py | 5 ++--- twitchdl/twitch.py | 34 ++++++++++++++++++++++++++++------ 5 files changed, 40 insertions(+), 20 deletions(-) diff --git a/twitchdl/commands/clips.py b/twitchdl/commands/clips.py index 67345ff..2af105c 100644 --- a/twitchdl/commands/clips.py +++ b/twitchdl/commands/clips.py @@ -1,17 +1,15 @@ -from typing import Generator import click import re import sys -from itertools import islice from os import path +from typing import Generator from twitchdl import twitch, utils from twitchdl.commands.download import get_clip_authenticated_url from twitchdl.download import download_file -from twitchdl.entities import Data from twitchdl.output import green, print_clip, print_json, print_paged, yellow - +from twitchdl.twitch import Clip def clips( @@ -54,7 +52,7 @@ def _continue(): return True -def _target_filename(clip: Data): +def _target_filename(clip: Clip): url = clip["videoQualities"][0]["sourceURL"] _, ext = path.splitext(url) ext = ext.lstrip(".") @@ -74,7 +72,7 @@ def _target_filename(clip: Data): return f"{name}.{ext}" -def _download_clips(generator: Generator[Data, None, None]): +def _download_clips(generator: Generator[Clip, None, None]): for clip in generator: target = _target_filename(clip) @@ -86,7 +84,7 @@ def _download_clips(generator: Generator[Data, None, None]): download_file(url, target) -def _print_all(generator: Generator[Data, None, None], all: bool): +def _print_all(generator: Generator[Clip, None, None], all: bool): for clip in generator: click.echo() print_clip(clip) diff --git a/twitchdl/commands/download.py b/twitchdl/commands/download.py index 4b6f378..15fab80 100644 --- a/twitchdl/commands/download.py +++ b/twitchdl/commands/download.py @@ -16,7 +16,7 @@ from urllib.parse import urlparse, urlencode from twitchdl import twitch, utils from twitchdl.download import download_file -from twitchdl.entities import Data, DownloadOptions +from twitchdl.entities import DownloadOptions from twitchdl.exceptions import ConsoleError from twitchdl.http import download_all from twitchdl.output import blue, bold, dim, green, print_log, yellow @@ -116,7 +116,7 @@ def _concat_vods(vod_paths: list[str], target: str): raise ConsoleError(f"Joining files failed: {result.stderr}") -def get_video_placeholders(video: Video, format: str) -> Data: +def get_video_placeholders(video: Video, format: str) -> dict[str, str]: date, time = video['publishedAt'].split("T") game = video["game"]["name"] if video["game"] else "Unknown" diff --git a/twitchdl/commands/info.py b/twitchdl/commands/info.py index c23c1c8..85e166e 100644 --- a/twitchdl/commands/info.py +++ b/twitchdl/commands/info.py @@ -3,9 +3,10 @@ import m3u8 from twitchdl import utils, twitch from twitchdl.commands.download import get_video_placeholders -from twitchdl.entities import Data from twitchdl.exceptions import ConsoleError from twitchdl.output import bold, print_table, print_video, print_clip, print_json, print_log +from twitchdl.twitch import Clip, Video + def info(id: str, *, json: bool = False): video_id = utils.parse_video_identifier(id) @@ -87,7 +88,7 @@ def video_json(video, playlists, chapters): print_json(video) -def clip_info(clip: Data): +def clip_info(clip: Clip): click.echo() print_clip(clip) click.echo() diff --git a/twitchdl/output.py b/twitchdl/output.py index 2873fcb..879e31e 100644 --- a/twitchdl/output.py +++ b/twitchdl/output.py @@ -5,8 +5,7 @@ from itertools import islice from twitchdl import utils from typing import Any, Callable, Generator, TypeVar -from twitchdl.entities import Data -from twitchdl.twitch import Video +from twitchdl.twitch import Clip, Video T = TypeVar("T") @@ -111,7 +110,7 @@ def print_video_compact(video: Video): click.echo(f"{bold(id)} {date} {green(title)} {blue(game)}") -def print_clip(clip: Data): +def print_clip(clip: Clip): published_at = clip["createdAt"].replace("T", " @ ").replace("Z", "") length = utils.format_duration(clip["durationSeconds"]) channel = clip["broadcaster"]["displayName"] diff --git a/twitchdl/twitch.py b/twitchdl/twitch.py index 3457655..5ef33c7 100644 --- a/twitchdl/twitch.py +++ b/twitchdl/twitch.py @@ -26,6 +26,25 @@ class Game(TypedDict): name: str +class VideoQuality(TypedDict): + frameRate: str + quality: str + sourceURL: str + + +class Clip(TypedDict): + id: str + slug: str + title: str + createdAt: str + viewCount: int + durationSeconds: int + url: str + videoQualities: list[VideoQuality] + game: Game + broadcaster: User + + class Video(TypedDict): id: str title: str @@ -134,7 +153,7 @@ def get_video(video_id: str) -> Video | None: return response["data"]["video"] -def get_clip(slug: str): +def get_clip(slug: str) -> Clip | None: query = f""" {{ clip(slug: "{slug}") {{ @@ -204,8 +223,12 @@ def get_channel_clips(channel_id: str, period: ClipsPeriod, limit: int, after: s return response["data"]["user"]["clips"] -def channel_clips_generator(channel_id: str, period: str, limit: int) -> Generator[Data, None, None]: - def _generator(clips: Data, limit: int) -> Generator[Data, None, None]: +def channel_clips_generator( + channel_id: str, + period: ClipsPeriod, + limit: int +) -> Generator[Clip, None, None]: + def _generator(clips: Data, limit: int) -> Generator[Clip, None, None]: for clip in clips["edges"]: if limit < 1: return @@ -226,11 +249,10 @@ def channel_clips_generator(channel_id: str, period: str, limit: int) -> Generat return _generator(clips, limit) -def channel_clips_generator_old(channel_id, period, limit): +def channel_clips_generator_old(channel_id: str, period: ClipsPeriod, limit: int): cursor = "" while True: - clips = get_channel_clips( - channel_id, period, limit, after=cursor) + clips = get_channel_clips(channel_id, period, limit, after=cursor) if not clips["edges"]: break