bin/jptgdp
2019-06-13 08:00:22 -05:00

161 lines
3.4 KiB
Bash
Executable File

#! /bin/bash
#
# jptgdp - Just Play the Goddamn Playlist
# Copyright (C) 2019 Vintage Salt <rehashedsalt@cock.li>
#
# Distributed under terms of the MIT license.
#
# TODO:
# * Provide integration with other players, like mpd
# * Actually add that rofi support cuz I want it
# * Add a quick way to append to a playlist
# Variables
_name="$(basename -- "$0")"
_tmpdir="${XDG_CACHE_HOME:-$HOME/.cache}/$_name"
_tmpfile="$_tmpdir/tmpfile"
_xdguserdirs="${XDG_CONFIG_HOME:-$HOME/.config}/user-dirs.dirs"
[ -f "$_xdguserdirs" ] && source "$_xdguserdirs"
_musicdir="${XDG_MUSIC_DIR:-$HOME/Music}/JPTGDP Songs"
# Helper functions
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 "$_musicdir" ] && rm "$_musicdir"/* > /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.
-f <file> The playlist file to load
-c Clears the cache (which can become quite large)
-d Download only; don't queue anything up
-s Shuffle the playlist
-r <directory> Start up rofi, if installed, and present a listing of
all .ytp files in the given directory
-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="$_musicdir/${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 &
if wait $!; then
mv "$_tmpfile"* "$filename"
else
log "No results found for \"$line\""
fi
fi
[ -z "$_optdownloadonly" ] && audacious -e "$filename"
done < <(if [ -n "$_optshuffle" ]; then shuf "$1"; else cat "$1"; fi)
if [ -z "$_optdownloadonly" ]; then
log "Finished building queue"
else
log "Finished downloading"
fi
}
# Main
main() {
# Boostrapping and setup
validatedeps basename mktemp || error "Critical dependency $_return was not met" 1
mkdir -p "$_tmpdir"
mkdir -p "$_musicdir"
trap trapexit EXIT
# Actual program stuff
while getopts ":cdf:r:sh" opt; do
case $opt in
c)
clearcache
exit $?
;;
d)
_optdownloadonly=1
;;
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
if [ -n "$_optrofi" ]; then rofimenu; exit $?; fi
if [ -n "$_optfile" ]; then playlist "$_optfile"; exit $?; fi
error "Nothing to do" 0
}
main "$@"