Files
2026-10-29 09:39:54 -04:00

58 lines
1.9 KiB
Bash
Executable File

#!/usr/bin/env bash
# Desktop notification with cover art on song change. Run by ncmpcpp's
# execute_on_song_change, so it only fires while ncmpcpp is open.
#
# mopidy: Mopidy-MPD has no albumart command, so the cover comes from the
# Subsonic server behind Mopidy-Subidy. url and username are read from
# mopidy.conf, the password from the untracked secrets.conf.
# Usage: song-notify [subidy:song:<id>] (defaults to the current song)
set -u
conf=~/.config/mopidy/mopidy.conf
secrets=~/.config/mopidy/secrets.conf
cache=${XDG_CACHE_HOME:-$HOME/.cache}/ncmpcpp/covers
fmt='%file%\t%artist%\t%title%\t%album%'
if [ $# -gt 0 ]; then
line=$(mpc -f "$fmt" playlist 2>/dev/null |
awk -F'\t' -v u="$1" '$1 == u { print; exit }')
else
line=$(mpc -f "$fmt" current 2>/dev/null)
fi
IFS=$'\t' read -r uri artist title album <<<"$line"
[ -n "$uri" ] || exit 0
# Value of key in [subidy] of an ini file.
ini() {
awk -F' *= *' -v k="$2" '
/^\[/ { s = ($0 == "[subidy]") }
s && $1 == k { print $2; exit }' "$1"
}
cover=
id=${uri#subidy:song:}
if [ "$id" != "$uri" ] && [ -r "$secrets" ]; then
url=$(ini "$conf" url)
user=$(ini "$conf" username)
pass=$(ini "$secrets" password)
salt=$(head -c 8 /dev/urandom | od -An -tx1 | tr -d ' \n')
token=$(printf '%s%s' "$pass" "$salt" | md5sum | cut -d' ' -f1)
auth="u=$user&t=$token&s=$salt&v=1.16.1&c=ncmpcpp"
art=$(curl -fsS --max-time 5 "$url/rest/getSong.view?$auth&f=json&id=$id" |
jq -r '."subsonic-response".song.coverArt // empty')
if [ -n "$art" ]; then
cover=$cache/${art////_}
if [ ! -s "$cover" ]; then
mkdir -p "$cache"
curl -fsS --max-time 10 -o "$cover" \
"$url/rest/getCoverArt.view?$auth&id=$art&size=256" || cover=
fi
fi
fi
notify-send -a ncmpcpp ${cover:+-i "$cover"} \
-h string:x-canonical-private-synchronous:ncmpcpp \
"${title:-$uri}" "${artist:-}${album:+ — $album}"