Skip to content

Commit e209fe5

Browse files
committed
Parallelized beet bad
1 parent 10bc466 commit e209fe5

File tree

1 file changed

+56
-49
lines changed

1 file changed

+56
-49
lines changed

beetsplug/badfiles.py

+56-49
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020

2121
from beets.plugins import BeetsPlugin
2222
from beets.ui import Subcommand
23-
from beets.util import displayable_path, confit
23+
from beets.util import displayable_path, confit, par_map
2424
from beets import ui
2525
from subprocess import check_output, CalledProcessError, list2cmdline, STDOUT
2626
import shlex
@@ -48,6 +48,9 @@ def __init__(self, cmd, oserror):
4848

4949

5050
class BadFiles(BeetsPlugin):
51+
def __init__(self):
52+
self.verbose = False
53+
5154
def run_command(self, cmd):
5255
self._log.debug(u"running command: {}",
5356
displayable_path(list2cmdline(cmd)))
@@ -89,56 +92,60 @@ def get_checker(self, ext):
8992
command = None
9093
if command:
9194
return self.check_custom(command)
92-
elif ext == "mp3":
95+
if ext == "mp3":
9396
return self.check_mp3val
94-
elif ext == "flac":
97+
if ext == "flac":
9598
return self.check_flac
9699

97-
def check_bad(self, lib, opts, args):
98-
for item in lib.items(ui.decargs(args)):
99-
100-
# First, check whether the path exists. If not, the user
101-
# should probably run `beet update` to cleanup your library.
102-
dpath = displayable_path(item.path)
103-
self._log.debug(u"checking path: {}", dpath)
104-
if not os.path.exists(item.path):
105-
ui.print_(u"{}: file does not exist".format(
106-
ui.colorize('text_error', dpath)))
107-
108-
# Run the checker against the file if one is found
109-
ext = os.path.splitext(item.path)[1][1:].decode('utf8', 'ignore')
110-
checker = self.get_checker(ext)
111-
if not checker:
112-
self._log.error(u"no checker specified in the config for {}",
113-
ext)
114-
continue
115-
path = item.path
116-
if not isinstance(path, six.text_type):
117-
path = item.path.decode(sys.getfilesystemencoding())
118-
try:
119-
status, errors, output = checker(path)
120-
except CheckerCommandException as e:
121-
if e.errno == errno.ENOENT:
122-
self._log.error(
123-
u"command not found: {} when validating file: {}",
124-
e.checker,
125-
e.path
126-
)
127-
else:
128-
self._log.error(u"error invoking {}: {}", e.checker, e.msg)
129-
continue
130-
if status > 0:
131-
ui.print_(u"{}: checker exited with status {}"
132-
.format(ui.colorize('text_error', dpath), status))
133-
for line in output:
134-
ui.print_(u" {}".format(displayable_path(line)))
135-
elif errors > 0:
136-
ui.print_(u"{}: checker found {} errors or warnings"
137-
.format(ui.colorize('text_warning', dpath), errors))
138-
for line in output:
139-
ui.print_(u" {}".format(displayable_path(line)))
140-
elif opts.verbose:
141-
ui.print_(u"{}: ok".format(ui.colorize('text_success', dpath)))
100+
def check_item(self, item):
101+
# First, check whether the path exists. If not, the user
102+
# should probably run `beet update` to cleanup your library.
103+
dpath = displayable_path(item.path)
104+
self._log.debug(u"checking path: {}", dpath)
105+
if not os.path.exists(item.path):
106+
ui.print_(u"{}: file does not exist".format(
107+
ui.colorize('text_error', dpath)))
108+
109+
# Run the checker against the file if one is found
110+
ext = os.path.splitext(item.path)[1][1:].decode('utf8', 'ignore')
111+
checker = self.get_checker(ext)
112+
if not checker:
113+
self._log.error(u"no checker specified in the config for {}",
114+
ext)
115+
return
116+
path = item.path
117+
if not isinstance(path, six.text_type):
118+
path = item.path.decode(sys.getfilesystemencoding())
119+
try:
120+
status, errors, output = checker(path)
121+
except CheckerCommandException as e:
122+
if e.errno == errno.ENOENT:
123+
self._log.error(
124+
u"command not found: {} when validating file: {}",
125+
e.checker,
126+
e.path
127+
)
128+
else:
129+
self._log.error(u"error invoking {}: {}", e.checker, e.msg)
130+
return
131+
if status > 0:
132+
ui.print_(u"{}: checker exited with status {}"
133+
.format(ui.colorize('text_error', dpath), status))
134+
for line in output:
135+
ui.print_(u" {}".format(displayable_path(line)))
136+
elif errors > 0:
137+
ui.print_(u"{}: checker found {} errors or warnings"
138+
.format(ui.colorize('text_warning', dpath), errors))
139+
for line in output:
140+
ui.print_(u" {}".format(displayable_path(line)))
141+
elif self.verbose:
142+
ui.print_(u"{}: ok".format(ui.colorize('text_success', dpath)))
143+
144+
def command(self, lib, opts, args):
145+
# Get items from arguments
146+
items = lib.items(ui.decargs(args))
147+
self.verbose = opts.verbose
148+
par_map(self.check_item, items)
142149

143150
def commands(self):
144151
bad_command = Subcommand('bad',
@@ -148,5 +155,5 @@ def commands(self):
148155
action='store_true', default=False, dest='verbose',
149156
help=u'view results for both the bad and uncorrupted files'
150157
)
151-
bad_command.func = self.check_bad
158+
bad_command.func = self.command
152159
return [bad_command]

0 commit comments

Comments
 (0)