+#!/bin/sh
+#
+# Copyright © 2019 Nick Bowler
+#
+# Generate thumbnails for cover art retrieved from MPD.
+#
+# License GPLv3+: GNU General Public License version 3 or any later version.
+# This is free software: you are free to change and redistribute it.
+# There is NO WARRANTY, to the extent permitted by law.
+
+: "${XDG_CACHE_HOME=$HOME/.cache}"
+: "${THUMBNAILDIR=$XDG_CACHE_HOME/mpdthumb}"
+
+# Try to find mpdexec...
+case $0 in
+/*) self=$0 ;;
+*/*) self=$PWD/${0#./} ;;
+*) self=`command -v $0` ;;
+esac
+owndir=${self%/*}
+
+if command -v "$owndir/mpdexec.pl" >/dev/null; then
+ : "${MPDEXEC=$owndir/mpdexec.pl}"
+elif command -v mpdexec.pl >/dev/null; then
+ : "${MPDEXEC=mpdexec.pl}"
+else
+ : "${MPDEXEC=mpdexec}"
+fi
+
+if command -v gm >/dev/null; then
+ : "${CONVERT=gm convert}"
+else
+ : "${CONVERT=convert}"
+fi
+
+size=x128
+
+lastarg=
+dashdash=
+for arg; do
+ if test ${lastarg:+y}; then
+ arg=$lastarg=$arg
+ lastarg=
+ fi
+
+ case $dashdash$arg in
+ --size=*) size=${arg#--size=} ;;
+ --small) size=56 ;;
+ --size) lastarg=$arg ;;
+ --) dashdash=: ;;
+ -*) printf '%s: unrecognized argument: %s\n' "$0" "$arg" 1>&2; exit 1 ;;
+ *) set x "$@" "$arg"; shift
+ esac
+
+ shift
+done
+
+w=${size%x*} h=${size#*x}
+if expr "$w$h" : '[0-9][0-9]*$' >/dev/null; then :; else
+ printf '%s: invalid --size setting: %s\n' "$0" "$size" 1>&2
+ exit 1
+fi
+
+case $# in 0)
+ printf 'usage: %s [options] file [file ...]\n' "$0" 1>&2
+ exit 1
+esac
+
+tmp=`mktemp`
+exec 3>"$tmp" 4<"$tmp"
+rm -f "$tmp"
+
+tmp=`mktemp`
+exec 5>"$tmp" 6<"$tmp"
+rm -f "$tmp"
+
+for arg; do
+ arg=${arg%/*}/
+ shift; set x "$@" "$arg"; shift
+
+ printf '%s\n' "$arg" | sed '/[ \\"]/ {
+ s/[\\"]/\\&/g
+ s/.*/"&"/
+ }
+ s/.*/albumart & 2147483647/' >&3;
+done
+
+<&4 $MPDEXEC --ignore-errors >&5 2>&1 || exit
+while read a b <&6; do
+ case $a in
+ size:) :;;
+ ACK) echo; shift || exit; continue ;;
+ *) continue ;;
+ esac
+
+ # We combine the filename and the size to compute the cache key and
+ # hope this suffices to detect stale entries. Unfortunately MPD does
+ # not currently give us the modified date which would be more useful...
+ file=$1; shift || exit
+ cache_id=`printf 'MPD:%s:%s' "$file" "$b" | md5sum`
+ cache_id=${cache_id:+${cache_id%% *}_$size.png}
+
+ if test ! -f "$THUMBNAILDIR/$cache_id"; then
+ if test ! -f "$THUMBNAILDIR/CACHEDIR.TAG"; then
+ mkdir -p "$THUMBNAILDIR"
+ { cat >"$THUMBNAILDIR/CACHEDIR.TAG~" || exit; } <<'EOF'
+Signature: 8a477f597d28d172789f06886806bc55
+EOF
+ mv -f "$THUMBNAILDIR/CACHEDIR.TAG~" "$THUMBNAILDIR/CACHEDIR.TAG"
+ fi
+
+ # Not cached, retrieve the entire image
+ $MPDEXEC --binary --download albumart "$file" >&3 || exit
+ <&4 $CONVERT -scale "$size" - "$THUMBNAILDIR/tmp.$cache_id" ||
+ { rc=$? rm -f "$THUMBNAILDIR/tmp.$cache_id"; exit $rc; }
+ mv -f "$THUMBNAILDIR/tmp.$cache_id" "$THUMBNAILDIR/$cache_id"
+ fi
+
+ printf '%s\n' "$THUMBNAILDIR/$cache_id"
+done