diff options
-rw-r--r-- | hm/soispha/pkgs/scripts.nix | 19 | ||||
-rw-r--r-- | hm/soispha/pkgs/scripts/specific/ytcc/filter_comments.jq | 20 | ||||
-rwxr-xr-x | hm/soispha/pkgs/scripts/specific/ytcc/filter_comments.sh | 12 | ||||
-rwxr-xr-x | hm/soispha/pkgs/scripts/specific/ytcc/nest_comments.py | 100 | ||||
-rwxr-xr-x | hm/soispha/pkgs/scripts/specific/ytcc/ytc (renamed from hm/soispha/pkgs/scripts/wrappers/ytc) | 8 | ||||
-rwxr-xr-x | hm/soispha/pkgs/scripts/specific/ytcc/yts (renamed from hm/soispha/pkgs/scripts/wrappers/yts) | 0 |
6 files changed, 157 insertions, 2 deletions
diff --git a/hm/soispha/pkgs/scripts.nix b/hm/soispha/pkgs/scripts.nix index e0b5a086..84fdfb54 100644 --- a/hm/soispha/pkgs/scripts.nix +++ b/hm/soispha/pkgs/scripts.nix @@ -72,6 +72,14 @@ ''; }; }; + filter-comments-scr = sysLib.writeShellScriptWithLibrary { + name = "filter-comments"; + src = ./scripts/specific/ytcc/filter_comments.sh; + dependencies = with pkgs; [jq fmt less locale] ++ [nest_comments-scr]; + replacementStrings = { + JQ_PREPROCCESSOR_SCRIPT = ./scripts/specific/ytcc/filter_comments.jq; + }; + }; screenshot_persistent-scr = write_shell { name = "screenshot_persistent"; path = "small_functions"; @@ -125,6 +133,11 @@ TASK_PROJECT_FILE = "/home/soispha/repos/nix/nixos-config/hm/soispha/conf/taskwarrior/projects/default.nix"; }; }; + nest_comments-scr = write_python { + name = "nest_comments.py"; + path = "specific/ytcc"; + dependencies_python = ps: []; + }; update-sys-scr = write_shell { name = "update-sys"; path = "small_functions"; @@ -219,7 +232,7 @@ }; ytc-scr = write_shell { name = "ytc"; - path = "wrappers"; + path = "specific/ytcc"; dependencies = builtins.attrValues { inherit (pkgs) @@ -241,7 +254,7 @@ }; yts-scr = write_shell { name = "yts"; - path = "wrappers"; + path = "specific/ytcc"; keep_path = true; # We need neovim dependencies = builtins.attrValues { inherit (pkgs) ytcc jq gawk; @@ -252,6 +265,7 @@ in [ # llp-scr # TODO: see above aumo-scr con2pdf-scr + filter-comments-scr fupdate-scr hibernate-scr ll-scr @@ -259,6 +273,7 @@ in [ lyrics-scr mpc-rm-scr neorg-scr + nest_comments-scr screenshot_persistent-scr screenshot_temporary-scr spodi-scr diff --git a/hm/soispha/pkgs/scripts/specific/ytcc/filter_comments.jq b/hm/soispha/pkgs/scripts/specific/ytcc/filter_comments.jq new file mode 100644 index 00000000..78bde7b8 --- /dev/null +++ b/hm/soispha/pkgs/scripts/specific/ytcc/filter_comments.jq @@ -0,0 +1,20 @@ +def relative_time: + "\(((now - ("\(.timestamp)T00:00:00Z" | fromdate)) / (60 * 60 * 24)) * 10 | round / 10)d"; + +def spaces($ident): + "\([range($ident)] | map(" ") | join(""))"; + +def c($colour): + "\u001B[\($colour)m"; + +def if_states($char): + "\(if .edited or .is_favorited then $char else "" end)"; + +def status: + "\(if_states("["))\(if .edited then "" else "" end)\(if .is_favorited and .edited then " " else "" end)\(if .is_favorited then "" else "" end)\(if_states("]"))"; + +def fmt_cmt($ident): + "\(spaces($ident))\(if .author_is_uploader then c("91;1") else c("35") + end)\(.author)\(c("0"))\(status) \(c("36;1"))(\(. | relative_time))\(c("0")):\n\(spaces($ident))\(.text | gsub("\n"; "\n\(spaces($ident))"))\n\(spaces($ident))\(if .replies? then (.replies | map(fmt_cmt($ident + 4)) | join("\n\(spaces($ident))")) else "" end)"; + +. | map(fmt_cmt(0)) | join("\n") diff --git a/hm/soispha/pkgs/scripts/specific/ytcc/filter_comments.sh b/hm/soispha/pkgs/scripts/specific/ytcc/filter_comments.sh new file mode 100755 index 00000000..436a3bc5 --- /dev/null +++ b/hm/soispha/pkgs/scripts/specific/ytcc/filter_comments.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env dash + +# shellcheck source=/dev/null +SHELL_LIBRARY_VERSION="1.10.2" . %SHELL_LIBRARY_PATH + +# This is the symlink to the active info.json +file="$XDG_RUNTIME_DIR/ytcc/running"; + + +nest_comments.py "$file" | jq --raw-output -f %JQ_PREPROCCESSOR_SCRIPT | fmt -u -s --width=90 | less -r + +# vim: ft=sh diff --git a/hm/soispha/pkgs/scripts/specific/ytcc/nest_comments.py b/hm/soispha/pkgs/scripts/specific/ytcc/nest_comments.py new file mode 100755 index 00000000..2927f7bd --- /dev/null +++ b/hm/soispha/pkgs/scripts/specific/ytcc/nest_comments.py @@ -0,0 +1,100 @@ +#!/usr/bin/env python3 + +""" +SPDX-License-Identifier: MIT https://opensource.org/licenses/MIT +Copyright © 2021 pukkandan.ytdlp@gmail.com +Copyright © 2024 soispha@vhack.eu + + +* Input file is an info.json (with comments) that yt-dlp (https://github.com/yt-dlp/yt-dlp) wrote +* Change FIELDS according to your needs + +The output file will be in the format: +[{ + 'text': 'comment 1', + ... + 'replies': [{ + 'text': 'reply 1', + ... + 'replies': [...], + }, ...], +}, ...] +""" + +import json +import sys +import argparse +from datetime import datetime + +def eprint(*args, **kwargs): + print(*args, file=sys.stderr, **kwargs) + +def get_fields(dct): + for name, fn in FIELDS.items(): + val = fn(dct, name) + if val is not None: + yield name, val + + +def filter_func(comments): + return [dict(get_fields(c)) for c in comments] + + +FIELDS = { + "text": dict.get, + "author": dict.get, + "timestamp": lambda dct, name: dct.get(name) + and datetime.strftime(datetime.utcfromtimestamp(dct.get(name)), "%Y-%m-%d"), + "edited": lambda dct, name: "(edited)" in dct.get("_time_text"), + "author_is_uploader": dict.get, + "is_favorited": dict.get, + # Add more fields here + "replies": lambda dct, name: filter_func(dct.get(name, [])) or None, +} + + +parser = argparse.ArgumentParser() +parser.add_argument( + "input-file", + dest="inputfile", + metavar="FILE", + required=True, + help="File to read video metadata from (info.json)", +) +args = parser.parse_args() + + +eprint("Reading file") +with open(args.inputfile, encoding="utf-8") as f: + info_dict = json.load(f) + +comment_data = { + c["id"]: c + for c in sorted(info_dict["comments"], key=lambda c: c.get("timestamp") or 0) +} +count = len(info_dict["comments"]) +del info_dict +nested_comments = [] +for i, (cid, c) in enumerate(comment_data.items(), 1): + eprint(f"Processing comment {i}/{count}", end="\r") + parent = ( + nested_comments + if c["parent"] == "root" + else comment_data[c["parent"]].setdefault("replies", []) + ) + parent.append(c) +del parent + + +eprint("") +nested_comments = filter_func(nested_comments) + + +eprint("Converting to json") +out = json.dumps(nested_comments, indent=4, ensure_ascii=False) + + +del nested_comments +eprint("Writing file") +print(out) +eprint("Done") diff --git a/hm/soispha/pkgs/scripts/wrappers/ytc b/hm/soispha/pkgs/scripts/specific/ytcc/ytc index c607ea81..c66ae96c 100755 --- a/hm/soispha/pkgs/scripts/wrappers/ytc +++ b/hm/soispha/pkgs/scripts/specific/ytcc/ytc @@ -4,6 +4,8 @@ SHELL_LIBRARY_VERSION="1.10.2" . %SHELL_LIBRARY_PATH CONCURRENT=4 OUTPUT_PATH="/tmp/ytcc"; +STATUS_FILE="$XDG_RUNTIME_DIR/ytcc/running"; +STATUS_PATH="$(dirname "$STATUS_FILE")"; col() { echo "$1" | csvtool -t ';' -u ';' col "$2" - @@ -11,6 +13,11 @@ col() { play() { msg2 "Playing: '$1'" + + info_json="$(echo "$1" | sed 's|\(.*\)\.[a-z0-9]\+|\1.info.json|')"; + [ -L "$STATUS_FILE" ] && rm "$STATUS_FILE" + ln -s "$(readlink -f "$info_json")" "$STATUS_FILE" + mpv "$1" --speed=2.7 --volume=75 output="$?"; @@ -41,6 +48,7 @@ cat << EOF > "$yt_flags" --sponsorblock-remove sponsor EOF +[ -d "$STATUS_PATH" ] || mkdir "$STATUS_PATH"; [ -d "$OUTPUT_PATH" ] || mkdir "$OUTPUT_PATH"; cd "$OUTPUT_PATH" || die "(Bug): Was created" diff --git a/hm/soispha/pkgs/scripts/wrappers/yts b/hm/soispha/pkgs/scripts/specific/ytcc/yts index b5edf52c..b5edf52c 100755 --- a/hm/soispha/pkgs/scripts/wrappers/yts +++ b/hm/soispha/pkgs/scripts/specific/ytcc/yts |