Browse Source

feat: add playlist and history export scripts

given the format of the json export of playlists and history, write a couple small scripts (in jq and/or bash) that will convert a json exported file, and present the data in a plaintext format. one script prints the title of each playlist then outputs the url and title of each video in the playlist (unviewed ones first, then the "done" ones). another script outputs the history data, but condensed: the url and title of each video viewed, plus the date and time of the most recent activity of that video, ordered by that date and time; optional space-separated arguments filter only the videos containing all the tags given by the arguments.

```git-revs
b08baff  (Base revision)
114f0d3  Create script to format playlist export as plaintext
fca63c3  Make 'format-playlists.sh' executable
c4efe4a  Create script to format history export with optional tag filtering
d33a19f  Make 'format-history.sh' executable
df66c19  Document the export script implementation
376119e  Format history output as tab-separated single lines
9782c5c  Update documentation to reflect tab-separated output
e8eada1  Reorder output to timestamp, url, title
d29ed61  Update documentation for new field order
8a843d1  Format playlists with single-line videos and done subtitle
HEAD     Update documentation for single-line format
```

codemcp-id: 20-feat-add-playlist-and-history-export-scripts
Brandon Wong 7 months ago
parent
commit
5cbb85e326

File diff suppressed because it is too large
+ 60 - 0
2025-11-08-codemcp-feat-add-playlist-and-history-export-scripts.md


+ 51 - 0
format-history.sh

@@ -0,0 +1,51 @@
+#!/bin/bash
+
+if [ $# -eq 0 ]; then
+    echo "Usage: $0 <export-file.json> [tag1] [tag2] ..." >&2
+    exit 1
+fi
+
+export_file="$1"
+shift
+tags=("$@")
+
+if [ ! -f "$export_file" ]; then
+    echo "Error: File '$export_file' not found" >&2
+    exit 1
+fi
+
+if [ ${#tags[@]} -eq 0 ]; then
+    jq -r '
+    .playbackHistory | to_entries |
+    map({
+      url: .value.url,
+      title: .value.title,
+      lastInteraction: ([.value.history[].timestamp] | max)
+    }) |
+    sort_by(.lastInteraction) | reverse |
+    .[] |
+    "\((.lastInteraction / 1000 | strftime("%Y-%m-%d %H:%M:%S")))\t\(.url)\t\(.title)"
+    ' "$export_file"
+else
+    # Build jq filter for tag matching
+    tag_filters=""
+    for tag in "${tags[@]}"; do
+        if [ -n "$tag_filters" ]; then
+            tag_filters="$tag_filters and "
+        fi
+        tag_filters="${tag_filters}(.value.tags // [] | contains([\"$tag\"]))"
+    done
+
+    jq -r "
+    .playbackHistory | to_entries |
+    map(select($tag_filters)) |
+    map({
+      url: .value.url,
+      title: .value.title,
+      lastInteraction: ([.value.history[].timestamp] | max)
+    }) |
+    sort_by(.lastInteraction) | reverse |
+    .[] |
+    \"\((.lastInteraction / 1000 | strftime(\"%Y-%m-%d %H:%M:%S\")))\\t\(.url)\\t\(.title)\"
+    " "$export_file"
+fi

+ 37 - 0
format-playlists.sh

@@ -0,0 +1,37 @@
+#!/bin/bash
+
+if [ $# -eq 0 ]; then
+    echo "Usage: $0 <export-file.json>" >&2
+    exit 1
+fi
+
+export_file="$1"
+
+if [ ! -f "$export_file" ]; then
+    echo "Error: File '$export_file' not found" >&2
+    exit 1
+fi
+
+jq -r '
+.playlists | to_entries | .[] |
+"# \(.key)",
+(
+  [.value[] |
+    select(.status != "done") |
+    "\(.url)\t\(.title)"
+  ] |
+  if length > 0 then .[] else empty end
+),
+(
+  if ([.value[] | select(.status == "done")] | length) > 0 then
+    "## Done",
+    ([.value[] |
+      select(.status == "done") |
+      "\(.url)\t\(.title)"
+    ] | .[])
+  else
+    empty
+  end
+),
+""
+' "$export_file"