#!/usr/bin/env bash shopt -s globstar function dmenu_t () { rofi -dmenu $(echo "$rofiopts") "$@" } # load default settings # custom rofi settings (rofi reads settings from ~/.Xresources) # but you can override settings here. rofiopts="-lines 32 -width 1500 -i -no-levenshtein-sort" # custom mpd host mpd_host= mpd_port= mpd_password= # Number of Songs to be added for "Random Tracks" value=20 # stop on suspend? stop_after_suspend=no # use artist or albumartist for random tracks random_artist=artist # scrobbler to use. possible values: mpdscribble, mpdas scrobbler=mpdscribble # Fill these if scrobbler runs on a different host # set to 0 if mpdscribble runs locally ssh_lastfm=0 ssh_host= # color of the help messages help_color="#0C73C2" help_separator_color="#5F5F5F" # custom keybindings # global albumlist="Alt+F1" tracklist="Alt+F2" queue="Alt+F3" toggle="Alt+F6" prev="Alt+F5" next="Alt+F8" stop="Alt+F7" seek="Alt+f" nextalbum="Alt+Shift+F5" prevalbum="Alt+Shift+F8" # Adding of songs/albums add="Alt+1" insert="Alt+2" replace="Alt+3" rate="Alt+r" addplay="Alt+4" insertplay="Alt+5" savefav="Alt+s" # playlist menu # also used: rate delete="Alt+Delete" crop="Alt+x" clear="Alt+c" movedown="Alt+Down" moveup="Alt+Up" goalbum="Alt+a" gotrack="Alt+t" chplaylist="Alt+p" # table customization track_width="2" title_width="40" artist_width="40" date_width="6" # album is much longer in order to keep filename off screen album_width="200" # custom widths for playlist pl_title_width="60" pl_artist_width="40" # override settings from global config file, if present if [[ ! -f $HOME/.config/clerk/config ]] && [[ ! -f /etc/clerk ]]; then echo "Error: could not find configuration file \"$HOME/.config/clerk/config\"" echo "You can use the provided example configuration file (config.clerk), copy it to the above location and edit it to your needs." exit fi if [[ -f /etc/clerk.conf ]]; then source /etc/clerk.conf fi # override settings from local config, if present if [[ -f $HOME/.config/clerk/config ]]; then source $HOME/.config/clerk/config fi if [[ -n $mpd_host ]]; then if [[ -n $mpd_password ]]; then export MPD_HOST="${mpd_password}@${mpd_host}" else export MPD_HOST="${mpd_host}" fi fi if [[ -n $mpd_port ]]; then export MPD_PORT="${mpd_port}" fi # check for scrobbler if [[ $scrobbler == mpdas ]]; then export scrobbler="mpdas -d" export scrobbler_kill="mpdas" elif [[ $scrobbler == mpdscribble ]]; then export scrobbler_kill="mpdscribble" fi # set help color if [[ $help_color == "" ]]; then help_color=$(dmenu_t -dump-xresources | grep -P '^rofi.color.normal' | awk -F ',' '{ print $2 }' | xargs) help_separator_color=$(dmenu_t -dump-xresources | grep -P 'rofi.color.normal' | awk -F ',' '{ print $2 }' | xargs) fi fix_date_format() { # provided by Thorsten Wißmann: # https://github.com/t-wissmann/dotfiles/blob/master/menu/rofi-mpd.sh # reformats the date given in column $1 from format %c of locale LC_TIME=C # (see man strftime) to the format specified in argument $2 column indices # start with 1 column_index="$1" gawk -F $'\t' ' # parse a date which was formated using %c to unix time BEGIN { # generated by the following bash one-liner: # for i in {1..12} ; do LC_TIME=C date -d "1972-$i-01" +month2num[\"%b\"]\ =\ %_m ; done month2num["Jan"] = 1 month2num["Feb"] = 2 month2num["Mar"] = 3 month2num["Apr"] = 4 month2num["May"] = 5 month2num["Jun"] = 6 month2num["Jul"] = 7 month2num["Aug"] = 8 month2num["Sep"] = 9 month2num["Oct"] = 10 month2num["Nov"] = 11 month2num["Dec"] = 12 } function reformat_c_date(str) { monthname = gensub(/^([^ ]*)[ ]+([^ ]*)[ ]+([^ ]*)[ ]+([^ ]*)[ ]+([^ ]*)$/, "\\2", "g", str) monthnum = month2num[monthname] nicedate = gensub(/^([^ ]*)[ ]+([^ ]*)[ ]+([^ ]*)[ ]+([^ ]*)[ ]+([^ ]*)$/, "\\5 " monthnum " \\3 \\4", "g", str) nicedate = gensub(/:/, " ", "g", nicedate) return nicedate } { # modify the $column_index-th field $'"$1"' = strftime("'"$2"'", mktime(reformat_c_date($'"$1"'))) print $0 } ' } updateCache () { notify-send "clerk" "updating cache files" cd $HOME/.config/clerk rm -f *.cache mpc --format '%mtime%\t[%albumartist%|%artist%] — (%date%) — %album%' \ search filename '' \ | fix_date_format 1 '%Y-%m-%d-%H:%M:%S' \ | sort -nr \ | gawk '{for (i=2; i $HOME/.config/clerk/latest.cache # | sed 's,^\([^\t]*\t[^\t]\{40\}\)[^\t]*,\1,' | column -o $'\t' -s $'\t' -t | uniq > $HOME/.config/clerk/latest.cache mpc --format '[%albumartist%|%artist%]\t(%date%)\t%album%' \ search filename '' \ | sort \ | uniq \ | gawk -F '\t' '{ printf "%."'${artist_width}'"s\t%."'${date_width}'"s\t%."'${album_width}'"s\n", $1, $2, $3 }' \ | column -s $'\t' -t > $HOME/.config/clerk/albums.cache mpc --format '%track%\t%title%\t%artist%\t(%date%)\t%album%\t%file%' \ search filename '' \ | gawk -F '\t' '{ printf "%."'${track_width}'"s\t%."'${title_width}'"s\t%."'${artist_width}'"s\t%."'${date_width}'"s\t%."'${album_width}'"s\t%.500s\n", $1, $2, $3, $4, $5, $6 }' \ | column -s $'\t' -t \ > $HOME/.config/clerk/tracks.cache notify-send "clerk" "finished updating cache files" date=$(mpc stats | grep 'DB Updated: ') file="$HOME/.config/clerk/.lastupdate" echo "${date}" > "${file}" # | gawk -F '\t' '{ printf "%.2s\t%.40s\t%.40s\t%.200s\t%.500s\n", $1, $2, $3, $4, $5, $6 }' \ if [[ $forceupdate == "true" ]]; then exit fi } date=$(mpc stats | grep 'DB Updated: ') file="$HOME/.config/clerk/.lastupdate" if [ "$(< $file)" = "$date" ] && [ -f "$file" ] ; then : else updateCache date=$(mpc stats | grep 'DB Updated: ') echo "${date}" > "${file}" break fi # Use GNU coreutils on OSX sed=$([[ "$OSTYPE" == "darwin"* ]] && echo 'gsed' || echo 'sed') shuf=$([[ "$OSTYPE" == "darwin"* ]] && echo 'gshuf' || echo 'shuf') tac=$([[ "$OSTYPE" == "darwin"* ]] && echo 'gtac' || echo 'tac') # main Menu dplayPrompt () { if [[ -z $(mpc status | grep "/") ]]; then song="No Song is playing" else song=$(mpc current) fi menu=$(echo -e "< Exit\n---\n1 [ Browse Library ]>\n2 [ Current Artist ]>\n3 [ Current Queue ]>\n---\n4 [ Options ]>\n5 [ Ratings ]>\n6 [ Help ]" \ | dmenu_t \ -dmenu \ -lines 17 \ -mesg "Currently Playing: ${song}" \ -auto-select \ -kb-custom-1 ${prev} \ -kb-custom-2 ${toggle} \ -kb-custom-3 ${stop} \ -kb-custom-4 ${next} \ -kb-custom-5 ${albumlist} \ -kb-custom-6 ${tracklist} \ -kb-custom-7 ${queue} \ -kb-custom-8 ${seek} \ -kb-custom-9 ${nextalbum} \ -kb-custom-10 ${prevalbum} \ -p "clerk > ") val=$? if [[ $val -eq 1 ]]; then exit elif [[ $val -eq 10 ]]; then mpc prev dplayPrompt elif [[ $val -eq 11 ]]; then mpc toggle dplayPrompt elif [[ $val -eq 12 ]]; then mpc stop dplayPrompt elif [[ $val -eq 13 ]]; then mpc next dplayPrompt elif [[ $val -eq 14 ]]; then addAlbum alphabet elif [[ $val -eq 15 ]]; then addTrackTags elif [[ $val -eq 16 ]]; then dplayQueue elif [[ $val -eq 17 ]]; then seekMenu elif [[ $val -eq 18 ]]; then skipAlbum next unset IFS dplayPrompt elif [[ $val -eq 19 ]]; then skipAlbum prev unset IFS dplayPrompt fi if [[ "$menu" == "< Exit" ]]; then exit elif [[ "$menu" == "2 "* ]]; then currentMenu elif [[ "$menu" == "3 "* ]]; then dplayQueue elif [[ "$menu" == "1 "* ]]; then browseLibPrompt elif [[ "$menu" == "4 "* ]]; then dplayOptionsPrompt elif [[ "$menu" == "5 "* ]]; then ratingPrompt elif [[ "$menu" == "6 "* ]]; then helpMenu elif [[ -z "$menu" ]]; then exit fi } helpMenu () { showhelp=$(echo -e "< Return\n \ ---\n \ # Global\n \ Album List: "${albumlist}"\n \ Track List: "$tracklist"\n \ Queue: "$queue"\n \ Toggle Playback "$toggle"\n \ Previous: "$prev"\n \ Previous Album: "$prevalbum"\n \ Next: "$next"\n \ Next Album: "$nextalbum"\n \ Stop: "$stop"\n \ Seek: "$seek"\n \ \n \ # Adding of Songs/Albums\n \ Add: "$add"\n \ Insert: "$insert"\n \ Replace: "$replace"\n \ Rate: "$rate"\n \ Add & Play: "$addplay"\n \ Insert & Play: "$insertplay"\n \ Save to Favs: "$savefav"\n \ \n \ # Playlist Menu\n \ Delete selected "$delete"\n \ Crop Playlist: "$crop"\n \ Clear Playlist: "$clear"\n \ Move Down: "$movedown"\n \ Move Up: "$moveup"\n \ Go to Album: "$goalbum"\n \ Go to Track: "$gotrack"\n \ Load/Save: "$playlist"" | dmenu_t -dmenu -p "Hotkeys > ") val=$? if [[ $val -eq 1 ]]; then exit fi if [[ $showhelp == "< Return" ]]; then dplayPrompt else helpMenu fi } seekMenu () { seekval="$((echo -e "< Return\n---\n$(for i in $(seq 0 10 100); do echo "${i}%"; done)") \ | dmenu_t -dmenu \ -p "Seek > ")" if [[ $seekval == *"%" ]]; then mpc seek "${seekval}" unset seekval $* elif [[ $seekval == "< Return" ]]; then unset seekval $* elif [[ $seekval == "---" ]]; then unset seekval $* fi } # start/stop scrobbler. locally or remote lastFM () { # Some Variables to clean up the code if [[ $ssh_lastfm == 1 ]]; then mpds_check="$(ssh $ssh_host -q -t "pgrep $scrobbler_kill")" if [ -n "$mpds_check" ]; then ssh $ssh_host -q -t "killall $scrobbler_kill" && notify-send "MPD" "LastFM Scrobbling Disabled" else ssh $ssh_host -q "$scrobbler" && notify-send "MPD" "LastFM Scrobbling Enabled" fi else if pgrep $scrobbler_kill then killall $scrobbler_kill && notify-send "MPD" "LastFM Scrobbling Disabled" else $scrobbler && notify-send "MPD" "LastFM Scrobbling Enabled" fi fi } lastFMCheck () { # Some Variables to clean up the code if ((ssh_lastfm)); then mpds_check="$(ssh $ssh_host -q -t "pgrep $scrobbler_kill")" if [ -n "$mpds_check" ]; then echo "lastfm: off" else echo "lastfm: on" fi else if pgrep $scrobbler_kill then echo "lastfm: on" else echo "lastfm: off" fi fi } currentMenu () { if [[ $1 == "album" ]]; then album_entry="${filename}" addAlbum alphabet elif [[ $1 == "track" ]]; then entry="${filename}" addTrackTags fi menu=$(echo -e "< Return\n---\n1 [ Browse Albums ]>\n2 [ Browse Tracks ]>" \ | rofi \ -dmenu \ -p "Browse for $(mpc current -f '%artist%')") if [[ $menu == "1 [ Browse Albums ]>" ]]; then filter=$(mpc current -f '%artist%') firstsong=$(mpc -f '%album% %album%' search artist "$(mpc current -f '%artist%')" album "$(mpc current -f '%album%')" | head -1) album_entry="$firstsong" filter="$filter" addAlbum alphabet elif [[ $menu == "2 [ Browse Tracks ]>" ]]; then filter=$(mpc current -f '%artist%') firstsong=$(mpc -f '%file%' search artist "$(mpc current -f '%artist%')" title "$(mpc current -f '%title%')" album "$(mpc current -f '%album%')" | head -1) entry="$firstsong" filter="$filter" addTrackTags elif [[ $menu == "" ]]; then dplayPrompt elif [[ $menu == "< Return" ]]; then dplayPrompt else : fi } # rating menu ratingPrompt () { menu=("< Return" "---" "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 Backup/Restore") 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*) loveLast ;; 0*) backupPrompt ;; \<*) dplayPrompt ;; *) exit esac } # create rating json files from mpd sticker database and vice versa backupPrompt () { menu=("< Return" "---" "1 Backup Album Ratings to File" "2 Backup Track Ratings to File" "---" "3 Restore Ratings from File") prompt() { printf "%s\n" "$@" | dmenu_t -p "Backup/Restore > " } case "$(prompt "${menu[@]}")" in 1*) clerk_helper importalbumratings & ;; 2*) clerk_helper importtrackratings & ;; 3*) clerk_helper sendstickers & ;; \<*) ratingPrompt ;; *) exit esac } # if mpdas is used use mpc to love track on last.fm. otherwise try # lastfm-mpd-cli loveLast () { if [[ "$scrobbler" == "mpdscribble" ]]; then lastfm-mpd-cli love > /dev/null && notify-send "MPD" "Loved $(mpc current -f '%title%') on LastFM" && exit elif [[ "$scrobbler" == "mpdas" ]]; then mpc sendmessage mpdas love fi } infoPrompt () { menu=("0 Return to Main Menu" "---" "1 Artist Info" "2 Album Info" "3 Current Track Lyrics" "4 Current Track Tags") prompt() { printf "%s\n" "$@" | dmenu_t -p "MPD Menu > " } case "$(prompt "${menu[@]}")" in # 1*) surfraw yubnub allmusic $(mpc current -f %artist%) ;; 1*) artistinfo ;; 2*) surfraw yubnub allmusic $(mpc current -f %album%) && exit;; # 3*) surfraw yubnub google $(mpc current -f %title%) $(mpc current -f %artist%) lyrics ;; 3*) lyrics ;; 4*) currentTag ;; \<*) dplayPrompt ;; *) exit esac } currentTag () { declare -i seen=0 while read line do seen=1 if [[ "$line" == "0 Return to Main Menu" ]]; then dplayPrompt elif [[ "$line" == "Show all Tags" ]]; then readComments elif [[ "$line" == "" ]]; then return fi done < <(echo -e "0 Return to Main Menu\n---\nShow all Tags\n---\n$(mpc current --format "Artist: %artist%\nAlbum: %album%\nDate: %date%\nTrack: %track%\nTitle: %title%")" | dmenu_t -p 'Current Song > ') if [[ $seen = 0 ]] then exit fi } # read all tags from file. Note that mpd can only read vorbiscomment properly readComments () { declare -i seen=0 while read line do seen=1 if [[ "$line" == "0 Return to Main Menu" ]]; then dplayPrompt elif [[ "$line" == "Show Tags" ]]; then currentTag elif [[ "$line" == "" ]]; then return fi done < <(echo -e "0 Return to Main Menu\n---\nShow Tags\n---\n$(mpc current --format '%file%' | clerk_helper readcomments)" | dmenu_t -p 'Current Song > ') if [[ $seen = 0 ]] then exit fi } # Messy options menu. dplayOptionsPrompt () { # define variables to be used in menu export status="$(mpc status)" single=$(echo "$status" | tail -1 | gawk -F ':' '{ print $5 }' | cut -d ' ' -f 2) random=$(echo "$status" | tail -1 | gawk -F ':' '{ print $4 }' | cut -d ' ' -f 2) consume=$(echo "$status" | tail -1 | gawk -F ':' '{ print $6 }' | cut -d ' ' -f 2) repeat=$(echo "$status" | tail -1 | gawk -F ':' '{ print $3 }' | cut -d ' ' -f 2) if [[ -a /tmp/mpd-sima.pid ]]; then export sima=on else export sima=off fi if [[ "$ssh_lastfm" == "1" ]]; then mpds_check="$(ssh $ssh_host -q -t "pgrep $scrobbler_kill")" if [ -n "$mpds_check" ]; then export scrobble=on else export scrobble=off fi else if pgrep $scrobbler_kill 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=("< Return" "---" "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 Similar Artists Mode: $(echo $sima)" "---" "8 Set Crossfade $(mpc crossfade | cut -d ':' -f2)" "9 Manage Outputs" "0 Number of Random Songs: $(echo $value)") prompt() { printf "%s\n" "$@" | dmenu_t -auto-select -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*) mpdSima && dplayOptionsPrompt ;; 8*) crossfadePrompt ;; 9*) outputPrompt ;; 0*) optionRandomPrompt ;; \<*) dplayPrompt ;; *) exit esac } # toggle similar artist playback mpdSima () { if [[ -a /tmp/mpd-sima.pid ]]; then kill $(cat /tmp/mpd-sima.pid) sleep 1 else mpd-sima -d -p /tmp/mpd-sima.pid sleep 1 fi } # function to change number of random songs in config file optionRandomPrompt() { number="$(echo -e " " | 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=$(echo -e "< Return\n---\n0\n1\n2\n3\n4\n5" | dmenu_t -p "Crossfade") if [[ $menu == "< Return" ]]; then dplayOptionsPrompt else mpc crossfade ${menu}; dplayOptionsPrompt fi } # read list of available podcasts. Not using mpd playlists, because mpd does # not support custom names for urls. format of podcast in file is "Name \ URL" loadRSS () { podcast=$(echo -e "< Return\n---\n$(cat $HOME/.config/clerk/podcasts | cut -d '\' -f1)" | dmenu_t -p "Choose Podcast > ") if [[ $podcast == "< Return" ]]; then dplayQueue else mpc clear mpc load $(grep "$podcast" $HOME/.config/clerk/podcasts | cut -d '\' -f2) episode=$(mpc playlist --format "%position% — %artist% — %title%" | dmenu_t -p "Choose Episode > ") POS=$(echo "$episode" | gawk -F " — " '{ print $1 }') mpc play "$POS" fi } # suspend current playlist. playlist, song id and play-position are saved to # $HOME/.config/clerk/suspend suspendPlaylist () { playing=$(! mpc status | grep 'playing\|paused') time=$(mpc status | $sed '2!d;s;/.:.*;;;s;.* ;;') position=$(mpc current --format '%position%') if [[ -z "$playing" ]]; then notify-send "clerk" "mpd is not playing, no state to suspend" else mpc rm suspended mpc save suspended rm -f $HOME/.config/clerk/suspend echo "pos="$position"" >> $HOME/.config/clerk/suspend echo "time="$time"" >> $HOME/.config/clerk/suspend if [[ "$stop_after_suspend" == yes ]]; then mpc stop else echo " " fi notify-send "Clerk" "Playlist suspended" dplayQueue fi } # read $HOME/.config/clerk/suspend and restore playlist. Then start playing # from same position that was saved in suspend file resumePlaylist () { http=$(! mpc current --format %file% | grep 'http://') source $HOME/.config/clerk/suspend mpc clear mpc load suspended mpc play $pos mpc toggle sleep 2 mpc seek "$time" mpc toggle notify-send "Clerk" "Resumed last-suspended Playlist" dplayQueue } # Play or delete items from current Queue dplayQueue () { while true; do if [[ $val -eq 1 ]]; then exit fi re='^[0-9]+$' if [[ "$POS" =~ $re ]]; then if [[ $last != $(mpc -f '%file%' playlist | tail -1) ]]; then POS=$(echo $(( $POS + 1 ))) elif [[ -z $last ]]; then POS=$(echo $(( $POS + 2 ))) else POS=$(echo $(( $POS + 2 ))) fi else mpd_play=$(mpc status | mpc status | grep -E '\[playing\]|\[paused\]') if [[ -n ${mpd_play} ]]; then POS=$(echo $(( $(mpc current -f '%position%') + 1 ))) else POS=$(echo $(( $(mpc current -f '%position%') + 2 ))) fi fi select="-selected-row $POS" help_text="$(echo -e "${delete}: Delete - ${crop}: Crop - ${moveup}: Move Up - ${goalbum}: Go to Album - ${chplaylist}: Load/Save\n${clear}: Clear - ${rate}: Rate - ${movedown}: Move Down - ${gotrack}: Go to Track" | column -s '-' -t | perl -pe "s/ - /\|\<\/span\>/g")" line1=$(echo "${help_text}" | head -1) line2=$(echo "${help_text}" | tail -1) HELP="${line1} ${line2}" songs () { mpc --format '%position%\t%track%\t%title%\t%artist%\t(%date%)\t%album%' playlist \ | gawk -F '\t' '{ printf "%.4s\t%."'${track_width}'"s\t%."'${pl_title_width}'"s\t%."'${pl_artist_width}'"s\t%."'${date_width}'"s\t%."'${album_width}'"s\n", $1, $2, $3, $4, $5, $6 }' \ | column -s $'\t' -t } if [[ -n $(mpc current) ]]; then current=$(mpc current -f '%position%') highlight="-a $(echo $(( $current +1 )))" else : fi TRACKDISPLAY=$(echo -e "< Return\n---\n$(songs)" \ | dmenu_t \ -kb-custom-1 "${delete}" \ -kb-custom-2 "${rate}" \ -kb-custom-4 "${prevalbum}" \ -kb-custom-3 "${nextalbum}" \ -kb-custom-5 "${clear}" \ -kb-custom-6 "${moveup}" \ -kb-custom-7 "${movedown}" \ -kb-custom-8 "${toggle}" \ -kb-custom-9 "${stop}" \ -kb-custom-10 "${albumlist}" \ -kb-custom-11 "${tracklist}" \ -kb-custom-12 "${goalbum}" \ -kb-custom-13 "${gotrack}" \ -kb-custom-14 "${chplaylist}" \ -kb-custom-15 "${next}" \ -kb-custom-16 "${crop}" \ -kb-custom-18 "${stop}" \ -kb-custom-19 "${seek}" \ -kb-custom-17 "${prev}" \ -dmenu $(echo "${select}") $(echo "${highlight}") \ -mesg "${HELP}" \ -p "Current Queue > ") val=$? TRACKDISPLAY_NEW=$(echo "${TRACKDISPLAY}" | perl -pe "s/ +/\t/g") POS=$(echo "${TRACKDISPLAY_NEW}" | gawk -F '\t' '{ print $1 }') ARTIST=$(echo "${TRACKDISPLAY_NEW}" | gawk -F '\t' '{ print $4 }') TITLE=$(echo "${TRACKDISPLAY_NEW}" | gawk -F '\t' '{ print $3 }') if [[ $val -eq 1 ]]; then exit elif [[ $val -eq 10 ]]; then last=$(mpc playlist -f '%file%' | tail -1) mpc del $POS; POS2=$(echo "$POS" | head -1) POS=$(( $POS2 - 1)); dplayQueue elif [[ $val -eq 19 ]]; then addAlbum alphabet elif [[ $val -eq 20 ]]; then addTrackTags elif [[ $val -eq 23 ]]; then plMenu elif [[ $val -eq 24 ]]; then mpc next mpd_play=$(mpc status | mpc status | grep -E '\[playing\]|\[paused\]') if [[ -n ${mpd_play} ]]; then POS=$(echo $(( $(mpc current -f '%position%') + 0 ))) fi elif [[ $val -eq 26 ]]; then mpc prev mpd_play=$(mpc status | mpc status | grep -E '\[playing\]|\[paused\]') if [[ -n ${mpd_play} ]]; then POS=$(echo $(( $(mpc current -f '%position%') + 0 ))) fi elif [[ $val -eq 27 ]]; then mpc stop elif [[ $val -eq 28 ]]; then seekMenu elif [[ $val -eq 21 ]]; then temp=$(mpc playlist --format '%position%\t%file%' | grep -P "^${POS}\t" | gawk -F '\t' '{ print $2 }') info=$(mpc --format '%albumartist%\t%album%\t%date%\t%track%\t%title%' search filename "${temp}") ARTIST=$(echo "${info}" \ | gawk -F '\t' '{ print $1 }') ALBUM=$(echo "${info}" \ | gawk -F '\t' '{ print $2 }') DATE=$(echo "${info}" \ | gawk -F '\t' '{ print $3 }') filename="${ARTIST} ${ALBUM}" currentMenu album elif [[ $val -eq 22 ]]; then filename=$(mpc playlist --format '%position%\t%file%' | grep -P "^${POS}\t" | grep "${ARTIST}" | gawk -F '\t' '{ print $2 }') currentMenu track elif [[ $val -eq 25 ]]; then unset last if [[ $TRACKDISPLAY_NEW == *">"* || $TRACKDISPLAY_NEW == *"<"* || $TRACKDISPLAY_NEW == "---" ]]; then mpc crop else mpc play $POS; mpc crop fi elif [[ $val -eq 16 ]]; then if [[ $(echo "$TRACKDISPLAY_NEW" | wc -l) -gt 1 ]]; then : # unset last # posSelect=$(echo "$(songs)" | dmenu_t -dmenu -mesg "Move after >") # if [[ $posSelect == "" ]]; then # exit; # else # chosenPos=$(echo "$posSelect" | awk -F ' ' '{print $1}') # trackids="$(echo -e "$POS\n" | sed \$d)" # POS=$(echo -e "$trackids" | head -1) # echo "$trackids" | sort -n | tac | while read POS2; do # mpc mv $POS2 $chosenPos # chosenPos=$chosenPos # done # POS=$(echo "${chosenPos}"); # fi else unset last mpc mv $POS $(echo $(( $POS + 1 ))) POS=$(echo $(( $POS + 1 ))); fi elif [[ $val -eq 15 ]]; then if [[ $(echo "$TRACKDISPLAY_NEW" | wc -l) -gt 1 ]]; then : # unset last # posSelect=$(echo "$(songs)" | dmenu_t -dmenu -mesg "Move after >") # if [[ $posSelect == "" ]]; then # exit; # else # chosenPos=$(echo "$posSelect" | awk -F ' ' '{print $1}') # trackids="$(echo -e "$POS\n" | sed \$d)" # POS=$(echo -e "$trackids" | head -1) # echo "$trackids" | sort -n | tac | while read POS2; do # mpc mv $POS2 $chosenPos # chosenPos=$chosenPos # done # POS=$(echo "${chosenPos}"); # fi else unset last mpc mv $POS $(echo $(( $POS - 1 ))) POS=$(echo $(( $POS - 1 ))); fi elif [[ $val -eq 17 ]]; then unset last mpc toggle mpd_play=$(mpc status | mpc status | grep -E '\[playing\]|\[paused\]') if [[ -n ${mpd_play} ]]; then POS=$(echo $(( $(mpc current -f '%position%') + 0 ))) fi elif [[ $val -eq 18 ]]; then unset last mpc stop elif [[ $val -eq 12 ]]; then unset last skipAlbum next unset IFS mpd_play=$(mpc status | mpc status | grep -E '\[playing\]|\[paused\]') if [[ -n ${mpd_play} ]]; then POS=$(echo $(( $(mpc current -f '%position%') + 0 ))) fi dplayQueue elif [[ $val -eq 13 ]]; then unset last skipAlbum prev unset IFS mpd_play=$(mpc status | mpc status | grep -E '\[playing\]|\[paused\]') if [[ -n ${mpd_play} ]]; then POS=$(echo $(( $(mpc current -f '%position%') + 0 ))) fi dplayQueue elif [[ $val -eq 14 ]]; then unset last if [[ $TRACKDISPLAY_NEW == *""* ]]; then mpc clear fi elif [[ $val -eq 0 ]]; then unset last if [[ $TRACKDISPLAY_NEW == "< Return" ]]; then dplayPrompt else mpc play $POS; fi elif [[ $val -eq 11 ]]; then unset last filename=$(mpc playlist --format '%position%\t%file%' | grep "^${POS}" | grep "${ARTIST}" | gawk -F '\t' '{ print $2 }') info=$(mpc --format '%artist%\t%album%\t%date%\t%track%\t%title%' search filename "${filename}") echo "${info}" ARTIST=$(echo "${info}" \ | gawk -F '\t' '{ print $1 }') ALBUM=$(echo "${info}" \ | gawk -F '\t' '{ print $2 }') DATE=$(echo "${info}" \ | gawk -F '\t' '{ print $3 }') TRACK=$(echo "${info}" \ | gawk -F '\t' '{ print $4 }') TITLE=$(echo "${info}" \ | gawk -F '\t' '{ print $5 }') rateartist="${ARTIST}" ratealbum="${ALBUM}" ratetrack="${TRACK}" ratetitle="${TITLE}" rateTrack elif [[ $TRACKDISPLAY_NEW == "< Return" ]]; then dplayQueue fi done } plMenu () { plmenu=$(echo -e "< Return\n---\n1 [ Load Playlist ]\n2 [ Save Playlist ]" | dmenu_t -auto-select -dmenu -p "Load/Save Playlist > ") if [[ $plmenu == "1"* ]]; then dplayQueueLoad elif [[ $plmenu == "2"* ]]; then dplayQueueSave elif [[ $plmenu == "< Return" ]]; then dplayQueue elif [[ $plmenu == "" ]]; then exit fi } skipAlbum () { IFS=' ' _PLAYLISTTEMP=$(mpc playlist --format "%album%" | awk -F'\n' '{print "_" $1}') _PLAYLIST=($_PLAYLISTTEMP) ACTNR=$(mpc --format "%position%" | head -n 1) # works >= mpc git 2009-11-28 ACTALBUM="_"$(mpc --format "%album%" | head -n 1) SONGSANZ=${#_PLAYLIST[*]} case $1 in next) # Next album for (( IDX=$ACTNR; $IDX<$SONGSANZ; IDX++ )) do if [ ${_PLAYLIST[$IDX]} != $ACTALBUM ]; then let IDX+=1 mpc play $IDX echo New album \(next\) IDX: $IDX break fi done ;; prev) # Previous album #GETEND=FALSE ACTNRTEMP=$ACTNR let ACTNRTEMP-=2 for (( IDX=$ACTNR-2; $IDX>=0; IDX-- )) do #echo TEST0 IDX $IDX echo IDX: $IDX - ${_PLAYLIST[$IDX]} if [ ${_PLAYLIST[$IDX]} != $ACTALBUM ]; then # if [ $GETEND = TRUE ]; then if [ $IDX -ne $ACTNRTEMP ]; then #echo TEST: IDX:$IDX $ACTNRTEMP let IDX+=2 mpc play $IDX echo New album \(prev\) IDX: $IDX break fi ACTALBUM=${_PLAYLIST[$IDX]} #echo ALBUMENDE ERKANNT BEI IDX: $IDX #GETEND=TRUE fi if [ $IDX = 0 ]; then #if [ $GETEND = FALSE ]; then # mpc play 1 # break #fi mpc play 1 break fi done ;; *) echo "usage: $0 {prev|next}" ;; esac } # show all mpd playlists and load them to queue dplayQueueLoad () { _playlist=$(echo -e "< Return\n---\n$(mpc lsplaylists)" | dmenu_t -p "Load Playlist > ") val=$? if [[ $val -eq 1 ]]; then exit fi if [[ "$_playlist" == "< Return" ]]; then dplayQueue else mpc clear mpc load "$_playlist" && dplayQueue fi } # save current playlist to playlist file. dplayQueueSave () { while read playlists do val=$? if [[ $val -eq 1 ]]; then exit fi if [[ "$playlists" == "< Return" ]]; then dplayQueue elif [[ "$playlists" == "Save new Playlist" ]]; then playlist=$(echo "" | dmenu_t -p "Type Name for Playlist > ") if [[ "$playlist" == "" ]]; then dplayQueueSave else mpc save "$playlist" dplayQueue fi else playlist=$(echo -e "0 Return to Playlist Menu\n---\nYes\nNo" | dmenu_t -p "Overwrite Playlist? > ") if [[ "$playlist" == "Yes" ]]; then mpc rm "$playlists" mpc save "$playlists" elif [[ "$playlist" == "No" ]]; then playlist=$(echo "" | dmenu_t -p "Type Name for Playlist > ") if [[ "$playlist" == "" ]]; then dplayQueue else mpc save "$playlist" dplayQueue fi fi fi done < <(echo -e "< Return\n---\nSave new Playlist\n---\n$(mpc lsplaylists)" | dmenu_t -p "Choose Playlist > ") exit } # enable/disable outputs outputPrompt () { menu="$(echo -e "0 Return to Options Menu\n---\n$(mpc outputs)" \ | dmenu_t -p "Outputs > ")"; if [[ "$menu" == "0 Return to Options Menu" ]] then dplayOptionsPrompt; elif [[ "$menu" == "" ]]; then exit else mpc toggleoutput $(echo "$menu" \ | gawk '{print $2}'); notify-send "MPD" "$(echo "$menu" \ | $sed -e 's/enabled$/disabled/;ta;s/disabled$/enabled/;:a;')"; outputPrompt fi } # rate any album rateAlbum () { rating="$(seq 10 | dmenu_t -p "Select Album Rating: > ")" if [[ $rating == "" ]]; then exit else # check if rateartist was defined, if it wasn't use currently playing # track for rating, otherwise use what was delivered in the rate* # variables. if [[ -z "$rateartist" ]]; then artist=$(mpc current -f '%artist%') album=$(mpc current -f '%album%') date=$(mpc current -f '%date%') if [[ -n $(mpc find track "1" albumartist "${artist}" album "${album}" date "${date}") ]]; then track="1" else track="01" fi disc=$(mpc current -f '%disc%') export disc=${disc} export track=${track} clerk_helper ratealbum "${artist}" "${album}" "${date}" "${rating}" notify-send "clerk" "rated ${artist} - ${album} with ${rating}" else export disc=${disc} export track=${track} clerk_helper ratealbum "${rateartist}" "${ratealbum}" "${ratedate}" "${rating}" notify-send "clerk" "rated ${rateartist} - ${ratealbum} with ${rating}" fi fi } rateTrack () { rating="$(echo -e "< Return\n---\n$(seq 10)" | dmenu_t -p "Select Track Rating: > ")" if [[ $rating == "" ]]; then exit elif [[ $rating == "< Return" ]]; then dplayQueue else if [[ -z "$rateartist" ]]; then export rating=${rating} rateartist=$(mpc current -f '%artist%') ratetitle=$(mpc current -f '%title%') ratetrack=$(mpc current -f '%track%') ratealbum=$(mpc current -f '%album%') clerk_helper ratetrack "${rateartist}" "${ratealbum}" "${ratetrack}" "${ratetitle}" "${rating}" notify-send "clerk" "rated $(mpc current) with $(echo ${rating})" else clerk_helper ratetrack "${rateartist}" "${ratealbum}" "${ratetrack}" "${ratetitle}" "${rating}" notify-send "clerk" "rated ${rateartist} - ${ratetitle} with $(echo ${rating})" fi fi } # function to instantly rate a track without a submenu. rating is defined on # commandline instantRateTrack () { rateartist=$(mpc current -f '%artist%') ratetitle=$(mpc current -f '%title%') ratetrack=$(mpc current -f '%track%') ratealbum=$(mpc current -f '%album%') export rating=$1 clerk_helper ratetrack "${rateartist}" "${ratealbum}" "${ratetrack}" "${ratetitle}" "${rating}" notify-send "clerk" "rated ${rateartist} - ${ratetitle} with $(echo ${rating})" } # load rated albums with minimum rating of xx loadRatedAlbums () { rating="$(seq 10 | dmenu_t -p "Minimum Rating > ")" if [[ $rating == "" ]]; then exit else albums="$(while read -a line; do dirname "${line[*]}"; done <<< "$(mpc sticker "" find albumrating \ | grep -E "albumrating=$rating")" \ | $sed 's/\/\CD.*//g' \ | sort \ | uniq \ | dmenu_t -p "Choose Album > ")" if [[ $albums == "" ]]; then exit else mpc clear; mpc add "$albums"; mpc play fi fi } loadRatedTracks () { rating="$(seq 10 | dmenu_t -p "Rating > ")" if [ rating = "" ]; then exit else cd $HOME/.config/clerk mpc clear songs="$(mpc sticker "" find rating | grep "rating=$rating" | gawk -F ': rating=' '{ print $1 }')" echo "$songs" | mpc add mpc play fi } loadRandomRatedTracks () { number="$(echo " " | dmenu_t -p "Number of Songs > " | xargs echo)" rating="$(seq 10 | dmenu_t -p "Minimum Rating > ")" if [ rating = "" ]; then exit else cd $HOME/.config/clerk mpc clear songs="$(mpc sticker "" find rating \ | grep -E "rating=$rating|rating=$(echo $(( $rating + 1 )))|rating=$(echo $(( $rating + 2 )))|rating=$(echo $(( $rating + 3 )))|rating=$(echo $(( $rating + 4 )))" \ | gawk -F ':' '{ print $1 }')" echo "$songs" \ | $shuf -n $number \ | mpc add mpc play rm -f /tmp/clerk_tracklist fi } loadRandomRating () { rating="$(seq 10 | dmenu_t -p "Minimum Rating > ")" if [ rating = "" ]; then exit else album="$(while read -a line; do dirname "${line[*]}"; done <<< "$(mpc sticker "" find albumrating \ | grep -E "albumrating=$rating|albumrating=$(echo $(( $rating+1 )))|albumrating=$(echo $(( $rating+2 )))|albumrating=$(echo $(( $rating+3 )))|albumrating=$(echo $(( $rating+4 )))|albumrating=$(echo $(( $rating+5 )))|albumrating=$(echo $(( $rating+6 )))")" \ | $sed 's/\/\CD.*//g' \ | $shuf -n1)" mpc clear; mpc add "$album"; mpc play fi } # load random album. Make sure to make each sub item random. this way each # artist has equal chances of being played, no matter how many albums it has. playRandomAlbum () { mpc clear > /dev/null artist="$(mpc list "albumartist" | $shuf -n 1)" album="$(mpc list album "albumartist" "$artist" | $shuf -n 1)" mpc findadd album "$album" "albumartist" "$artist"; mpc play > /dev/null } # same for tracks, no artist should be preferred because it has more tracks. playRandomTracks () { mpc clear > /dev/null artist="$(mpc list "$random_artist" | $shuf -n 1)" album="$(mpc list album "$random_artist" "$artist" | $shuf -n 1)" title="$(mpc list title album "$album" "$random_artist" "$artist" | $shuf -n 1)" mpc findadd album "$album" "$random_artist" "$artist" title "$title"; mpc play > /dev/null n=0; while (( n++ < $value -1 )); do artist="$(mpc list "$random_artist" | $shuf -n 1)" album="$(mpc list album "$random_artist" "$artist" | $shuf -n 1)" title="$(mpc list title album "$album" "$random_artist" "$artist" | $shuf -n 1)" mpc findadd album "$album" "$random_artist" "$artist" title "$title" done mpc play > /dev/null exit } exitAfterAdd () { if [[ $exit_after_add == "yes" ]]; then exit elif [[ $exit_after_add == "no" ]]; then : fi } addAlbum() { displaystyle () { mode="$1" help_text="$(echo -e "${add}: Add - ${insert}: Insert - ${replace}: Replace (Default) - ${savefav}: Save\n${rate}: Rate - ${addplay}: Add + Play - ${insertplay}: Insert + Play" | column -s '-' -t | perl -pe "s/ - /\|\<\/span\>/g")" line1=$(echo "${help_text}" | head -1) line2=$(echo "${help_text}" | tail -1) HELP="${line1} ${line2}" if [[ $1 == "latest" ]]; then album_list="latest.cache" elif [[ $1 == "alphabet" ]]; then album_list="albums.cache" fi ALBUM_TEMP="$(dmenu_t \ -sep '\n' \ -kb-custom-1 "${add}" \ -kb-custom-2 "${insert}" \ -kb-custom-3 "${replace}" \ -kb-custom-8 "${rate}" \ -kb-custom-4 "${addplay}" \ -kb-custom-5 "${insertplay}" \ -kb-custom-6 ${tracklist} \ -kb-custom-7 ${queue} \ -kb-custom-9 ${prev} \ -kb-custom-10 ${toggle} \ -kb-custom-11 ${stop} \ -kb-custom-12 ${next} \ -kb-custom-13 ${seek} \ -kb-custom-14 ${savefav} \ -kb-custom-15 ${nextalbum} \ -kb-custom-16 ${prevalbum} \ -dmenu -filter "$filter" \ -select "$album_entry" \ -mesg "${HELP}" \ -format "f¬s" \ -input "$HOME/.config/clerk/${album_list}" \ -p "Choose Album > ")" } returnto () { if [[ $mode == "latest" ]]; then addAlbum latest elif [[ $mode == "alphabet" ]]; then addAlbum alphabet fi } mode=$1 displaystyle $mode val=$? ALBUM_ORIG="${ALBUM_TEMP#*¬}" firstline=$(echo "$ALBUM_ORIG" | sed 's/.*¬//g' | tail -1) unset filter export filter_temp="${ALBUM_TEMP%¬*}" ALBUM=$(echo "${ALBUM_ORIG}" | perl -pe "s/ +/\t/g" | sed 's/.*¬//g') export filter=$(echo "$filter_temp" | head -1 | sed 's/¬.*//g') if [[ -z "$ALBUM" ]]; then exit else artist=$(echo -en "$ALBUM" \ | gawk -F '\t' '{ print $1 }' \ | sed -e 's/[[:space:]]*$//') album=$(echo "$ALBUM" \ | gawk -F "\t" '{print $3}') date=$(echo "$ALBUM" \ | gawk -F "\t" '{print $2}' \ | gawk '{print substr($0, 2, length($0) - 2)}') if [[ $val -eq 11 ]]; then echo "$ALBUM" | uniq | while read line; do xALBUM="$line" artist=$(echo -en "$xALBUM" \ | gawk -F '\t' '{ print $1 }' \ | sed -e 's/[[:space:]]*$//') album=$(echo "$xALBUM" \ | gawk -F "\t" '{print $3}') date=$(echo "$xALBUM" \ | gawk -F "\t" '{print $2}' \ | gawk '{print substr($0, 2, length($0) - 2)}') disc=$(mpc find -f '%disc%' date "$date" album "$album" albumartist "$artist" | uniq) if [[ $(echo "$disc" | wc -l) -gt 1 ]]; then discmenu=$(echo -e "All\n$disc" | rofi -dmenu -p "Choose Disc > ") if [[ $discmenu == "" ]]; then exit elif [[ $discmenu == "All" ]]; then echo -e "All\n$disc" | tail -n +2 | while read discline; do mpc search date "$date" album "$album" albumartist "$artist" disc "$discline" | mpc insert done else mpc search date "$date" album "$album" albumartist "$artist" disc "$discmenu" | mpc insert fi else mpc search date "$date" album "$album" albumartist "$artist" | mpc insert fi done album_entry="$firstline" exitAfterAdd returnto elif [[ $val -eq 12 ]]; then mpc clear; echo "$ALBUM" | uniq | while read line; do xALBUM="$line" artist=$(echo -en "$xALBUM" \ | gawk -F '\t' '{ print $1 }' \ | sed -e 's/[[:space:]]*$//') album=$(echo "$xALBUM" \ | gawk -F "\t" '{print $3}') date=$(echo "$xALBUM" \ | gawk -F "\t" '{print $2}' \ | gawk '{print substr($0, 2, length($0) - 2)}') disc=$(mpc find -f '%disc%' date "$date" album "$album" albumartist "$artist" | uniq) if [[ $(echo "$disc" | wc -l) -gt 1 ]]; then discmenu=$(echo -e "All\n$disc" | rofi -dmenu -p "Choose Disc > ") if [[ $discmenu == "" ]]; then exit elif [[ $discmenu == "All" ]]; then mpc clear echo -e "All\n$disc" | tail -n +2 | while read discline; do mpc findadd date "$date" album "$album" albumartist "$artist" disc "$discline" done else mpc clear mpc findadd date "$date" album "$album" albumartist "$artist" disc "$discmenu" fi else mpc findadd date "$date" album "$album" albumartist "$artist" fi done mpc play album_entry="$firstline" exitAfterAdd returnto elif [[ $val -eq 0 ]]; then if [[ "$ALBUM" == "< Return" ]]; then unset artist browseLibPrompt elif [[ "$ALBUM" == "" ]]; then returnto $mode else echo "$ALBUM" | uniq | while read line; do xALBUM="$line" # echo "$ALBUM" | while read line; do artist=$(echo -en "$xALBUM" \ | gawk -F '\t' '{ print $1 }' \ | sed -e 's/[[:space:]]*$//') album=$(echo "$xALBUM" \ | gawk -F "\t" '{print $3}') date=$(echo "$xALBUM" \ | gawk -F "\t" '{print $2}' \ | gawk '{print substr($0, 2, length($0) - 2)}') disc=$(mpc find -f '%disc%' date "$date" album "$album" albumartist "$artist" | uniq) if [[ $(echo "$disc" | wc -l) -gt 1 ]]; then discmenu=$(echo -e "All\n$disc" | rofi -dmenu -p "Choose Disc > ") if [[ $discmenu == "" ]]; then exit elif [[ $discmenu == "All" ]]; then mpc clear echo -e "All\n$disc" | tail -n +2 | while read discline; do mpc findadd date "$date" album "$album" albumartist "$artist" disc "$discline" done else mpc clear mpc findadd date "$date" album "$album" albumartist "$artist" disc "$discmenu" fi else mpc clear mpc findadd date "$date" album "$album" albumartist "$artist" fi done mpc play album_entry="$firstline" exitAfterAdd returnto fi elif [[ $val -eq 10 ]]; then echo "$ALBUM" | uniq | while read line; do xALBUM="$line" # echo "$ALBUM" | while read line; do artist=$(echo -en "$xALBUM" \ | gawk -F '\t' '{ print $1 }' \ | sed -e 's/[[:space:]]*$//') album=$(echo "$xALBUM" \ | gawk -F "\t" '{print $3}') date=$(echo "$xALBUM" \ | gawk -F "\t" '{print $2}' \ | gawk '{print substr($0, 2, length($0) - 2)}') disc=$(mpc find -f '%disc%' date "$date" album "$album" albumartist "$artist" | uniq) if [[ $(echo "$disc" | wc -l) -gt 1 ]]; then discmenu=$(echo -e "All\n$disc" | rofi -dmenu -p "Choose Disc > ") if [[ $discmenu == "" ]]; then exit elif [[ $discmenu == "All" ]]; then echo -e "All\n$disc" | tail -n +2 | while read discline; do mpc findadd date "$date" album "$album" albumartist "$artist" disc "$discline" done else mpc findadd date "$date" album "$album" albumartist "$artist" disc "$discmenu" fi else mpc findadd date "$date" album "$album" albumartist "$artist" fi done album_entry="$firstline" exitAfterAdd returnto elif [[ $val -eq 15 ]]; then album_entry="${firstline}" addTrackTags returnto elif [[ $val -eq 16 ]]; then album_entry="${firstline}" dplayQueue elif [[ $val -eq 13 ]]; then album_entry="${firstline}" mpc findadd date "$date" album "$album" albumartist "$artist" mpc searchplay "${album}" elif [[ $val -eq 18 ]]; then mpc prev album_entry="${firstline}" returnto elif [[ $val -eq 19 ]]; then mpc toggle album_entry="${firstline}" returnto elif [[ $val -eq 20 ]]; then mpc stop album_entry="${firstline}" returnto elif [[ $val -eq 21 ]]; then mpc next album_entry="${firstline}" returnto elif [[ $val -eq 22 ]]; then album_entry="${firstline}" seekMenu addAlbum $1 elif [[ $val -eq 23 ]]; then album_entry="${firstline}" ALBUM="$ALBUM" saveAlbumToPlaylist selection elif [[ $val -eq 24 ]]; then skipAlbum next unset IFS album_entry="${firstline}" returnto elif [[ $val -eq 25 ]]; then skipAlbum prev unset IFS album_entry="${firstline}" returnto elif [[ $val -eq 17 ]]; then if [[ -n $(mpc find -f '%disc%' albumartist "${artist}" album "${album}" date "${date}") ]]; then disc=$(mpc find -f '%disc%' albumartist "${artist}" album "${album}" date "${date}" | head -1) else disc="" fi if [[ -n $(mpc find track "1" albumartist "${artist}" album "${album}" date "${date}") ]]; then track="1" else track="01" fi disc=${disc} track=${track} rateartist="${artist}" ratealbum="${album}" ratedate="${date}" rateAlbum album_entry="$firstline" elif [[ $val -eq 14 ]]; then mpc clear; mpc findadd date "$date" album "$album" albumartist "$artist"; mpc searchplay "${album}" album_entry="$firstline" elif [[ $val -eq 1 ]]; then exit fi returnto fi } addTrackTags() { help_text=$(echo -e "${add}: Add (Default) - ${insert}: Insert - ${replace}: Replace \ \n${rate}: Rate - ${addplay}: Add + Play - ${insertplay}: Insert + Play" \ | column -s '-' -t | perl -pe "s/ - /\|\<\/span\>/g") # -o "|" -t) line1=$(echo "${help_text}" | head -1) line2=$(echo "${help_text}" | tail -1) HELP="${line1} ${line2}" TRACK_TEMP="$(dmenu_t \ -kb-custom-1 "${add}" \ -kb-custom-2 "${insert}" \ -kb-custom-3 "${replace}" \ -kb-custom-8 "${rate}" \ -kb-custom-4 "${addplay}" \ -kb-custom-5 "${insertplay}" \ -kb-custom-6 ${albumlist} \ -kb-custom-7 ${queue} \ -kb-custom-9 ${prev} \ -kb-custom-10 ${toggle} \ -kb-custom-11 ${stop} \ -kb-custom-12 ${next} \ -kb-custom-13 ${seek} \ -kb-custom-14 ${nextalbum} \ -kb-custom-15 ${prevalbum} \ -dmenu -filter "$filter" \ -select "$entry" \ -format "f¬s" \ -mesg "${HELP}" \ -input "$HOME/.config/clerk/tracks.cache" \ -p "Choose Track > ")" val=$? TRACK_ORIG="${TRACK_TEMP#*¬}" firstline=$(echo "${TRACK_ORIG}" | sed 's/.*¬//g' | tail -1) unset filter export filter_temp="${TRACK_TEMP%¬*}" TRACK="$(echo "${TRACK_ORIG}" | perl -pe "s/ +/\t/g" | sed 's/.*¬//g')" export filter=$(echo "$filter_temp" | head -1 | sed 's/¬.*//g') if [[ -z "$TRACK" ]]; then exit else filename=$(echo "$TRACK" | gawk -F "\t" '{print $6}') if [[ $val -eq 11 ]]; then filename=$(echo "$TRACK" | gawk -F "\t" '{print $6}') echo "$filename" | uniq | while read line; do mpc insert "${line}" done entry="$firstline" exitAfterAdd elif [[ $val -eq 12 ]]; then filename=$(echo "$TRACK" | gawk -F "\t" '{print $6}') mpc clear; echo "$filename" | uniq | while read line; do mpc add "${line}" done mpc play entry="$firstline" exitAfterAdd elif [[ $val -eq 10 ]]; then filename=$(echo "$TRACK" | gawk -F "\t" '{print $6}') echo "$filename" | uniq | while read line; do mpc add "${line}" done entry="$firstline" exitAfterAdd elif [[ $val -eq 0 ]]; then if [[ "$TRACK" == "< Return" ]]; then browseLibPrompt elif [[ "$TRACK" == "---" ]]; then addTrackTags else filename=$(echo "$TRACK" | gawk -F "\t" '{print $6}') echo "$filename" | uniq | while read line; do mpc add "${line}" done entry="$firstline" exitAfterAdd fi elif [[ $val -eq 13 ]]; then title=$(echo "$TRACK" | gawk -F "\t" '{print $2}' | head -1) filename=$(echo "$TRACK" | gawk -F "\t" '{print $6}') echo "$filename" | uniq | while read line; do mpc add "${line}" done mpc searchplay "${title}" entry="$firstline" exitAfterAdd elif [[ $val -eq 15 ]]; then addAlbum alphabet elif [[ $val -eq 16 ]]; then dplayQueue elif [[ $val -eq 14 ]]; then title=$(echo "$TRACK" | gawk -F "\t" '{print $2}' | head -1) filename=$(echo "$TRACK" | gawk -F "\t" '{print $6}') echo "$filename" | uniq | while read line; do mpc insert "${line}" done mpc searchplay "${title}" entry="$firstline" exitAfterAdd elif [[ $val -eq 18 ]]; then mpc prev elif [[ $val -eq 19 ]]; then mpc toggle entry="${firstline}" elif [[ $val -eq 20 ]]; then mpc stop entry="${firstline}" elif [[ $val -eq 21 ]]; then mpc next entry="${firstline}" elif [[ $val -eq 22 ]]; then entry="${firstline}" seekMenu addTrackTags elif [[ $val -eq 23 ]]; then skipAlbum next unset IFS entry="${firstline}" elif [[ $val -eq 24 ]]; then skipAlbum prev unset IFS entry"${firstline}" elif [[ $val -eq 17 ]]; then info=$(mpc search --format '%artist%\t%album%\t%date%\t%track%\t%title%' filename "${filename}") artist="$(echo "$info" \ | gawk -F '\t' '{ print $1 }')" album="$(echo "$info" \ | gawk -F '\t' '{ print $2 }')" date="$(echo "$info" \ | gawk -F '\t' '{ print $3 }')" track="$(echo "$info" \ | gawk -F '\t' '{ print $4 }')" title="$(echo "$info" \ | gawk -F '\t' '{ print $5 }')" echo "${artist} ${album} ${date} ${track} ${title}" rateartist="${artist}" ratealbum="${album}" ratetrack="${track}" ratetitle="${title}" rateTrack entry="$firstline" elif [[ $val -eq 1 ]]; then exit fi addTrackTags fi } browseLibPrompt() { menu="$((echo -e "< Return\n---\n1 [ Choose Albums ]>\n2 [ Choose Track ]>\n3 [ Browse Latest Additions ]>\n---\n4 [ Play Random Album ]\n5 [ Play Random Tracks ]\n---\n6 [ Update Album/Track Cache ]") \ | dmenu_t \ -auto-select \ -kb-custom-1 ${albumlist} \ -kb-custom-2 ${tracklist} \ -kb-custom-3 ${queue} \ -p "Library Menu > ")" val=$? if [[ $val -eq 1 ]]; then exit elif [[ $val -eq 10 ]]; then addAlbum alphabet elif [[ $val -eq 11 ]]; then addTrackTags elif [[ $val -eq 12 ]]; then dplayQueue elif [[ $val -eq 13 ]]; then nowPlaying fi if [[ "${menu}" == "1 "* ]]; then addAlbum alphabet elif [[ "${menu}" == "2 "* ]]; then addTrackTags elif [[ "${menu}" == "6 "* ]]; then updateCache; browseLibPrompt elif [[ "${menu}" == "< "* ]]; then dplayPrompt elif [[ "${menu}" == "3 "* ]]; then addAlbum latest elif [[ "${menu}" == "4 "* ]]; then playRandomAlbum elif [[ "${menu}" == "5 "* ]]; then playRandomTracks fi } saveAlbumToPlaylist() { if [[ $1 == "selection" ]]; then TRACK="${TRACK}" else TRACK="$((echo -e "< Return\n---"; cat $HOME/.config/clerk/albums.cache) | dmenu_t -dmenu -p "Save Album to Playlist > ")" fi val=$? if [[ $val -eq 1 ]]; then exit fi if [[ "$TRACK" == "< Return" ]]; then dplayPrompt elif [[ "$TRACK" == "---" ]]; then saveAlbumToPlaylist else artist=$(echo -en "$TRACK" \ | gawk -F '\t' '{ print $1 }' \ | sed -e 's/[[:space:]]*$//') group2=$(echo -en "$TRACK" \ | gawk -F '\t' '{ print $2 "\t" $3}' \ | sed -e 's/[[:space:]]*$//') album=$(echo -en "$group2" \ | gawk -F "\t" '{print $2}') date=$(echo -en "$group2" \ | gawk -F "\t" '{print $1}' \ | gawk '{print substr($0, 2, length($0) - 2)}') clear echo "${artist} ${album} ${date}" mpc search date "$date" album "$album" albumartist "$artist" | clerk_helper saveto fi saveAlbumToPlaylist } saveLatestToPlaylist() { declare -i seen=0 while read TRACK do seen=1 if [[ "$TRACK" == "0 Return to Main Menu" ]] then dplayPrompt else artist=$(echo -en "$TRACK" \ | gawk -F '\t' '{ print $1 }' \ | sed -e 's/[[:space:]]*$//') group2=$(echo -en "$TRACK" \ | gawk -F '\t' '{ print $2 }' \ | sed -e 's/[[:space:]]*$//') album=$(echo "$group2" \ | gawk -F " — " '{print $2}') date=$(echo "$group2" \ | gawk -F " — " '{print $1}' \ | gawk '{print substr($0, 2, length($0) - 2)}') mpc search date "$date" album "$album" albumartist "$artist" | clerk_helper saveto fi done < <(echo -e "0 Return to Main Menu\n---\n$(cat $HOME/.config/clerk/latest.cache)" | dmenu_t -dmenu -p "Save Album to Playlist > ") if [[ $seen = 0 ]] then exit fi } saveTrackToPlaylist() { TRACK_TEMP="$((echo -e "0 Return to Main Menu\n---"; cat $HOME/.config/clerk/tracks.cache) | dmenu_t -filter "$filter" -select "$entry" -format "f¬s" -dmenu -p "Save Track to Playlist > ")" TRACK="${TRACK_TEMP#*¬}" unset filter export filter="$(echo ${TRACK_TEMP} | gawk -F '¬' '{ print $1 }')" if [[ "$TRACK" == "0 Return to Main Menu" ]] then dplayPrompt elif [[ -z "$TRACK" ]]; then exit else filename=$(echo "$TRACK" | gawk -F "\t" '{print $3}') info=$(mpc search --format '%artist%\t%album%\t%date%\t%track%\t%title%' filename "${filename}") artist="$(echo "$info" \ | gawk -F '\t' '{ print $1 }')" album="$(echo "$info" \ | gawk -F '\t' '{ print $2 }')" date="$(echo "$info" \ | gawk -F '\t' '{ print $3 }')" track="$(echo "$info" \ | gawk -F '\t' '{ print $4 }')" title="$(echo "$info" \ | gawk -F '\t' '{ print $5 }')" mpc search track "$track" album "$album" title "$title" albumartist "$artist" | clerk_helper saveto entry="$TRACK" saveTrackToPlaylist fi } getAlbumsFromPlaylist () { current=$(mpc save temp) pl="clerk" mpc clear mpc load "${pl}" list=$(mpc playlist -f '%artist% - %album% - %date%' | sort -u | rofi -dmenu -mesg "${add}: Add, ${insert}: Insert, ${replace}: Replace") val=$? mpc clear if [[ $val == 12 ]]; then mpc searchadd artist "$(echo $list | gawk -F ' - ' '{print $1}')" album "$(echo $list | gawk -F ' - ' '{print $2}')" date "$(echo $list | gawk -F ' - ' '{print $3}')" mpc play elif [[ $val == 11 ]]; then mpc load temp mpc search artist "$(echo $list | gawk -F ' - ' '{print $1}')" album "$(echo $list | gawk -F ' - ' '{print $2}')" date "$(echo $list | gawk -F ' - ' '{print $3}')" | mpc insert elif [[ $val == 10 ]]; then mpc load temp mpc searchadd artist "$(echo $list | gawk -F ' - ' '{print $1}')" album "$(echo $list | gawk -F ' - ' '{print $2}')" date "$(echo $list | gawk -F ' - ' '{print $3}')" fi mpc rm temp } ################################################################################ while :; do case $1 in --nextalbum) skipAlbum next exit ;; --prevalbum) skipAlbum prev exit ;; --add) if [[ ! $2 ]]; then echo "Missing argument for --add" echo "Possible values: track, album, latest" elif [[ $2 == track ]]; then addTrackTags elif [[ $2 == album ]]; then addAlbum alphabet elif [[ $2 == latest ]]; then addAlbum latest fi break ;; --rate) if [[ ! $2 ]]; then echo "Missing arguemtn for --rate" echo "Possible values: track, album, instant" echo "Launching rating menu" ratingPrompt elif [[ $2 == track ]]; then rateTrack elif [[ $2 == album ]]; then rateAlbum elif [[ $2 == instant ]]; then if [[ ! $3 ]]; then echo "Missing argument for --rate instant" echo "Please define rating between 1-10" else instantRateTrack $3 fi elif [[ $2 == load ]]; then mpc clear && mpc sticker "" find rating | grep -E "rating=6|rating=7|rating=8|rating=9|rating=10" | gawk -F ':' '{print $1}' | $shuf -n $value | mpc add && mpc play fi break ;; --random) if [[ ! $2 ]]; then echo "Missing argument for --random" echo "Possible values: track, album" elif [[ $2 == track ]]; then playRandomTracks elif [[ $2 == album ]]; then playRandomAlbum fi break ;; --current) currentTag break ;; --browse) if [[ ! $2 ]]; then echo "Missing argument for --browse" echo "Possible values: artist, date, genre, folder, system" elif [[ $2 == artist ]]; then browseArtist elif [[ $2 == albumartist ]]; then browseAlbumArtist elif [[ $2 == date ]]; then browseDate elif [[ $2 == genre ]]; then browseGenre elif [[ $2 == system ]]; then browseFilesystem elif [[ $2 == folder ]]; then browseFolders fi break ;; --backup) if [[ ! $2 ]]; then echo "Missing argument for --backup" echo "Possible values: track, album" elif [[ $2 == track ]]; then backupTrackRatings elif [[ $2 == album ]]; then backupAlbumRatings fi break ;; --restore) if [[ ! $2 ]]; then echo "Missing argument for --restore" echo "Possible values: track, album" elif [[ $2 == track ]]; then restoreTrackRatings elif [[ $2 == album ]]; then restoreAlbumRatings fi break ;; --queue) if [[ ! $2 ]]; then echo "Missing argument for --queue" echo "Possible values: show, delete, suspend, resume" elif [[ $2 == show ]]; then dplayQueue elif [[ $2 == delete ]]; then dplayQueueDelete elif [[ $2 == suspend ]]; then suspendPlaylist elif [[ $2 == resume ]]; then resumePlaylist fi break ;; --rss) loadRSS break ;; --playlist) if [[ $2 == savealbum ]]; then saveAlbumToPlaylist elif [[ $2 == load ]]; then dplayQueueLoad elif [[ $2 == savelast ]]; then saveLatestToPlaylist elif [[ $2 == savetrack ]]; then saveTrackToPlaylist elif [[ $2 == loadalbum ]]; then getAlbumsFromPlaylist fi break ;; --lastfm) if [[ ! $2 ]]; then echo "Missing argument for --lastfm" echo "Possible values: toggle, check, love" elif [[ $2 == toggle ]]; then lastFM elif [[ $2 == check ]]; then lastFMCheck elif [[ $2 == love ]]; then if [[ scrobbler=mpdscribble ]]; then lastfm-mpd-cli love > /dev/null && notify-send "MPD" "Loved $(mpc current -f '%title%') on LastFM" elif [[ scrobbler=mpdas ]]; then mpc sendmessage mpdas love fi fi break ;; --update) forceupdate=true updateCache ;; --help|-h) echo "---" echo "clerk: rofi based MPD Interface" echo "Copyright © 2013 - 2015 Rasmus Steinke" echo "---" echo "General" echo " --help, -h this help message" echo " --current show currently playing track" echo " --update update album/track caches" echo "" echo "Library" echo " --add adds selection at the end of the queue" echo " --random play random track or album" echo "" echo "Playlist" echo " --queue manage current queue" echo " --playlist save selection to playlist \"clerk\"" echo " --playlist load playlist" echo " --rss load podcast" echo " (podcast should be placed in ~/.config/clerk/podcasts" echo " with format NAME \ URL)" echo "" echo "Ratings" echo " --rate rate albums or tracks" echo " "load" adds random rated tracks to queue" echo "" echo " --backup backup ratings from mpd sticker database to json file." echo " --restore restore ratings back to mpd sticker database" echo "" echo "LastFM" echo " --lastfm toggle or check last.fm status, love current track" break ;; *) dplayPrompt ;; esac shift done