diff --git a/yt b/yt index 77407b8..b763c90 100755 --- a/yt +++ b/yt @@ -19,24 +19,35 @@ set -e test -z "$DEBUG" || set -x +test -z "$XDG_CACHE_HOME" && cachefile="$HOME/.cache/yt.cache" \ + || cachefile="$XDG_CACHE_HOME/yt.cache" +test -z "$YT_PL_DIR" \ + || test -n "$XDG_DATA_HOME" && YT_PL_DIR="$XDG_DATA_HOME/yt" \ + || YT_PL_DIR="$HOME/.local/share/yt" argv0="$0" com="$1" -cachefile="$XDG_CACHE_HOME/yt.cache" FMT='%(title)s – %(channel)s (%(duration>%H:%M:%S)s) [%(webpage_url)s]' WBAPI='https://archive.org/wayback/available?url=' + add() { # adds a video to a playlist file - while test -n "$2"; do - if test -n "$(grep -e "$1" "$2")" + while test -f "$YT_PL_DIR/$2.m3u"; do + file="$YT_PL_DIR/$2.m3u" + video="$(printf '%s\n' "$1" \ + | sed -e 's/youtu\.be\//www.youtube\.com\/watch?q=/g' -e 's/\?[^q].*$//g')" + printf '%s\n' "$video" + + if test -n "$(grep -e "$video" "$file")" then - printf "%s: %s: %s: Video already in playlist.\n" "$argv0" "$2" "$1" + printf "%s: %s: %s: Video already in playlist.\n" \ + "$argv0" "$file" "$video" exit else - cache "$1" - archive "$1" - printf "%s\n" "$1" >> "$2" + cache "$video" + archive "$video" + printf "%s\n" "$video" >> "$file" fi shift @@ -58,18 +69,14 @@ archive() { # archives a video to the Wayback Machine if [ "$wayback_url" != "null" ]; then shift; continue; fi printf "%s: %s: Saving video to the Wayback Machine.\n" "$argv0" "$1" 1>&2 - curl -s -d "url=$1" https://web.archive.org/{url} >/dev/null + curl -s -d "url=$1" 'https://web.archive.org/{url}' >/dev/null fi shift done } cache() { # cache the video title for faster retrieval - if test -z "$XDG_CACHE_HOME"; then - printf "%s: unable to create title cachefile: \$XDG_CACHE_HOME unset." \ - "$argv0" 2>&1 - exit 69 # sysexits.h(3) EX_UNAVAILABLE - fi + test -e "$cachefile" || touch "$cachefile" while test -n "$1"; do grep "$1" "$cachefile" 2>/dev/null 1>&2 || printf '%s\n' \ @@ -79,8 +86,11 @@ cache() { # cache the video title for faster retrieval } clone() { # clones a YouTube playlist to a file - yt-dlp --flat-playlist "$1" --print url > "$2" - verify "$2" + test -d "$YT_PL_DIR" || mkdir -p "$YT_PL_DIR" + file="$YT_PL_DIR/$2.m3u" + + yt-dlp --flat-playlist "$1" --print url > "$file" + verify "$file" } lines() { @@ -90,6 +100,17 @@ lines() { done } +list() { + selection="$(ls "$YT_PL_DIR" | sed 's/\.m3u//g' | $YTPICK)" + + while test -d "$YT_PL_DIR/$selection"; do + dir="$selection" + selection="$(ls "$YT_PL_DIR/$selection" | sed 's/\.m3u//g' | $YTPICK)" + done + + pick "$dir/$selection" +} + music() { # downloads a video, splitting by chapter and only saving the audio while test -n "$1"; do yt-dlp -vx --split-chapters -o \ @@ -99,14 +120,17 @@ music() { # downloads a video, splitting by chapter and only saving the audio done } -pick() { # Pick a video to play from a list of videos +pick() { # Pick a video to play from a playlist of videos if test -z "$YTPICK"; then - printf "%s: Please set \$YTPICK to your preferred picking tool." "$argv0" 1>&2 + printf "%s: Please set \$YTPICK to your preferred picking tool." \ + "$argv0" 1>&2 exit 78 # sysexits.h(3) EX_CONFIG fi - while test -n "$1"; do - for line in $(lines "$1"); do + while test -f "$YT_PL_DIR/$1.m3u"; do + file="$YT_PL_DIR/$1.m3u" + + for line in $(lines "$file"); do if test -n "$(printf '%s\n' "$line" | sed -n '/^\#/p')" then continue @@ -124,17 +148,18 @@ pick() { # Pick a video to play from a list of videos done chosen="$(printf '%s\n' "$list" | $YTPICK | sed -e 's/.*\[//g' -e 's/\]//g')" + printf "%s: %s: Playing stream.\n" "$argv0" "$chosen" 1>&2 test -n "$chosen" && mpv "$chosen" } play() { # play a video after caching its title - cache $@ - mpv $@ + cache "$@" + mpv "$@" } queue() { - while test -n "$1"; do - mpv "$1" + while test -f "$YT_PL_DIR/$1.m3u"; do + mpv "$YT_PL_DIR/$1.m3u" shift done } @@ -145,8 +170,10 @@ usage() { } verify() { # replaces videos with archived versions if they are not available - while test -n "$1"; do - for video in $(lines "$1"); do + while test -f "$YT_PL_DIR/$1.m3u"; do + file="$YT_PL_DIR/$1.m3u" + + for video in $(lines "$file"); do if test -n "$(yt-dlp -s "$video" 2>&1 \ | grep -i -e 'video unavailable' -e 'private video' -e 'been removed')" then @@ -162,16 +189,16 @@ verify() { # replaces videos with archived versions if they are not available printf "%s: %s: Video not available on the Wayback Machine.\n" \ "$argv0" "$video" 1>&2 # replace the video link with a comment containing link - content="$(sed "s;^$video;\# $video;g" "$1")" + content="$(sed "s;^$video;\# $video;g" "$file")" # write the new content buffer to file - printf '%s\n' "$content" > "$1" + printf '%s\n' "$content" > "$file" else printf "%s: %s: Replacing link with Wayback link.\n" \ "$argv0" "$video" 1>&2 - content="$(sed "s;^$video;$wayback_url;g" "$1")" - printf '%s\n' "$content" >"$1" + content="$(sed "s;^$video;$wayback_url;g" "$file")" + printf '%s\n' "$content" >"$file" cache "$wayback_url" fi else @@ -215,6 +242,10 @@ case "$com" in shift 2>/dev/null || usage 'clone uri file' clone "$@" ;; + list) + shift 2>/dev/null || usage 'list' + list "$@" + ;; music) shift 2>/dev/null || usage 'music uri...' music "$@" @@ -236,6 +267,6 @@ case "$com" in verify "$@" ;; *) - usage 'add | clone | music | pick | play | verify' + usage 'add | clone | list | music | pick | play | verify' ;; esac