]> git.draconx.ca Git - mpdhacks.git/commitdiff
mpdmenu: Factor out thumbnail generation.
authorNick Bowler <nbowler@draconx.ca>
Fri, 28 Jun 2019 00:01:41 +0000 (20:01 -0400)
committerNick Bowler <nbowler@draconx.ca>
Sat, 29 Jun 2019 16:05:59 +0000 (12:05 -0400)
Prep work for making use of MPD albumart, move all calls to the
thumbnailer into a single function, and adapt the menus to call
the function once to generate an entire list of cover art.

Drop the use of the --image option in the thumbnailer by poking at
the cover art directly, since this will no longer work with MPD
albumart.

mpdmenu.pl

index be2c08fb46f8ed0f6cebb7a3f0651610e1fc7e9b..9a7c77efe9f4f185dede74aab9cb4e202b3cfb7d 100755 (executable)
@@ -13,6 +13,7 @@ use strict;
 
 use Getopt::Long;
 use IO::Socket::INET6;
+use Scalar::Util qw(reftype);
 use FindBin;
 
 use constant {
@@ -27,6 +28,72 @@ binmode(STDOUT, ":utf8");
 use Encode;
 
 my $SELF = "$FindBin::Bin/$FindBin::Script";
+my $MUSIC = $ENV{MUSIC} // "/srv/music";
+
+# get_item_thumbnails({ options }, file, ...)
+# get_item_thumbnails(file, ...)
+#
+# For each music file listed, obtain a thumbnail (if any) for the
+# cover art.
+#
+# The first argument is a hash reference to control the mode of
+# operation; it may be omitted for default options.
+#
+#   get_item_thumbnails({ small => 1 }, ...) - smaller thumbnails
+#
+# The returned list consists of strings (in the same order as the filename
+# arguments) suitable for use directly in FVWM menus; by default the filename
+# is bracketed by asterisks (e.g., "*thumbnail.png*"); in small mode it is
+# surrounded by % (e.g., "%thumbnail.png%").  If no cover art was found, the
+# empty string is returned for that file.
+sub get_item_thumbnails {
+       my @results = ();
+       my $flags = {};
+       my @opts = ();
+
+       $flags = shift if (reftype($_[0]) eq "HASH");
+       return @results unless @_;
+
+       my $c = "*";
+       if ($flags->{small}) {
+               push @opts, "--small";
+               $c = "%";
+       }
+
+       foreach (@_) {
+               open THUMB, "-|", "$FindBin::Bin/thumbnail.zsh", "--music",
+                                 @opts, $_;
+               my $thumb = <THUMB>;
+               chomp $thumb;
+
+               $thumb = "$c$thumb$c" if (-f $thumb);
+               push @results, $thumb;
+               close THUMB;
+               die("thumbnail.zsh failed") if ($?);
+       }
+
+       return @results;
+}
+
+# Given a music filename, search for the cover art in the same directory.
+sub mpd_cover_filename {
+       my ($dir) = @_;
+       my $file;
+
+       $dir =~ s/\/[^\/]*$//;
+       foreach ("cover.png", "cover.jpg", "cover.tiff", "cover.bmp") {
+               if (-f "$dir/$_") {
+                       $file = "$dir/$_";
+                       last;
+               }
+       }
+       return unless defined $file;
+
+       # Follow one level of symbolic link to get to the scans directory.
+       $file = readlink($file) // $file;
+       $file = "$dir/$file" unless ($file =~ /^\//);
+       return $file;
+}
 
 sub cmd
 {
@@ -149,18 +216,14 @@ if (defined $album) {
 { # work around 'use locale' breaking s///i
        my $i = 0;
        use locale;
-       foreach (sort keys(%albums)) {
-               my $key      = $_;
-               my $a_album  = sanitise($key, 1);
 
-               open THUMB, "-|", "$FindBin::Bin/thumbnail.zsh",
-                                        "--small", "--music", $albums{$key};
-               my $thumb = <THUMB>;
-               close THUMB;
-               die("Incompetent use of thumbnail.zsh") if ($?);
+       my @keys = sort keys %albums;
+       my @thumbs = get_item_thumbnails({ small => 1 },
+                                         map { $albums{$_} } @keys);
 
-               $thumb =~ s/\n//sg;
-               $thumb = "%$thumb%" if (-f $thumb);
+       foreach my $key (@keys) {
+               my $a_album  = sanitise($key, 1);
+               my $thumb = shift @thumbs;
 
                cmd("AddToMenu $menu \"$thumb$a_album\" Popup MenuMPDArt_$i");
 
@@ -240,12 +303,20 @@ if (defined $album) {
 
 { # work around 'use locale' breaking s///i
        use locale;
+
+       my @thumbs = get_item_thumbnails({ small => 1 },
+                                         map { $_->{file} } @titles);
+       for (my $i = 0; $i < @titles; $i++) {
+               $titles[$i]->{thumb} = $thumbs[$i];
+       }
+
        foreach (sort titlesort @titles) {
-               my ($t_file, $t_artist, $t_title, $t_id) = (
+               my ($t_file, $t_artist, $t_title, $t_id, $thumb) = (
                        $_->{file},
                        $_->{Artist},
                        $_->{Title},
                        $_->{Id},
+                       $_->{thumb}
                );
 
                # MPD searches are case-insensitive.
@@ -254,15 +325,6 @@ if (defined $album) {
                $t_artist = sanitise($t_artist, 1);
                $t_title  = sanitise($t_title, 1);
 
-               open THUMB, "-|", "$FindBin::Bin/thumbnail.zsh",
-                                        "--small", "--music", $t_file;
-               my $thumb = <THUMB>;
-               close(THUMB);
-               die("Incompetent use of thumbnail.zsh") if ($?);
-
-               $thumb =~ s/\n//sg;
-               $thumb = "%$thumb%" if (-f $thumb);
-
                cmd("AddToMenu $menu \"$thumb$t_artist - $t_title\""
                    ." Exec exec $FindBin::Bin/mpdexec.pl"
                    ." playid $t_id");
@@ -303,20 +365,14 @@ if (defined $album) {
                }
                die("Failed data query\n") unless (keys(%entry) > 0);
 
-               open THUMB, "-|", "$FindBin::Bin/thumbnail.zsh",
-                                        "--image", "--music",  $entry{file};
-               my $thumb = <THUMB>;
-               my $scan  = <THUMB>;
-               close(THUMB);
-               die("Incompetent use of thumbnail.zsh") if ($?);
-
-               $thumb =~ s/\n//sg;
-               $scan  =~ s/\n//sg;
+               my ($thumb) = get_item_thumbnails($entry{file});
+               if ($thumb) {
+                       my $cover = mpd_cover_filename("$MUSIC/$entry{file}");
 
-               if (-f $thumb) {
-                       cmd("AddToMenu $menu \"*$thumb*\" "
-                               ."Exec exec geeqie ".shellify($scan, 0));
+                       cmd("AddToMenu $menu \"$thumb\" "
+                               ."Exec exec geeqie ".shellify($cover, 0));
                }
+
                cmd("AddToMenu $menu \"Title:   ".sanitise($entry{Title}, 0)
                        ."\" Popup MenuMPDTitle");
                cmd("AddToMenu $menu \"Artist:  ".sanitise($entry{Artist}, 0)