mirror of
https://github.com/ihabunek/twitch-dl
synced 2024-08-30 18:32:25 +00:00
110 lines
3.1 KiB
Python
110 lines
3.1 KiB
Python
import re
|
|
import sys
|
|
from os import path
|
|
from pathlib import Path
|
|
from typing import Callable, Generator, List, Optional
|
|
|
|
import click
|
|
|
|
from twitchdl import twitch, utils
|
|
from twitchdl.commands.download import get_clip_authenticated_url
|
|
from twitchdl.entities import VideoQuality
|
|
from twitchdl.http import download_file
|
|
from twitchdl.output import green, print_clip, print_clip_compact, print_json, print_paged, yellow
|
|
from twitchdl.twitch import Clip, ClipsPeriod
|
|
|
|
|
|
def clips(
|
|
channel_name: str,
|
|
*,
|
|
all: bool = False,
|
|
compact: bool = False,
|
|
download: bool = False,
|
|
json: bool = False,
|
|
limit: Optional[int] = None,
|
|
pager: Optional[int] = None,
|
|
period: ClipsPeriod = "all_time",
|
|
target_dir: Path = Path(),
|
|
):
|
|
# 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 or default_limit)
|
|
|
|
generator = twitch.channel_clips_generator(channel_name, period, limit)
|
|
|
|
if json:
|
|
return print_json(list(generator))
|
|
|
|
if download:
|
|
return _download_clips(target_dir, generator)
|
|
|
|
print_fn = print_clip_compact if compact else print_clip
|
|
|
|
if pager:
|
|
return print_paged("Clips", generator, print_fn, pager)
|
|
|
|
return _print_all(generator, print_fn, all)
|
|
|
|
|
|
def _target_filename(clip: Clip, video_qualities: List[VideoQuality]):
|
|
url = video_qualities[0]["sourceURL"]
|
|
_, ext = path.splitext(url)
|
|
ext = ext.lstrip(".")
|
|
|
|
match = re.search(r"^(\d{4})-(\d{2})-(\d{2})T", clip["createdAt"])
|
|
if not match:
|
|
raise ValueError(f"Failed parsing date from: {clip['createdAt']}")
|
|
date = "".join(match.groups())
|
|
|
|
name = "_".join(
|
|
[
|
|
date,
|
|
clip["id"],
|
|
clip["broadcaster"]["login"],
|
|
utils.slugify(clip["title"]),
|
|
]
|
|
)
|
|
|
|
return f"{name}.{ext}"
|
|
|
|
|
|
def _download_clips(target_dir: Path, generator: Generator[Clip, None, None]):
|
|
if not target_dir.exists():
|
|
target_dir.mkdir(parents=True, exist_ok=True)
|
|
|
|
for clip in generator:
|
|
# videoQualities can be null in some circumstances, see:
|
|
# https://github.com/ihabunek/twitch-dl/issues/160
|
|
if not clip["videoQualities"]:
|
|
continue
|
|
|
|
target = target_dir / _target_filename(clip, clip["videoQualities"])
|
|
|
|
if target.exists():
|
|
click.echo(f"Already downloaded: {green(target)}")
|
|
else:
|
|
try:
|
|
url = get_clip_authenticated_url(clip["slug"], "source")
|
|
click.echo(f"Downloading: {yellow(target)}")
|
|
download_file(url, target)
|
|
except Exception as ex:
|
|
click.secho(ex, err=True, fg="red")
|
|
|
|
|
|
def _print_all(
|
|
generator: Generator[Clip, None, None],
|
|
print_fn: Callable[[Clip], None],
|
|
all: bool,
|
|
):
|
|
for clip in generator:
|
|
print_fn(clip)
|
|
|
|
if not all:
|
|
click.secho(
|
|
"\nThere may be more clips. "
|
|
+ "Increase the --limit, use --all or --pager to see the rest.",
|
|
dim=True,
|
|
)
|