From d2a3671f2debac19db220053cb9fe6a4fd9b550b Mon Sep 17 00:00:00 2001 From: Salt Date: Thu, 13 Jun 2019 07:34:00 -0500 Subject: [PATCH] justplaythegoddamnpart: Add a program to download really friggin barebones playlists --- justplaythegoddamnpart | 150 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100755 justplaythegoddamnpart diff --git a/justplaythegoddamnpart b/justplaythegoddamnpart new file mode 100755 index 0000000..ed0b3de --- /dev/null +++ b/justplaythegoddamnpart @@ -0,0 +1,150 @@ +#! /bin/bash +# +# justplayit +# Copyright (C) 2019 Vintage Salt +# +# Distributed under terms of the MIT license. +# + +# Variables +_name="$(basename -- "$0")" +_tmpdir="${XDG_CACHE_HOME:-$HOME/.cache}/$_name" +_tmpfile="$_tmpdir/tmpfile" +_playlistdir="$_tmpdir"/playlist +_debug=1 + +# Helper functions +debug() { + [ -z "$1" ] && return 1 + [ -z "$_debug" ] && return 0 + log "debug: $1" +} +log() { + [ -z "$1" ] && return 1 + printf "%s: %s\\n" \ + "$_name" \ + "$1" +} +error() { + [ -z "$1" ] && return 1 + [ -z "$2" ] && return 2 + log "$1" + exit "${2:-1}" +} +validatedeps() { + for prog in "$@"; do + if ! command -v "$prog" > /dev/null 2>&1; then + _return="$prog" + return 1 + fi + done + return 0 +} + +# Traps +trapexit() { + kill $(jobs -p) > /dev/null 2>&1 + #[ -n "$_tmpdir" ] && rm "$_tmpfile"* > /dev/null 2>&1 +} + +# Critical functions +clearcache() { + [ -n "$_playlistdir" ] && rm "$_playlistdir"/* > /dev/null 2>&1 + log "Cache has been emptied" +} +helptext() { + cat << EOF +Usage: $_name [OPTION] +Use youtube-dl and audacious to queue up a playlist given a file of only search +queries. + -c Clears the cache (which can become quite large) + -f The playlist file to load + -r Start up rofi, if installed, and present a listing of + all .ytp files in the given directory + -s Shuffle the playlist + -h Print this help text + +Copyright (c) 2019 rehashedsalt@cock.li +Licensed under the MIT license +EOF +} +rofimenu() { + validatedeps rofi || error "$_return is not currently installed" 1 + error "Not yet implemented" 1 + return 0 +} +playlist() { + [ -z "$1" ] && return 1 + [ -f "$1" ] || error "Attempted to access non-file playlist \"$1\"" 50 + [ -r "$1" ] || error "Cannot read playlist \"$1\"" 51 + while read line; do + [ -z "$line" ] && continue + rm "$_tmpfile"* > /dev/null 2>&1 + filename="$_playlistdir/${line//[^ a-zA-Z0-9\[\]|()_-]/}" + if ! [ -f "$filename" ]; then + log "Finding a song for \"$line\"" + youtube-dl \ + --add-metadata \ + --audio-format "best" \ + --geo-bypass \ + --playlist-items 1 \ + -x \ + -o "$_tmpfile.%(ext)s" \ + ytsearch:"$line" \ + > /dev/null 2>&1 & + wait + mv "$_tmpfile"* "$filename" + fi + audacious -e "$filename" + done < <(if [ -n "$_optshuffle" ]; then shuf "$1"; else cat "$1"; fi) + log "Finished building queue" +} + +# Main +main() { + # Boostrapping and setup + validatedeps basename mktemp || error "Critical dependency $_return was not met" 1 + mkdir -p "$_tmpdir" + mkdir -p "$_playlistdir" + trap trapexit EXIT + + # Actual program stuff + while getopts ":cf:r:sh" opt; do + case $opt in + c) + clearcache + exit $? + ;; + f) + _optfile="$OPTARG" + ;; + r) + _optrofi=1 + ;; + s) + _optshuffle=1 + ;; + h) + helptext + exit $? + ;; + :) + error "Option requires argument: -$OPTARG" 2 + ;; + *) + error "Invalid option: -$OPTARG" 2 + ;; + esac + done + debug "Temporary directory is \"$_tmpdir\"" + debug "Playlist directory is \"$_playlistdir\"" + debug "Temporary file is \"$_tmpfile\"" + [ -n "$_optshuffle" ] && debug "Shuffling playlist" + + if [ -n "$_optrofi" ]; then rofimenu; exit $?; fi + if [ -n "$_optfile" ]; then playlist "$_optfile"; exit $?; fi + error "Nothing to do" 0 +} + +main "$@" +