]> git.draconx.ca Git - mpdhacks.git/blobdiff - mpdthumb.sh
mpdthumb: Fix compatibility with newer MPD versions.
[mpdhacks.git] / mpdthumb.sh
index f41c5f6f18cf95b19d85e8608d1c6b94d5b55553..4ff4249042917920cdc9940b55086338e2500e7e 100755 (executable)
@@ -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 <nbowler@draconx.ca>.
 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