2020-09-03 06:49:41 +00:00
|
|
|
import json
|
2018-01-25 10:09:20 +00:00
|
|
|
import sys
|
|
|
|
import re
|
|
|
|
|
2022-02-23 18:07:27 +00:00
|
|
|
from itertools import islice
|
2020-04-11 11:08:42 +00:00
|
|
|
from twitchdl import utils
|
2022-08-20 09:35:07 +00:00
|
|
|
from typing import Any, Match
|
2020-04-11 11:08:42 +00:00
|
|
|
|
|
|
|
|
2018-01-25 10:09:20 +00:00
|
|
|
START_CODES = {
|
2020-05-17 11:35:51 +00:00
|
|
|
'b': '\033[1m',
|
2020-05-17 12:32:37 +00:00
|
|
|
'dim': '\033[2m',
|
2019-08-13 10:29:42 +00:00
|
|
|
'i': '\033[3m',
|
|
|
|
'u': '\033[4m',
|
2020-04-11 12:05:23 +00:00
|
|
|
'red': '\033[91m',
|
|
|
|
'green': '\033[92m',
|
|
|
|
'yellow': '\033[93m',
|
|
|
|
'blue': '\033[94m',
|
|
|
|
'magenta': '\033[95m',
|
|
|
|
'cyan': '\033[96m',
|
2018-01-25 10:09:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
END_CODE = '\033[0m'
|
|
|
|
|
|
|
|
START_PATTERN = "<(" + "|".join(START_CODES.keys()) + ")>"
|
|
|
|
END_PATTERN = "</(" + "|".join(START_CODES.keys()) + ")>"
|
|
|
|
|
|
|
|
USE_ANSI_COLOR = "--no-color" not in sys.argv
|
|
|
|
|
|
|
|
|
2022-08-20 09:35:07 +00:00
|
|
|
def start_code(match: Match[str]) -> str:
|
2018-01-25 10:09:20 +00:00
|
|
|
name = match.group(1)
|
|
|
|
return START_CODES[name]
|
|
|
|
|
|
|
|
|
2022-08-20 09:35:07 +00:00
|
|
|
def colorize(text: str) -> str:
|
2018-01-25 10:09:20 +00:00
|
|
|
text = re.sub(START_PATTERN, start_code, text)
|
|
|
|
text = re.sub(END_PATTERN, END_CODE, text)
|
|
|
|
|
|
|
|
return text
|
|
|
|
|
|
|
|
|
2022-08-20 09:35:07 +00:00
|
|
|
def strip_tags(text: str) -> str:
|
2018-01-25 10:09:20 +00:00
|
|
|
text = re.sub(START_PATTERN, '', text)
|
|
|
|
text = re.sub(END_PATTERN, '', text)
|
|
|
|
|
|
|
|
return text
|
|
|
|
|
|
|
|
|
2022-08-20 09:35:07 +00:00
|
|
|
def truncate(string: str, length: int) -> str:
|
2022-08-18 08:03:40 +00:00
|
|
|
if len(string) > length:
|
|
|
|
return string[:length - 1] + "…"
|
|
|
|
|
|
|
|
return string
|
|
|
|
|
|
|
|
|
2018-01-25 10:09:20 +00:00
|
|
|
def print_out(*args, **kwargs):
|
|
|
|
args = [colorize(a) if USE_ANSI_COLOR else strip_tags(a) for a in args]
|
|
|
|
print(*args, **kwargs)
|
|
|
|
|
|
|
|
|
2022-08-20 09:35:07 +00:00
|
|
|
def print_json(data: Any):
|
2020-09-03 06:49:41 +00:00
|
|
|
print(json.dumps(data))
|
|
|
|
|
|
|
|
|
2018-01-25 10:09:20 +00:00
|
|
|
def print_err(*args, **kwargs):
|
2024-03-28 11:06:50 +00:00
|
|
|
args = [f"<red>{arg}</red>" for arg in args]
|
2018-01-25 10:09:20 +00:00
|
|
|
args = [colorize(a) if USE_ANSI_COLOR else strip_tags(a) for a in args]
|
|
|
|
print(*args, file=sys.stderr, **kwargs)
|
2020-04-11 11:08:42 +00:00
|
|
|
|
|
|
|
|
2021-01-14 20:38:56 +00:00
|
|
|
def print_log(*args, **kwargs):
|
2024-03-28 11:06:50 +00:00
|
|
|
args = [f"<dim>{a}</dim>" for a in args]
|
2021-01-14 20:38:56 +00:00
|
|
|
args = [colorize(a) if USE_ANSI_COLOR else strip_tags(a) for a in args]
|
|
|
|
print(*args, file=sys.stderr, **kwargs)
|
|
|
|
|
|
|
|
|
2020-04-11 11:08:42 +00:00
|
|
|
def print_video(video):
|
2020-05-17 09:56:21 +00:00
|
|
|
published_at = video["publishedAt"].replace("T", " @ ").replace("Z", "")
|
|
|
|
length = utils.format_duration(video["lengthSeconds"])
|
2022-02-05 08:47:55 +00:00
|
|
|
|
2024-03-28 11:06:50 +00:00
|
|
|
channel = f"<blue>{video['creator']['displayName']}</blue>" if video["creator"] else ""
|
|
|
|
playing = f"playing <blue>{video['game']['name']}</blue>" if video["game"] else ""
|
2020-04-11 11:08:42 +00:00
|
|
|
|
2020-05-17 09:56:21 +00:00
|
|
|
# Can't find URL in video object, strange
|
2024-03-28 11:06:50 +00:00
|
|
|
url = f"https://www.twitch.tv/videos/{video['id']}"
|
2020-05-17 09:56:21 +00:00
|
|
|
|
2024-03-28 11:06:50 +00:00
|
|
|
print_out(f"<b>Video {video['id']}</b>")
|
|
|
|
print_out(f"<green>{video['title']}</green>")
|
2022-02-23 18:07:04 +00:00
|
|
|
|
|
|
|
if channel or playing:
|
|
|
|
print_out(" ".join([channel, playing]))
|
|
|
|
|
2024-03-29 08:22:50 +00:00
|
|
|
if video["description"]:
|
|
|
|
print_out(f"Description: {video['description']}")
|
|
|
|
|
2024-03-28 11:06:50 +00:00
|
|
|
print_out(f"Published <blue>{published_at}</blue> Length: <blue>{length}</blue> ")
|
|
|
|
print_out(f"<i>{url}</i>")
|
2020-09-03 06:49:41 +00:00
|
|
|
|
|
|
|
|
2022-08-18 08:03:40 +00:00
|
|
|
def print_video_compact(video):
|
|
|
|
id = video["id"]
|
|
|
|
date = video["publishedAt"][:10]
|
|
|
|
game = video["game"]["name"] if video["game"] else ""
|
|
|
|
title = truncate(video["title"], 80).ljust(80)
|
|
|
|
print_out(f'<b>{id}</b> {date} <green>{title}</green> <blue>{game}</blue>')
|
|
|
|
|
|
|
|
|
2022-02-23 18:07:27 +00:00
|
|
|
def print_paged_videos(generator, page_size, total_count):
|
|
|
|
iterator = iter(generator)
|
|
|
|
page = list(islice(iterator, page_size))
|
|
|
|
|
|
|
|
first = 1
|
|
|
|
last = first + len(page) - 1
|
|
|
|
|
|
|
|
while True:
|
|
|
|
print_out("-" * 80)
|
|
|
|
|
|
|
|
print_out()
|
|
|
|
for video in page:
|
|
|
|
print_video(video)
|
|
|
|
print_out()
|
|
|
|
|
|
|
|
last = first + len(page) - 1
|
|
|
|
|
|
|
|
print_out("-" * 80)
|
2024-03-28 11:06:50 +00:00
|
|
|
print_out(f"<yellow>Videos {first}-{last} of {total_count}</yellow>")
|
2022-02-23 18:07:27 +00:00
|
|
|
|
|
|
|
first = first + len(page)
|
|
|
|
last = first + 1
|
|
|
|
|
|
|
|
page = list(islice(iterator, page_size))
|
|
|
|
if not page or not _continue():
|
|
|
|
break
|
|
|
|
|
|
|
|
|
2020-09-03 06:49:41 +00:00
|
|
|
def print_clip(clip):
|
|
|
|
published_at = clip["createdAt"].replace("T", " @ ").replace("Z", "")
|
|
|
|
length = utils.format_duration(clip["durationSeconds"])
|
2021-01-14 20:38:56 +00:00
|
|
|
channel = clip["broadcaster"]["displayName"]
|
2020-11-10 09:44:18 +00:00
|
|
|
playing = (
|
2024-03-28 11:06:50 +00:00
|
|
|
f"playing <blue>{clip['game']['name']}</blue>"
|
2020-11-10 09:44:18 +00:00
|
|
|
if clip["game"] else ""
|
|
|
|
)
|
2020-09-03 06:49:41 +00:00
|
|
|
|
2024-03-28 11:06:50 +00:00
|
|
|
print_out(f"Clip <b>{clip['slug']}</b>")
|
|
|
|
print_out(f"<green>{clip['title']}</green>")
|
|
|
|
print_out(f"<blue>{channel}</blue> {playing}")
|
2020-09-03 06:49:41 +00:00
|
|
|
print_out(
|
2024-03-28 11:06:50 +00:00
|
|
|
f"Published <blue>{published_at}</blue>" +
|
|
|
|
f" Length: <blue>{length}</blue>" +
|
|
|
|
f" Views: <blue>{clip["viewCount"]}</blue>"
|
|
|
|
)
|
|
|
|
print_out(f"<i>{clip['url']}</i>")
|
2022-02-23 18:07:27 +00:00
|
|
|
|
|
|
|
|
|
|
|
def _continue():
|
|
|
|
print_out("Press <green><b>Enter</green> to continue, <yellow><b>Ctrl+C</yellow> to break.")
|
|
|
|
|
|
|
|
try:
|
|
|
|
input()
|
|
|
|
except KeyboardInterrupt:
|
|
|
|
return False
|
|
|
|
|
|
|
|
return True
|