#!/bin/bash shopt -s globstar source $HOME/.config/clerk/config #backend=rofi # Number of Songs to be added for "Random Tracks" #value=20 # Change this, if you have subfolders for multi-disc albums. this should match the name of your subfolders, exluding the number #cd_divider=CD # use artist or albumartist for album ratings #mpd_artist=albumartist #music_path="/mnt/wasteland/Audio/Rips" # Fill these if mpdscribble runs on a different host # set to 0 if mpdscribble runs locally #ssh_lastfm=1 #ssh_host=picon dplayPrompt () { menu=("1 Play random Album" "2 Play random Songs" "---" "3 Current Artist" "4 Current Queue" "5 Browse Library" "---" "6 Options" "7 Ratings" "8 Lookup" "9 Playback" "---" "0 Testing" "/ Search") prompt() { printf "%s\n" "$@" | dmenu_t -p "MPD Menu: > " } case "$(prompt "${menu[@]}")" in 1*) mpc clear; mpc findadd album "$(mpc list album | shuf -n1)"; mpc play ;; 2*) mpc clear && mpc listall | shuf | head -n "$value" | mpc add && mpc play ;; 3*) currentPrompt ;; 4*) dplayQueue ;; 5*) browseLib ;; /*) searchPrompt ;; 6*) dplayOptionsPrompt ;; 7*) ratingPrompt ;; 8*) infoPrompt ;; 9*) playbackPrompt ;; 0*) testingPrompt;; *) exit esac } playbackPrompt () { menu=("1 Toggle Playback" "2 Next Song" "3 Prev Song" "4 Stop" "5 Clear Playlist" "---" "0 back to MPD Menu") prompt() { printf "%s\n" "$@" | dmenu_t -p "Playback: > " } case "$(prompt "${menu[@]}")" in 1*) mpc toggle && playbackPrompt;; 2*) mpc next && playbackPrompt ;; 3*) mpc prev && playbackPrompt ;; 4*) mpc stop && playbackPrompt ;; 5*) mpc clear && dplayPrompt ;; 0*) dplayPrompt ;; *) dplayPrompt ;; esac } searchPrompt () { menu=("1 Search for Artist" "2 Search for Album" "3 Search for Track" "---" "0 back to MPD Menu") prompt() { printf "%s\n" "$@" | dmenu_t -p "Search: > " } case "$(prompt "${menu[@]}")" in 1*) dplay -x ;; 2*) dplay -a ;; 3*) dplay -t ;; 0*) dplayPrompt ;; *) dplayPrompt esac } lastFM () { # Some Variables to clean up the code mpds_check="$(ssh $ssh_host -q -t 'bash -c "pgrep mpdscribble"')" if ((ssh_lastfm)); then if [ -n "$mpds_check" ]; then ssh $ssh_host -q -t 'bash -c "killall mpdscribble"' && notify-send "MPD" "LastFM Scrobbling Disabled" else ssh $ssh_host -q 'mpdscribble' && notify-send "MPD" "LastFM Scrobbling Enabled" fi else if pgrep mpdscribble then killall mpdscribble && notify-send "MPD" "LastFM Scrobbling Disabled" else mpdscribble && notify-send "MPD" "LastFM Scrobbling Enabled" fi fi } currentPrompt () { menu=("1 Albums" "2 Tracks" "---" "0 back to MPD menu") prompt() { printf "%s\n" "$@" | dmenu_t -p "$(mpc current --format '%artist%') > " } case "$(prompt "${menu[@]}")" in 1*) currentAlbums ;; 2*) currentTracks ;; 0*) dplayPrompt ;; *) dplayPrompt esac } ratingPrompt () { menu=("1 Rate current Album" "2 Load Rated Albums" "3 Load Random Rated Album" "---" "4 Rate current Track" "5 Load Rated Tracks" "6 Load Random Rated Tracks" "---" "7 Love current Song on LastFM" "---" "0 back to MPD menu") prompt() { printf "%s\n" "$@" | dmenu_t -p "Ratings: > " } case "$(prompt "${menu[@]}")" in 1*) rateAlbum ;; 2*) loadRatedAlbums ;; 3*) loadRandomRating ;; 4*) rateTrack ;; 5*) loadRatedTracks ;; 6*) loadRandomRatedTracks ;; 7*) lastfm-mpd-cli love > /dev/null && notify-send "MPD" "Loved $(mpc current -f '%title%') on LastFM" ;; 0*) dplayPrompt ;; *) dplayPrompt esac } infoPrompt () { menu=("1 Artist Info" "2 Album Info" "3 Current Track Lyrics" "4 Show current Tracks Tags" "---" "0 back to MPD menu") prompt() { printf "%s\n" "$@" | dmenu_t -p "MPD Menu: > " } case "$(prompt "${menu[@]}")" in 1*) surfraw yubnub allmusic $(mpc current -f %artist%) ;; 2*) surfraw yubnub allmusic $(mpc current -f %album%) ;; 3*) surfraw yubnub google $(mpc current -f %title%) $(mpc current -f %artist%) lyrics ;; 4*) mpc current --format "Artist: %artist%\nAlbum: %album%\nDate: %date%\nTrack: %track%\nTitle: %title%" | rofi -dmenu -p 'tags' && dplayPrompt;; 0*) dplayPrompt ;; *) return esac } dplayOptionsPrompt () { export status="$(mpc status)" single=$(echo "$status" | tail -1 | awk -F ':' '{ print $5 }' | cut -d ' ' -f 2) random=$(echo "$status" | tail -1 | awk -F ':' '{ print $4 }' | cut -d ' ' -f 2) consume=$(echo "$status" | tail -1 | awk -F ':' '{ print $6 }' | cut -d ' ' -f 2) repeat=$(echo "$status" | tail -1 | awk -F ':' '{ print $3 }' | cut -d ' ' -f 2) mpds_check="$(ssh $ssh_host -q -t 'bash -c "pgrep mpdscribble"')" if ((ssh_lastfm)); then if [ -n "$mpds_check" ]; then export scrobble=on else export scrobble=off fi else if pgrep mpdscribble then export scrobble=on else export scrobble=off fi fi export rgain="$(mpc replaygain | cut -d ' ' -f 2)" replayGain () { if [[ $(mpc replaygain | cut -d ' ' -f 2) == album ]]; then mpc replaygain track > /dev/null && export rgain="track" elif [[ $(mpc replaygain | cut -d ' ' -f 2) == track ]]; then mpc replaygain off > /dev/null && export rgain="off" elif [[ $(mpc replaygain | cut -d ' ' -f 2) == off ]]; then mpc replaygain album > /dev/null && export rgain="album" fi } menu=("1 Random: $(echo $random)" "2 Repeat: $(echo $repeat)" "3 Single Mode: $(echo $single)" "4 Consume Mode: $(echo $consume)" "5 Replaygain: $(echo $rgain)" "6 Scrobbling: $(echo $scrobble)" "---" "7 Set Crossfade" "8 Manage Outputs" "9 Number of Random Songs: $(echo $value)" "---" "0 back to MPD Menu") prompt() { printf "%s\n" "$@" | dmenu_t -p "MPD Options: > " } case "$(prompt "${menu[@]}")" in 1*) mpc random && dplayOptionsPrompt ;; 2*) mpc repeat && dplayOptionsPrompt ;; 3*) mpc single && dplayOptionsPrompt ;; 4*) mpc consume && dplayOptionsPrompt ;; 5*) replayGain && dplayOptionsPrompt ;; 6*) lastFM && dplayOptionsPrompt ;; 7*) crossfadePrompt ;; 8*) outputPrompt ;; 9*) optionRandomPrompt ;; 0*) dplayPrompt ;; *) dplayPrompt ;; esac } optionRandomPrompt() { number="$(echo " " | dmenu_t -p 'Set No. of Songs for random Songs: > ')" sed -i "s/value=.*/value="$number"/" $HOME/.config/clerk/config export value="$number" dplayOptionsPrompt } crossfadePrompt () { menu=("1" "2" "3" "4" "5" "---" "0 back to MPD Options") prompt() { printf "%s\n" "$@" | dmenu_t -p "Crossfade: > " } case "$(prompt "${menu[@]}")" in 1) mpc crossfade 1 ;; 2) mpc crossfade 2 ;; 3) mpc crossfade 3 ;; 4) mpc crossfade 4 ;; 5) mpc crossfade 5 ;; 0:*) dplayOptionsPrompt ;; *) return esac } dplayQueue () { TRACKDISPLAY=$(mppc playlist --format '{track} • {title}'| dmenu_t); TITLE=$(echo "$TRACKDISPLAY" | awk -F ' • ' '{ print $2 }') if [ "$TRACKDISPLAY" = "" ]; then dplayPrompt else POS=$(mpc playlist | grep -n "$TITLE" | awk -F: '{print $1}') mpc play $POS; fi } outputPrompt () { menu="$(echo -e "$(mpc outputs)" | dmenu_t -p "Outputs: > ")"; if [[ "$menu" = "" ]] then dplayPrompt; else mpc toggleoutput $(echo "$menu" | awk '{print $2}'); notify-send "MPD" "$(echo "$menu" | sed -e 's/enabled$/disabled/;ta;s/disabled$/enabled/;:a;')"; fi } currentAlbums () { ARTIST=$(mpc current -f %artist%) ALBUM=$(mppc search artist "$ARTIST" --format '{date} {album}' | sort | uniq | dmenu_t -p "Albums by $(mpc current --format '%artist%'): > ") ALBUM_FINAL=$(echo "$ALBUM" | cut -d ' ' -f2-) if [ "$ALBUM" = "" ]; then currentPrompt; else currentSubAlbum -ca "$ALBUM_FINAL"; fi } currentTracks () { TRACK=$(mpc search artist "$(mpc current -f %artist%)" | dmenu_t -p "Tracks by $(mpc current --format '%artist%'): > ") if [ "$TRACK" = "" ]; then currentPrompt; else currentSubTrack -ct "$TRACK"; fi } currentSubTrack () { menu=("1 Add" "2 Insert" "3 Replace" "---" "0 back to MPD Menu") prompt() { printf "%s\n" "$@" | dmenu_t -p "MPD Menu: > " } case "$(prompt "${menu[@]}")" in 1*) dplay $1 add "$2";; 2*) dplay $1 insert "$2";; 3*) dplay $1 replace "$2";; 0*) dplayPrompt ;; *) dplayPrompt esac } currentSubAlbum () { menu=("1 Add" "2 Insert" "3 Replace" "---" "0 back to MPD Menu") prompt() { printf "%s\n" "$@" | dmenu_t -p "MPD Menu: > " } case "$(prompt "${menu[@]}")" in 1*) dplay $1 add "$2";; 2*) dplay $1 insert "$2";; 3*) dplay $1 replace "$2";; 0*) dplayPrompt ;; *) dplayPrompt esac } rateAlbum () { ratings="$(echo " " | dmenu_t -p "Rating: > " | xargs echo)" if [ ratings = "" ]; then exit else cd "$music_path" cd "$(dirname "$(mpc current -f %file%)")" if [[ "$(pwd)" == */"$cd_divider"* ]]; then cd .. else echo " " fi rm -f rating.txt echo "$ratings/10" > rating.txt echo "$(mpc current -f "%$mpd_artist%")" >> rating.txt echo "$(mpc current -f '%album%')" >> rating.txt echo "$(mpc current -f '%date%')" >> rating.txt notify-send "clerk" "Rated $(mpc current -f "%$mpd_artist% - %album%") with $ratings" fi } rateTrack () { extension=$(mpc current -f %file% | sed 's/.*\.//') ratings="$(echo " " | dmenu_t -p "Rating: > " | xargs echo)" if [ ratings = "" ]; then exit else cd "$music_path" if [[ "$extension" == flac ]]; then metaflac --remove-tag=comment "$(mpc current -f %file%)" metaflac --set-tag=comment="$ratings" "$(mpc current -f %file%)" # echo "Not yet implemented" && notify-send "clerk" "Rating Tracks is not yet implemented" elif [[ "$extension" == mp3 ]]; then eyeD3 --add-comment "$ratings" "$(mpc current -f %file%)" fi fi } loadRatedAlbums () { cd "$music_path" ratings="$(echo " " | dmenu_t -p "Rating: > " | xargs echo)" albums="$(grep -r "$ratings/10" **/rating.txt | sed -e 's/\/rating.txt.*//g')" album="$(echo -e "replace all\nadd all\n---\n$albums" | dmenu_t)"; if [ "$album" = "" ]; then ratePrompt; elif [ "$album" = "replace all" ]; then mpc clear grep -r "$ratings/10" **/rating.txt | sed -e 's/\/rating.txt.*//g' | while read line; do mpc add "$line" && mpc play; done elif [ "$album" = "add all" ]; then grep -r "$ratings/10" **/rating.txt | sed -e 's/\/rating.txt.*//g' | while read line; do mpc add "$line"; done ; else mpc add "$album" fi } loadRatedTracks () { ratings="$(echo " " | dmenu_t -p "Rating: > " | xargs echo)" if [ ratings = "" ]; then exit else for i in "$ratings"; do mpc find comment "$i" | mpc add; done fi } loadRandomRatedTracks () { number="$(echo " " | dmenu_t -p "Number of Songs: > " | xargs echo)" ratings_min="$(echo " " | dmenu_t -p "Minimum Rating: > " | xargs echo)" ratings_max="$(echo " " | dmenu_t -p "Maximum Rating: > " | xargs echo)" for ((i="$ratings_min"; i<="$ratings_max"; i++)); do mpc find comment "$i" | shuf | head -n "$number" | mpc add; done } loadRandomRating () { cd "$music_path" ratings_min="$(echo " " | dmenu_t -p "Minimum Rating: > " | xargs echo)" ratings_max="$(echo " " | dmenu_t -p "Maximum Rating: > " | xargs echo)" mpc clear grep -lF "$(seq $ratings_min $ratings_max)" **/rating.txt | sed -e 's/\/rating.txt.*//g' | shuf -n 1 | while read line; do mpc add "$line" && mpc play; done } playRandomAlbum () { mpc clear artist="$(mpc list "$mpd_artist" | shuf | head -1)" album="$(mpc list album "$mpd_artist" "$artist" | shuf | head -1)" mpc find album "$album" "$mpd_artist" "$artist" | mpc add && mpc play } playRandomTracks () { n=0; while (( n++ < $value )); do artist="$(mpc list artist | shuf | head -1)" album="$(mpc list album artist "$artist" | shuf | head -1)" title="$(mpc list title album "$album" artist "$artist" | shuf | head -1)" mpc find album "$album" artist "$artist" title "$title" | mpc add done } dplay () { case $1 in -x) ARTIST=$(echo -e "Adding Mode: Add\n----------------\n$(mpc list artist)" | dmenu_t -p "$2 Choose Artist: > "); if [[ "$ARTIST" = "" ]] then dplayPrompt else if [[ "$ARTIST" == "Adding Mode: Add" ]]; then dplay -xi else mpc find artist "$ARTIST" | mpc add fi fi ;; -xi) ARTIST=$(echo -e "Adding Mode: Insert\n----------------\n$(mpc list artist)" | dmenu_t -p "$2 Choose Artist: > "); if [[ "$ARTIST" = "" ]] then dplayPrompt else if [[ "$ARTIST" == "Adding Mode: Insert" ]]; then dplay -xr else mpc find artist "$ARTIST" | mpc insert fi fi ;; -xr) ARTIST=$(echo -e "Adding Mode: Replace\n----------------\n$(mpc list artist)" | dmenu_t -p "$2 Choose Artist: > "); if [[ "$ARTIST" = "" ]] then dplayPrompt else if [[ "$ARTIST" == "Adding Mode: Replace" ]]; then dplay -x else mpc clear && mpc find artist "$ARTIST" | mpc add && mpc play fi fi ;; -a) ALBUM=$(echo -e "Adding Mode: Add\n----------------\n$(mpc list album)" | dmenu_t -p "$2 Choose Album: > "); if [[ "$ALBUM" = "" ]] then dplayPrompt else if [[ "$ALBUM" == "Adding Mode: Add" ]]; then dplay -ai else mpc find album "$ALBUM" | mpc add fi fi ;; -ai) ALBUM=$(echo -e "Adding Mode: Insert\n----------------\n$(mpc list album)" | dmenu_t -p "$2 Choose Album: > "); if [[ "$ALBUM" = "" ]] then dplayPrompt else if [[ "$ALBUM" == "Adding Mode: Insert" ]]; then dplay -ar else mpc find album "$ALBUM" | mpc insert fi fi ;; -ar) ALBUM=$(echo -e "Adding Mode: Replace\n----------------\n$(mpc list album)" | dmenu_t -p "$2 Choose Album: > "); if [[ "$ALBUM" = "" ]] then dplayPrompt else if [[ "$ALBUM" == "Adding Mode: Replace" ]]; then dplay -a else mpc clear && mpc find album "$ALBUM" | mpc add && mpc play fi fi ;; -t) TRACK=$(echo -e "Adding Mode: Add\n---------------\n$(mpc listall)" | dmenu_t -p "$2 Choose Track: > "); if [[ "$TRACK" = "" ]] then dplayPrompt else if [[ "$TRACK" == "Adding Mode: Add" ]]; then dplay -ti else mpc add "$TRACK" fi fi ;; -ti) TRACK=$(echo -e "Adding Mode: Insert\n---------------\n$(mpc listall)" | dmenu_t -p "$2 Choose Track: > "); if [[ "$TRACK" = "" ]] then dplayPrompt else if [[ "$TRACK" = "Adding Mode: Insert" ]]; then dplay -tr else mpc insert "$TRACK" fi fi ;; -tr) TRACK=$(echo -e "Adding Mode: Replace\n----------------\n$(mpc listall)" | dmenu_t -p "$2 Choose Track: > "); if [[ "$TRACK" = "" ]] then dplayPrompt else if [[ "$TRACK" = "Adding Mode: Replace" ]]; then dplay -t else mpc clear && mpc add "$TRACK" && mpc play fi fi ;; -ct) if [[ $2 == replace ]] then mpc clear mpc add "$3" && mpc play; elif [[ $2 == insert ]] then mpc insert "$3"; else mpc add "$3"; fi ;; -ca) if [[ $2 == replace ]] then mpc clear mpc find album "$3" | mpc add && mpc play; elif [[ $2 == insert ]] then mpc find album "$3" | mpc insert; else mpc find album "$3" | mpc add; fi ;; esac } testingPrompt() { menu=("1 Play Album" "2 Add a Song" "---" "0 back to mpd menu") prompt() { printf "%s\n" "$@" | dmenu_t -p "Testing Menu: > " } case "$(prompt "${menu[@]}")" in 1*) testAddAlbum ;; 2*) testAddTrack ;; 0*) dplayPrompt ;; *) dplayPrompt esac } testAddAlbum() { TRACK=$(mppc listall --format '{date} {album}' | uniq | dmenu_t -dmenu -p "Choose Album > ") if [[ "$TRACK" = "" ]] then dplayPrompt else date=$(echo "$TRACK" | cut -d ' ' -f1) album=$(echo "$TRACK" | cut -d ' ' -f2-) mpc clear && mppc searchadd date "$date" album "$album" && mppc play fi } testAddTrack() { TRACK=$(mppc listall --format '{artist} • {track} • {title} • {album}'| dmenu_t -dmenu -p "Choose Track > ") if [[ "$TRACK" = "" ]] then dplayPrompt else artist=$(echo "$TRACK" | awk -F ' • ' '{print $1}') album=$(echo "$TRACK" | awk -F ' • ' '{print $4}') track=$(echo "$TRACK" | awk -F ' • ' '{print $2}') title=$(echo "$TRACK" | awk -F ' • ' '{print $3}') mppc searchadd artist "$artist" album "$album" title "$title" fi } browseLib() { browseAlbum() { ALBUMS=$(mppc list album "$ARTIST") ALBUM=$(echo -e "replace all\nadd all\ninsert all\n--------------------------\n$(mppc find artist "$ARTIST" --format '{date} • {album}' | sort | uniq)" | dmenu_t -dmenu -p "Choose Album > ") ALBUM_FINAL=$(echo "$ALBUM" | awk -F ' • ' '{ print $2 }') DATE=$(echo "$ALBUM" | awk -F ' • ' '{ print $1 }') if [[ "$ALBUM" = "" ]] then dplayPrompt elif [[ "$ALBUM" = "replace all" ]] then mpc clear && mppc findadd artist "$ARTIST" && mpc play elif [[ "$ALBUM" = "add all" ]] then mppc findadd artist "$ARTIST" elif [[ "$ALBUM" = "insert all" ]] then mppc find artist "$ARTIST" --format '{file}'| mpc insert else browseTrack fi } browseTrack() { TRACK=$(echo -e "replace all\nadd all\ninsert all\n--------------------------\n$(mppc find artist "$ARTIST" album "$ALBUM_FINAL" --format '{track} • {title}')" | dmenu_t -dmenu -p "Chose Track > ") TRACKFINAL=$(echo "$TRACK" | awk -F ' • ' '{ print $2}') if [[ "$TRACK" = "" ]] then browseAlbum elif [[ "$TRACK" = "replace all" ]] then mpc clear && mppc findadd artist "$ARTIST" album "$ALBUM_FINAL" date "$DATE" && mpc play elif [[ "$TRACK" = "add all" ]] then mppc findadd artist "$ARTIST" album "$ALBUM_FINAL" date "$DATE" elif [[ "$TRACK" = "insert all" ]] then mppc find artist "$ARTIST" album "$ALBUM_FINAL" date "$DATE" --format '{file}' | mpc insert else if [[ $(mpc playlist) == "" ]]; then mppc findadd artist "$ARTIST" album "$ALBUM_FINAL" date "$DATE" title "$TRACKFINAL" && mpc play else mppc findadd artist "$ARTIST" album "$ALBUM_FINAL" date "$DATE" title "$TRACKFINAL" fi fi } browseArtist() { ARTIST=$(echo -e "replace all\nadd all\ninsert all\n--------------------------\n$(mppc list artist)" | dmenu_t -dmenu -p "Choose Artist > ") export ARTIST="$ARTIST" if [[ "$ARTIST" = "" ]] then dplayPrompt elif [[ "$ARTIST" = "replace all" ]] then mpc clear && mpc add / && mpc play elif [[ "$ARTIST" = "add all" ]] then mpc add / elif [[ "$ARTIST" = "insert all" ]] then mpc insert / else browseAlbum fi } browseArtist } ################################################################################ if [[ "$backend" == "rofi" ]] then function dmenu_t () { rofi -dmenu "$@" } elif [[ "$backend" == "dmenu" ]] then function dmenu_t () { dmenu -l 15 "$@" } elif [[ "$backend" == "slmenu" ]] then function dmenu_t () { slmenu -l 15 "$@" } fi if [[ "$1" == "-h" ]]; then echo "clerk: the mpd UI that needs typing" echo "Copyright © 2013 - 2014 Rasmus Steinke" echo "" echo "Options" echo " -h this help message" echo " -a add album()" echo " -ai insert album()" echo " -ar replace album()" echo " -t add track()" echo " -ti insert track()" echo " -tr replace track()" echo " -rate show rating prompt" echo " -rtrack rate current track" echo " -ra play random album" echo " -rs play x random songs (defined with "value" variable)" echo " -show show currently playing track" echo " -lrated add x random tracks with rating >=4" echo " -library browse the library" elif [[ "$1" == "-a" ]]; then dplay -a elif [[ "$1" == "-ai" ]]; then dplay -ai elif [[ "$1" == "-ar" ]]; then dplay -ar elif [[ "$1" == "-t" ]]; then dplay -t elif [[ "$1" == "-ti" ]]; then dplay -ti elif [[ "$1" == "-tr" ]]; then dplay -tr elif [[ "$1" == "-rate" ]]; then ratingPrompt elif [[ "$1" == "-rtrack" ]]; then rateTrack elif [[ "$1" == "-ra" ]]; then playRandomAlbum elif [[ "$1" == "-rs" ]]; then playRandomTracks elif [[ "$1" == "-show" ]]; then notify-send "$(mpc current --format '%artist% - %title%')" "$(mpc current --format '\n%date% %album%')" elif [[ "$1" == "-lrated" ]]; then mpc clear && for ((i=4; i<="5"; i++)); do mpc find comment "$i" | shuf | head -n "$value" | mpc add; done && mpc play elif [[ "$1" == "-library" ]]; then browseLib else dplayPrompt fi