From: Nick Bowler Date: Thu, 22 Jul 2021 03:46:50 +0000 (-0400) Subject: mpdthumb: Fix compatibility with newer MPD versions. X-Git-Url: http://git.draconx.ca/gitweb/mpdhacks.git/commitdiff_plain/b6a0cfc0340af1a0a712dd7dd67fb59418cdcb15 mpdthumb: Fix compatibility with newer MPD versions. It seems that recent MPD servers have made backward-incompatible changes to the albumart command. Specifically, the cache check currently sends an absurdly huge offset to avoid downloading a pointless and unnecessary multi-KB blob for every image it is querying. While this worked well with older servers, new servers now reject such commands with an error instead of returning useful information. Fortunately, newer servers also implement the "binarylimit" command to reduce the amount of data transferred. For some reason we can't ask the server to send less than 64 bytes but whatever, it is probably good enough. So work around the problem by testing whether the server supports binarylimit, and use the new method if it does. Otherwise use the old method. Command-line options are provided to force the behaviour one way or the other (which avoids the extra round trip to the server). --- diff --git a/mpdthumb.sh b/mpdthumb.sh index f41c5f6..4ff4249 100755 --- a/mpdthumb.sh +++ b/mpdthumb.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright © 2019-2020 Nick Bowler +# Copyright © 2019-2021 Nick Bowler # # Generate thumbnails for cover art retrieved from MPD. # @@ -36,8 +36,8 @@ fi print_version () { cat <<'EOF' -mpdthumb.sh 0.8 -Copyright © 2020 Nick Bowler +mpdthumb.sh 0.9 +Copyright © 2021 Nick Bowler 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. @@ -64,18 +64,30 @@ the same order of the associated files specified on the command line. If a given file has no cover art, then a blank line is printed. Options: - --size=[W][xH] Specify the dimensions (in pixels) of a bounding rectangle - into which the image will be scaled to fit. One (but not - both) of the dimensions may be omitted to indicate no limit - in that direction. The default size is x128. - --small Equivalent to --size=56 - --version Print a version message and then exit. - --help Print this message and then exit. + --size=[W][xH] Specify the dimensions (in pixels) of a bounding + rectangle into which the image will be scaled to fit. + One (but not both) of the dimensions may be omitted + to indicate no limit in that direction. The default + size is x128. + --small Equivalent to --size=56 + --binarylimit[=ARG] + If ARG is omitted or 'yes', force the use of the + binarylimit command to reduce the amount of data + transferred in the hot cache case. If ARG is 'no', + then the old "large offset" method is used which is + incompatible with newer MPD servers. The default is + 'auto', which queries the server to determine the + appropriate method. + --no-binarylimit Equivalent to --binarylimit=no + --version Print a version message and then exit. + --help Print this message and then exit. Report bugs to . EOF } +opt_binarylimit=auto + size=x128 lastarg= dashdash= @@ -86,6 +98,9 @@ for arg; do fi case $dashdash$arg in + --binarylimit=*) opt_binarylimit=${arg#--*=} ;; + --no-binarylimit) opt_binarylimit=no ;; + --binarylimit) opt_binarylimit=yes ;; --size=*) size=${arg#--size=} ;; --small) size=56 ;; --size) lastarg=$arg ;; @@ -118,6 +133,31 @@ tmp=`mktemp` exec 5>"$tmp" 6<"$tmp" rm -f "$tmp" +# Test for binarylimit command in MPD server. We want to minimize data +# transfer in order to make cache hits as fast as possible. +# +# On older servers we can set a ridiculously large offset which causes the +# server to send no data, but this is rejected by new servers. On new servers +# we can limit the data transferred explicitly, but not less than 64 bytes +# for some reason (probably not a big problem). + +use_binarylimit=true +case $opt_binarylimit in +auto) $MPDEXEC binarylimit 64 2>/dev/null || use_binarylimit=false ;; +no) use_binarylimit=false ;; +yes) :;; +*) + print_usage 'invalid --binarylimit argument; must be yes, no or auto' 1>&2 + exit 1 +esac + +if $use_binarylimit; then + printf 'binarylimit 64\n' >&3 + binarylimit_offset=0 +else + binarylimit_offset=2147483647 +fi + for arg; do arg=${arg%/*}/ shift; set x "$@" "$arg"; shift @@ -126,14 +166,19 @@ for arg; do s/[\\"]/\\&/g s/.*/"&"/ } - s/.*/albumart & 2147483647/' >&3; + s/.*/albumart & '"$binarylimit_offset"'/' >&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 ;; + ACK) + case $b in + *binarylimit*) printf '%s: %s\n' "$argv0" "$a $b" 1>&2; exit 1 ;; + esac + + echo; shift || exit; continue ;; *) continue ;; esac