diff --git a/yt b/yt index 16d3db8..7a49dfe 100755 --- a/yt +++ b/yt @@ -30,6 +30,9 @@ test -n "$YT_PL_DIR" \ test -d "$YT_PL_DIR" \ || mkdir -p "$YT_PL_DIR" +# formatted $YT_PL_DIR for use with sed +P="$(printf '%s\n' "$YT_PL_DIR" | sed 's;\/;\\/;g')" + argv0="$0" com="$1" u='add | archive | clone | list | new | pick | play | search | sync | verify' @@ -52,8 +55,8 @@ add() { # adds a video to a playlist file "$argv0" "$file" "$video" exit else - cache "$video" - archive "$video" + cache "$video" & + archive "$video" & printf "%s\n" "$video" >> "$file" fi @@ -99,10 +102,17 @@ cache() { # cache the video title for faster retrieval clone() { # clones a YouTube playlist to a file test -z "$1" && usage 'clone uri [playlist]' - title="$(yt-dlp -s -I '1:1' --print '%(playlist)s' "$1")" + n=1 - file="$YT_PL_DIR/$title.m3u" - creator="$(yt-dlp -s -I '1:1' --print '%(playlist_uploader)s' "$1")" + while test -z "$title"; do + title="$(yt-dlp -s -I "$n" --print '%(playlist)s' "$1" || true)" + n="$((n + 1))" + done + + creator="$(yt-dlp -s -I "$n" --print '%(playlist_uploader)s' "$1")" + filename="$(printf '%s\n' "$title" | sed 's/ /_/g')" + + file="$YT_PL_DIR/$filename.m3u" videos="$(yt-dlp --flat-playlist "$1" --print url)" prefix="$(printf "#EXTM3U\n#EXTART:%s\n#PLAYLIST:%s [%s]\n" \ @@ -111,7 +121,7 @@ clone() { # clones a YouTube playlist to a file printf "%s: %s: Saving playlist to %s.\n" "$argv0" "$title" "$file" 1>&2 printf '%s\n\n%s\n' "$prefix" "$videos" >"$file" - verify "$file" + verify "$filename" } lines() { @@ -136,7 +146,7 @@ list() { } menu() { - playlist="$(ls "$YT_PL_DIR" | sed 's/\.m3u//g' | $YTPICK)" + playlist="$(ls "$YT_PL_DIR" | sed 's/\.m3u//g' | sed -n '/[^.old]/p' | $YTPICK)" while test -d "$YT_PL_DIR/$playlist"; do dir="$playlist" @@ -178,7 +188,7 @@ pick() { # Pick a video to play from a playlist of videos then continue else - cache "$line" + cache "$line" & fi if test -z "$list"; then @@ -206,7 +216,7 @@ play() { # play a video after caching its title exit 78 # sysexits.h(3) EX_CONFIG fi - cache "$@" + cache "$@" & "$PLAYER" "$@" } @@ -236,6 +246,9 @@ search() { results="$(yt-dlp "ytsearch$2:$1" --print "$FMT")" + cache "$(printf '%s\n' "$results" | sed -e 's/.*\[//g' -e 's/\]/ /g' \ + | tr -d '\n')" & + selection="$(printf '%s\n' "$results" \ | $YTPICK \ | sed 's/.*\[//g' \ @@ -261,13 +274,24 @@ search() { fi } +searchlocal() { + test -n "$1" && usage 'searchlocal' + + if test -z "$YTPICK"; then + printf "%s: Please set \$YTPICK to your preferred picking tool." \ + "$argv0" 1>&2 + exit 78 # sysexits.h(3) EX_CONFIG + fi + + $YTPICK <"$cachefile" +} + sync() { if test -z "$1" then set -- "$YT_PL_DIR"/*.m3u else - P="$(printf '%s\n' "$YT_PL_DIR" | sed 's;\/;\\/;g')" - set -- $(printf "$@" | sed "s/.* /$P\/&\.m3u/g") + set -- $(printf "$@" | sed "s/.* /$P\/&\.m3u /g") fi while test -n "$1"; do @@ -277,9 +301,7 @@ sync() { URL="$(sed -n 's/^\#PLAYLIST:.* \[//p' <"$file" | tr -d ']')" if test -n "$URL"; then - mv "$file" "$file.old" - - clone "$URL" || mv "$file.old" "$file" + clone "$URL" && mv "$file" "$file.old" fi fi @@ -295,10 +317,17 @@ usage() { verify() { # replaces videos with archived versions if they are not available test -z "$1" && usage 'verify playlist...' - while test -f "$YT_PL_DIR/$1.m3u"; do - file="$YT_PL_DIR/$1.m3u" + set -- $(printf '%s\n' "$@" | sed "s/[^ ]*/$P\/&.m3u /g") - for video in $(lines "$file"); do + while test -n "$1"; do + if ! test -f "$1"; then + printf '%s: %s: No such playlist.\n' \ "$argv0" "$1" 1>&2 + exit 69 # syexits.h(3) EX_UNAVAILABLE + fi + + printf "%s: %s: Verifying playlist.\n" "$argv0" "$1" 1>&2 + + for video in $(lines "$1"); do if test -n "$(yt-dlp -s "$video" 2>&1 \ | grep -i -e 'video unavailable' -e 'private video' -e 'been removed')" then @@ -314,22 +343,22 @@ 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" "$file")" + content="$(sed "s;^$video;\# $video;g" "$1")" # write the new content buffer to file - printf '%s\n' "$content" > "$file" + printf '%s\n' "$content" > "$1" else printf "%s: %s: Replacing link with Wayback link.\n" \ "$argv0" "$video" 1>&2 - content="$(sed "s;^$video;$wayback_url;g" "$file")" - printf '%s\n' "$content" >"$file" - cache "$wayback_url" + content="$(sed "s;^$video;$wayback_url;g" "$1")" + printf '%s\n' "$content" >"$1" + cache "$wayback_url" & fi else printf '%s: %s: Video available.\n' "$argv0" "$video" 1>&2 - cache "$video" - archive "$video" + cache "$video" & + archive "$video" & fi done