#!/bin/bash set -euo pipefail if [ $# -eq 0 ]; then echo "Usage: $0 [export-file2.json] ..." >&2 exit 1 fi jq -n --slurpfile files <( for file in "$@"; do basename=$(basename "$file") date_prefix=$(echo "$basename" | grep -oE '^[0-9]{4}-[0-9]{2}-[0-9]{2}' || echo "0000-00-00") jq --arg file "$file" --arg date "$date_prefix" '. + {sourceFile: $file, fileDate: $date}' "$file" done | jq -s '.' ) ' # Sort files by date (later dates have priority for tie-breaking) ($files[0] | sort_by(.fileDate)) as $sorted_files | # Merge playlists ($sorted_files | map(.playlists // {} | to_entries) | flatten | group_by(.key) | map({ key: .[0].key, value: ( # Get the playlist name .[0].key as $playlist_name | # Collect all videos from all versions with metadata (map(.value) | flatten | unique_by(.url)) as $all_videos | # For each video, find its earliest position $all_videos | map(. as $video | # Find earliest position across all files ([$sorted_files[] | select(.playlists[$playlist_name]) | .playlists[$playlist_name] | to_entries[] | select(.value.url == $video.url) | {index: .key, date: .} ] | if length > 0 then min_by(.date) else {index: 999999, date: {fileDate: "9999-99-99"}} end) as $earliest | # Get latest video data ([$sorted_files[] | select(.playlists[$playlist_name]) | .playlists[$playlist_name][] | select(.url == $video.url) ] | last) as $latest_video | $latest_video + { _sort_date: ($sorted_files | map(select(.playlists[$playlist_name] and (.playlists[$playlist_name] | map(.url) | contains([$video.url])))) | .[0].fileDate), _sort_index: $earliest.index } ) | # Sort by earliest appearance sort_by([._sort_date, ._sort_index]) | # Remove sort keys map(del(._sort_date, ._sort_index)) ) }) | from_entries) as $merged_playlists | # Merge playback history ($sorted_files | map(.playbackHistory // {} | to_entries) | flatten | group_by(.key) | map({ key: .[0].key, value: ( # For each video in history, merge all events and metadata map(.value) | { url: (map(.url) | last), title: (map(.title) | last), tags: (map(.tags // []) | flatten | unique), history: (map(.history // []) | flatten | unique_by(.timestamp) | sort_by(.timestamp)) } ) }) | from_entries) as $merged_history | # Collect all open tabs (unique by URL, keep latest title) ($sorted_files | map(.openTabs // []) | flatten | group_by(.url) | map(last)) as $merged_tabs | # Output merged result { playlists: $merged_playlists, playbackHistory: $merged_history, openTabs: $merged_tabs, exportDate: (now | todate), mergedFrom: ($sorted_files | map({file: .sourceFile, date: .fileDate})) } '