mirror of
https://github.com/beetbox/beets.git
synced 2025-12-06 16:42:42 +01:00
Add a new hook for badfiles pre-import user interaction, instead of flagging the task.
This commit is contained in:
parent
9c17d9a924
commit
1d4a2c3e2a
4 changed files with 47 additions and 18 deletions
|
|
@ -472,7 +472,6 @@ class ImportTask(BaseImportTask):
|
||||||
def __init__(self, toppath, paths, items):
|
def __init__(self, toppath, paths, items):
|
||||||
super(ImportTask, self).__init__(toppath, paths, items)
|
super(ImportTask, self).__init__(toppath, paths, items)
|
||||||
self.choice_flag = None
|
self.choice_flag = None
|
||||||
self.skip_summary_judgement = False
|
|
||||||
self.cur_album = None
|
self.cur_album = None
|
||||||
self.cur_artist = None
|
self.cur_artist = None
|
||||||
self.candidates = []
|
self.candidates = []
|
||||||
|
|
|
||||||
|
|
@ -501,6 +501,22 @@ def send(event, **arguments):
|
||||||
return results
|
return results
|
||||||
|
|
||||||
|
|
||||||
|
def send_seq(event, **arguments):
|
||||||
|
"""Like `send` but passes the result of the previous event handler to the
|
||||||
|
next, and returns only the result of the last non-None event handler.
|
||||||
|
|
||||||
|
`event` is the name of the event to send, all other named arguments
|
||||||
|
are passed along to the handlers.
|
||||||
|
"""
|
||||||
|
log.debug(u'Sequentially sending event: {0}', event)
|
||||||
|
previous = None
|
||||||
|
for handler in event_handlers()[event]:
|
||||||
|
result = handler(previous=previous, **arguments)
|
||||||
|
previous = result or previous
|
||||||
|
|
||||||
|
return previous
|
||||||
|
|
||||||
|
|
||||||
def feat_tokens(for_artist=True):
|
def feat_tokens(for_artist=True):
|
||||||
"""Return a regular expression that matches phrases like "featuring"
|
"""Return a regular expression that matches phrases like "featuring"
|
||||||
that separate a main artist or a song title from secondary artists.
|
that separate a main artist or a song title from secondary artists.
|
||||||
|
|
|
||||||
|
|
@ -698,10 +698,13 @@ class TerminalImportSession(importer.ImportSession):
|
||||||
print_(displayable_path(task.paths, u'\n') +
|
print_(displayable_path(task.paths, u'\n') +
|
||||||
u' ({0} items)'.format(len(task.items)))
|
u' ({0} items)'.format(len(task.items)))
|
||||||
|
|
||||||
# Call here so plugins have the option to skip `_summary_judgement`
|
# Let plugins display info or prompt the user before we go through the
|
||||||
choices = self._get_choices(task)
|
# process of selecting candidate.
|
||||||
|
action = plugins.send_seq('import_task_before_choice',
|
||||||
|
session=self, task=task)
|
||||||
|
if action is not None:
|
||||||
|
return action
|
||||||
|
|
||||||
if not task.skip_summary_judgement:
|
|
||||||
# Take immediate action if appropriate.
|
# Take immediate action if appropriate.
|
||||||
action = _summary_judgment(task.rec)
|
action = _summary_judgment(task.rec)
|
||||||
if action == importer.action.APPLY:
|
if action == importer.action.APPLY:
|
||||||
|
|
@ -717,6 +720,7 @@ class TerminalImportSession(importer.ImportSession):
|
||||||
# `choose_candidate` may be an `importer.action`, an
|
# `choose_candidate` may be an `importer.action`, an
|
||||||
# `AlbumMatch` object for a specific selection, or a
|
# `AlbumMatch` object for a specific selection, or a
|
||||||
# `PromptChoice`.
|
# `PromptChoice`.
|
||||||
|
choices = self._get_choices(task)
|
||||||
choice = choose_candidate(
|
choice = choose_candidate(
|
||||||
task.candidates, False, task.rec, task.cur_artist,
|
task.candidates, False, task.rec, task.cur_artist,
|
||||||
task.cur_album, itemcount=len(task.items), choices=choices
|
task.cur_album, itemcount=len(task.items), choices=choices
|
||||||
|
|
@ -745,8 +749,6 @@ class TerminalImportSession(importer.ImportSession):
|
||||||
assert isinstance(choice, autotag.AlbumMatch)
|
assert isinstance(choice, autotag.AlbumMatch)
|
||||||
return choice
|
return choice
|
||||||
|
|
||||||
choices = self._get_choices(task)
|
|
||||||
|
|
||||||
def choose_item(self, task):
|
def choose_item(self, task):
|
||||||
"""Ask the user for a choice about tagging a single item. Returns
|
"""Ask the user for a choice about tagging a single item. Returns
|
||||||
either an action constant or a TrackMatch object.
|
either an action constant or a TrackMatch object.
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ from beets.plugins import BeetsPlugin
|
||||||
from beets.ui import Subcommand
|
from beets.ui import Subcommand
|
||||||
from beets.util import displayable_path, par_map
|
from beets.util import displayable_path, par_map
|
||||||
from beets import ui
|
from beets import ui
|
||||||
|
from beets import importer
|
||||||
|
|
||||||
|
|
||||||
class CheckerCommandException(Exception):
|
class CheckerCommandException(Exception):
|
||||||
|
|
@ -56,8 +57,8 @@ class BadFiles(BeetsPlugin):
|
||||||
|
|
||||||
self.register_listener('import_task_start',
|
self.register_listener('import_task_start',
|
||||||
self.on_import_task_start)
|
self.on_import_task_start)
|
||||||
self.register_listener('before_choose_candidate',
|
self.register_listener('import_task_before_choice',
|
||||||
self.on_before_choose_candidate)
|
self.on_import_task_before_choice)
|
||||||
|
|
||||||
def run_command(self, cmd):
|
def run_command(self, cmd):
|
||||||
self._log.debug(u"running command: {}",
|
self._log.debug(u"running command: {}",
|
||||||
|
|
@ -171,9 +172,8 @@ class BadFiles(BeetsPlugin):
|
||||||
|
|
||||||
if checks_failed:
|
if checks_failed:
|
||||||
task._badfiles_checks_failed = checks_failed
|
task._badfiles_checks_failed = checks_failed
|
||||||
task.skip_summary_judgement = True
|
|
||||||
|
|
||||||
def on_before_choose_candidate(self, task, session):
|
def on_import_task_before_choice(self, task, session, previous):
|
||||||
if hasattr(task, '_badfiles_checks_failed'):
|
if hasattr(task, '_badfiles_checks_failed'):
|
||||||
ui.print_('{} one or more files failed checks:'
|
ui.print_('{} one or more files failed checks:'
|
||||||
.format(ui.colorize('text_warning', 'BAD')))
|
.format(ui.colorize('text_warning', 'BAD')))
|
||||||
|
|
@ -182,6 +182,18 @@ class BadFiles(BeetsPlugin):
|
||||||
ui.print_(error_line)
|
ui.print_(error_line)
|
||||||
|
|
||||||
ui.print_()
|
ui.print_()
|
||||||
|
ui.print_('What would you like to do?')
|
||||||
|
|
||||||
|
sel = ui.input_options(['aBort', 'skip', 'continue'])
|
||||||
|
|
||||||
|
if sel == 's':
|
||||||
|
return importer.action.SKIP
|
||||||
|
elif sel == 'c':
|
||||||
|
return None
|
||||||
|
elif sel == 'b':
|
||||||
|
raise importer.ImportAbort()
|
||||||
|
else:
|
||||||
|
raise Exception('Unexpected selection: {}'.format(sel))
|
||||||
|
|
||||||
def command(self, lib, opts, args):
|
def command(self, lib, opts, args):
|
||||||
# Get items from arguments
|
# Get items from arguments
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue