Parallelized `beet bad`
@@ -20,7 +20,7 @@ from __future__ import division, absolute_import, print_function
from beets.plugins import BeetsPlugin
from beets.ui import Subcommand
-from beets.util import displayable_path, confit
+from beets.util import displayable_path, confit, par_map
from beets import ui
from subprocess import check_output, CalledProcessError, list2cmdline, STDOUT
import shlex
@@ -48,6 +48,9 @@ class CheckerCommandException(Exception):
class BadFiles(BeetsPlugin):
+ def __init__(self):
+ self.verbose = False
+
def run_command(self, cmd):
self._log.debug(u"running command: {}",
displayable_path(list2cmdline(cmd)))
@@ -89,14 +92,12 @@ class BadFiles(BeetsPlugin):
command = None
if command:
return self.check_custom(command)
- elif ext == "mp3":
+ if ext == "mp3":
return self.check_mp3val
- elif ext == "flac":
+ if ext == "flac":
return self.check_flac
- def check_bad(self, lib, opts, args):
- for item in lib.items(ui.decargs(args)):
-
+ def check_item(self, item):
# First, check whether the path exists. If not, the user
# should probably run `beet update` to cleanup your library.
dpath = displayable_path(item.path)
@@ -111,7 +112,7 @@ class BadFiles(BeetsPlugin):
if not checker:
self._log.error(u"no checker specified in the config for {}",
ext)
- continue
+ return
path = item.path
if not isinstance(path, six.text_type):
path = item.path.decode(sys.getfilesystemencoding())
@@ -126,7 +127,7 @@ class BadFiles(BeetsPlugin):
)
else:
self._log.error(u"error invoking {}: {}", e.checker, e.msg)
- continue
+ return
if status > 0:
ui.print_(u"{}: checker exited with status {}"
.format(ui.colorize('text_error', dpath), status))
@@ -137,9 +138,15 @@ class BadFiles(BeetsPlugin):
.format(ui.colorize('text_warning', dpath), errors))
for line in output:
ui.print_(u" {}".format(displayable_path(line)))
- elif opts.verbose:
+ elif self.verbose:
ui.print_(u"{}: ok".format(ui.colorize('text_success', dpath)))
+ def command(self, lib, opts, args):
+ # Get items from arguments
+ items = lib.items(ui.decargs(args))
+ self.verbose = opts.verbose
+ par_map(self.check_item, items)
+
def commands(self):
bad_command = Subcommand('bad',
help=u'check for corrupt or missing files')
@@ -148,5 +155,5 @@ class BadFiles(BeetsPlugin):
action='store_true', default=False, dest='verbose',
help=u'view results for both the bad and uncorrupted files'
)
- bad_command.func = self.check_bad
+ bad_command.func = self.command
return [bad_command]
