diff --git a/changelog.yaml b/changelog.yaml index d59d1ba..558957e 100644 --- a/changelog.yaml +++ b/changelog.yaml @@ -7,6 +7,7 @@ - "Add setting defaults via environment variables, see: https://twitch-dl.bezdomni.net/environment_variables.html" - "Add `download --concat` option to avoid using ffmeg for joinig vods and concat them instead. This will produce a `.ts` file by default." - "Add video description to metadata (#129)" + - "Add `clips --compact` option for listing clips in one-per-line mode" 2.1.4: date: 2024-01-06 diff --git a/twitchdl/cli.py b/twitchdl/cli.py index 2745cb3..5be4976 100644 --- a/twitchdl/cli.py +++ b/twitchdl/cli.py @@ -101,6 +101,12 @@ def cli(ctx: click.Context, color: bool, debug: bool): help="Fetch all clips, overrides --limit", is_flag=True, ) +@click.option( + "-c", + "--compact", + help="Show clips in compact mode, one line per video", + is_flag=True, +) @click.option( "-d", "--download", @@ -110,9 +116,8 @@ def cli(ctx: click.Context, color: bool, debug: bool): @click.option( "-l", "--limit", - help="Number of clips to fetch [max: 100]", + help="Number of clips to fetch. Defaults to 40 in compact mode, 10 otherwise.", type=int, - default=10, callback=validate_positive, ) @click.option( @@ -135,9 +140,10 @@ def cli(ctx: click.Context, color: bool, debug: bool): def clips( channel_name: str, all: bool, + compact: bool, download: bool, json: bool, - limit: int, + limit: int | None, pager: int | None, period: ClipsPeriod, ): @@ -147,6 +153,7 @@ def clips( clips( channel_name, all=all, + compact=compact, download=download, json=json, limit=limit, diff --git a/twitchdl/commands/clips.py b/twitchdl/commands/clips.py index 0f9d420..d3288ac 100644 --- a/twitchdl/commands/clips.py +++ b/twitchdl/commands/clips.py @@ -1,14 +1,14 @@ import re import sys from os import path -from typing import Generator +from typing import Callable, Generator import click from twitchdl import twitch, utils from twitchdl.commands.download import get_clip_authenticated_url from twitchdl.download import download_file -from twitchdl.output import green, print_clip, print_json, print_paged, yellow +from twitchdl.output import green, print_clip, print_clip_compact, print_json, print_paged, yellow from twitchdl.twitch import Clip @@ -16,14 +16,18 @@ def clips( channel_name: str, *, all: bool = False, + compact: bool = False, download: bool = False, json: bool = False, - limit: int = 10, + limit: int | None = None, pager: int | None = None, period: twitch.ClipsPeriod = "all_time", ): + # Set different defaults for limit for compact display + default_limit = 40 if compact else 10 + # Ignore --limit if --pager or --all are given - limit = sys.maxsize if all or pager else limit + limit = sys.maxsize if all or pager else (limit or default_limit) generator = twitch.channel_clips_generator(channel_name, period, limit) @@ -33,23 +37,12 @@ def clips( if download: return _download_clips(generator) + print_fn = print_clip_compact if compact else print_clip + if pager: - return print_paged("Clips", generator, print_clip, pager) + return print_paged("Clips", generator, print_fn, pager) - return _print_all(generator, all) - - -def _continue(): - enter = click.style("Enter", bold=True, fg="green") - ctrl_c = click.style("Ctrl+C", bold=True, fg="yellow") - click.echo(f"Press {enter} to continue, {ctrl_c} to break.") - - try: - input() - except KeyboardInterrupt: - return False - - return True + return _print_all(generator, print_fn, all) def _target_filename(clip: Clip): @@ -86,10 +79,13 @@ def _download_clips(generator: Generator[Clip, None, None]): download_file(url, target) -def _print_all(generator: Generator[Clip, None, None], all: bool): +def _print_all( + generator: Generator[Clip, None, None], + print_fn: Callable[[Clip], None], + all: bool, +): for clip in generator: - click.echo() - print_clip(clip) + print_fn(clip) if not all: click.secho( diff --git a/twitchdl/output.py b/twitchdl/output.py index 6695393..2286823 100644 --- a/twitchdl/output.py +++ b/twitchdl/output.py @@ -1,10 +1,10 @@ -import click import json - from itertools import islice -from twitchdl import utils from typing import Any, Callable, Generator, TypeVar +import click + +from twitchdl import utils from twitchdl.twitch import Clip, Video T = TypeVar("T") @@ -124,6 +124,17 @@ def print_clip(clip: Clip): + f" Views: {blue(clip['viewCount'])}" ) click.secho(clip["url"], italic=True) + click.echo() + + +def print_clip_compact(clip: Clip): + slug = clip["slug"] + date = clip["createdAt"][:10] + title = truncate(clip["title"], 50).ljust(50) + game = clip["game"]["name"] if clip["game"] else "" + game = truncate(game, 30).ljust(30) + + click.echo(f"{date} {green(title)} {blue(game)} {bold(slug)}") def prompt_continue():