Repository: beetbox/beets

Issue:
Improve extractart to extract cover art of all albums for a query
The current `extractart` command of the `embedart` plugin is only able to extract the cover art of a single file. If the query the user specifies results in more than one item, only the art of the first one is extracted.

I would like to improve the command such the user queries for albums (like `ls -a` command) and one cover art is extracted per album and placed inside the album folder. The command should try all files of an album until an art is found. The command could be executed like `beet extractart -a <query>`.



Discussion:
Since I was working on embedart, here is a solution. I probably should add a test for it though...

I don't think the change you made does what I wanted to do: It wont extract the art of all albums specified by a query. It'll still only extract one art file.

Right... I read the issue too fast, sorry


Resolving patch:
diff --git a/beetsplug/embedart.py b/beetsplug/embedart.py
--- a/beetsplug/embedart.py
+++ b/beetsplug/embedart.py
@@ -88,12 +88,30 @@ def embed_func(lib, opts, args):
                                     help='extract an image from file metadata')
         extract_cmd.parser.add_option('-o', dest='outpath',
                                       help='image output file')
+        extract_cmd.parser.add_option('-n', dest='filename',
+                                      help='image filename to create for all '
+                                           'matched albums')
+        extract_cmd.parser.add_option('-a', dest='associate',
+                                      action='store_true',
+                                      help='associate the extracted images '
+                                           'with the album')
 
         def extract_func(lib, opts, args):
-            outpath = normpath(opts.outpath or config['art_filename'].get())
-            for item in lib.items(decargs(args)):
-                if self.extract(outpath, item):
+            if opts.outpath:
+                self.extract_first(normpath(opts.outpath),
+                                   lib.items(decargs(args)))
+            else:
+                filename = opts.filename or config['art_filename'].get()
+                if os.path.dirname(filename) != '':
+                    self._log.error(u"Only specify a name rather than a path "
+                                    u"for -n")
                     return
+                for album in lib.albums(decargs(args)):
+                    artpath = normpath(os.path.join(album.path, filename))
+                    artpath = self.extract_first(artpath, album.items())
+                    if artpath and opts.associate:
+                        album.set_art(artpath)
+                        album.store()
         extract_cmd.func = extract_func
 
         # Clear command.
@@ -236,7 +254,6 @@ def get_art(self, item):
         return mf.art
 
     # 'extractart' command.
-
     def extract(self, outpath, item):
         art = self.get_art(item)
 
@@ -258,6 +275,12 @@ def extract(self, outpath, item):
             f.write(art)
         return outpath
 
+    def extract_first(self, outpath, items):
+        for item in items:
+            real_path = self.extract(outpath, item)
+            if real_path:
+                return real_path
+
     # 'clearart' command.
     def clear(self, lib, query):
         id3v23 = config['id3v23'].get(bool)


Test patch: