~kris/dots

srice

ref: e98f3b030dc24445bd55c68d95d2d81933fd68b3 srice/.local/bin/misc/ytcomments -rw-r--r-- 1.6 KiB
e98f3b03 — Kris Yotam chore: sync local state after restore (push updates, no pull) a month ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#!/bin/bash

# Scrape YouTube comments into searchable .md and .json files.
# Usage: ytcomments <url> [output_dir]
#   url        - YouTube video URL
#   output_dir - where to save (default: current directory)
#
# Output files are named after the video title, sorted by like count.
# Search with: rg -i "keyword" file.md

die() { printf '%s\n' "$1" >&2; exit 1; }

[ -z "$1" ] && die "Usage: ytcomments <youtube-url> [output-dir]"

command -v yt-dlp >/dev/null || die "yt-dlp not found"
command -v jq >/dev/null || die "jq not found"

url="$1"
outdir="${2:-.}"
tmpdir=$(mktemp -d)
trap 'rm -rf "$tmpdir"' EXIT

printf 'Scraping comments from: %s\n' "$url"

yt-dlp --skip-download --write-comments \
	-o "$tmpdir/%(title)s.%(ext)s" "$url" 2>&1 | tail -1

infofile=$(find "$tmpdir" -name '*.info.json' | head -1)
[ -f "$infofile" ] || die "Failed to download comments"

title=$(jq -r '.title' "$infofile" | tr '/' '-' | tr -d '\n')
count=$(jq '.comments | length' "$infofile")
printf 'Found %s comments for: %s\n' "$count" "$title"

# Markdown — sorted by likes, most popular first
jq -r '
  .comments | sort_by(-.like_count) | .[] |
  "## \(.author) (\(.like_count) likes)\n\(.text)\n\n---\n"
' "$infofile" > "$outdir/$title.md"

# JSON — clean array sorted by likes
jq '[.comments | sort_by(-.like_count) | .[] | {
  author, text, likes: .like_count,
  replies: (.reply_count // 0),
  time: .timestamp
}]' "$infofile" > "$outdir/$title.json"

printf 'Saved:\n  %s/%s.md\n  %s/%s.json\n' "$outdir" "$title" "$outdir" "$title"
printf 'Search with: rg -i "keyword" "%s/%s.md"\n' "$outdir" "$title"