twitch-dl/twitchdl/commands/clips.py

98 lines
2.5 KiB
Python
Raw Normal View History

2024-04-01 07:40:54 +00:00
import click
2021-01-07 08:34:14 +00:00
import re
import sys
2021-01-07 08:34:14 +00:00
from os import path
2024-04-02 07:44:20 +00:00
from typing import Generator
2021-01-07 08:34:14 +00:00
from twitchdl import twitch, utils
from twitchdl.commands.download import get_clip_authenticated_url
2021-01-07 08:34:14 +00:00
from twitchdl.download import download_file
2024-04-01 07:40:54 +00:00
from twitchdl.output import green, print_clip, print_json, print_paged, yellow
2024-04-02 07:44:20 +00:00
from twitchdl.twitch import Clip
2021-01-07 08:34:14 +00:00
2024-03-23 09:50:42 +00:00
def clips(
channel_name: str,
*,
all: bool = False,
download: bool = False,
json: bool = False,
limit: int = 10,
pager: int | None = None,
2024-04-01 07:40:54 +00:00
period: twitch.ClipsPeriod = "all_time",
2024-03-23 09:50:42 +00:00
):
# Ignore --limit if --pager or --all are given
2024-03-23 09:50:42 +00:00
limit = sys.maxsize if all or pager else limit
2024-03-23 09:50:42 +00:00
generator = twitch.channel_clips_generator(channel_name, period, limit)
2024-03-23 09:50:42 +00:00
if json:
return print_json(list(generator))
2021-05-18 12:25:49 +00:00
2024-03-23 09:50:42 +00:00
if download:
return _download_clips(generator)
2024-03-23 09:50:42 +00:00
if pager:
2024-04-01 07:40:54 +00:00
return print_paged("Clips", generator, print_clip, pager)
2021-05-18 12:25:49 +00:00
2024-03-23 09:50:42 +00:00
return _print_all(generator, all)
2021-05-18 12:25:49 +00:00
2021-01-07 08:34:14 +00:00
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.")
2021-01-07 08:34:14 +00:00
try:
input()
except KeyboardInterrupt:
return False
return True
2024-04-02 07:44:20 +00:00
def _target_filename(clip: Clip):
2021-01-07 08:34:14 +00:00
url = clip["videoQualities"][0]["sourceURL"]
_, ext = path.splitext(url)
ext = ext.lstrip(".")
match = re.search(r"^(\d{4})-(\d{2})-(\d{2})T", clip["createdAt"])
2024-03-23 09:50:42 +00:00
if not match:
raise ValueError(f"Failed parsing date from: {clip['createdAt']}")
2021-01-07 08:34:14 +00:00
date = "".join(match.groups())
name = "_".join([
date,
clip["id"],
2021-01-14 20:38:56 +00:00
clip["broadcaster"]["login"],
2021-01-07 08:34:14 +00:00
utils.slugify(clip["title"]),
])
2024-03-28 11:06:50 +00:00
return f"{name}.{ext}"
2021-01-07 08:34:14 +00:00
2024-04-02 07:44:20 +00:00
def _download_clips(generator: Generator[Clip, None, None]):
for clip in generator:
target = _target_filename(clip)
2021-05-18 12:23:56 +00:00
if path.exists(target):
click.echo(f"Already downloaded: {green(target)}")
else:
url = get_clip_authenticated_url(clip["slug"], "source")
click.echo(f"Downloading: {yellow(target)}")
download_file(url, target)
2021-05-18 12:23:56 +00:00
2021-01-07 08:34:14 +00:00
2024-04-02 07:44:20 +00:00
def _print_all(generator: Generator[Clip, None, None], all: bool):
for clip in generator:
click.echo()
print_clip(clip)
2021-05-18 12:23:56 +00:00
2024-03-23 09:50:42 +00:00
if not all:
click.secho(
"\nThere may be more clips. " +
"Increase the --limit, use --all or --pager to see the rest.",
dim=True
)