diff --git a/beetsplug/badfiles.py b/beetsplug/badfiles.py index 70509ce4ff..c2e046bcac 100644 --- a/beetsplug/badfiles.py +++ b/beetsplug/badfiles.py @@ -170,16 +170,73 @@ def on_import_task_start(self, task, session): if checks_failed: task._badfiles_checks_failed = checks_failed + def handle_import_action(self, action, failure_type): + if action == "abort": + ui.print_( + f"{ui.colorize('text_warning', 'Aborting')}" + f" due to import_action_on_{failure_type} configuration" + ) + raise importer.ImportAbortError() + elif action == "skip": + ui.print_( + f"{ui.colorize('text_warning', 'Skipping')}" + f" due to import_action_on_{failure_type} configuration" + ) + return importer.Action.SKIP + elif action == "continue": + ui.print_( + f"{ui.colorize('text_warning', 'Continuing')}" + f" due to import_action_on_{failure_type} configuration" + ) + return None + else: + ui.print_( + ui.colorize( + "text_warning", + f"Got invalid import_action_on_{failure_type}" + f" configuration: {action}", + ) + ) + ui.print_( + ui.colorize( + "text_warning", + f"import_action_on_{failure_type} should be one of:" + f" ask abort skip continue", + ) + ) + raise importer.ImportAbortError() + def on_import_task_before_choice(self, task, session): if hasattr(task, "_badfiles_checks_failed"): + warning_action = self.config["import_action_on_warning"].get("ask") + error_action = self.config["import_action_on_error"].get("ask") + ui.print_( f"{ui.colorize('text_warning', 'BAD')} one or more files failed" " checks:" ) + + found_warning = False + found_error = False for error in task._badfiles_checks_failed: for error_line in error: + if 'checker found 0 errors or warnings' in error_line.lower(): + continue + + if "warning" in error_line.lower(): + found_warning = True + if "error" in error_line.lower(): + found_error = True + ui.print_(error_line) + # Check for and handle automatic actions. + # Errors always take precedence over warnings. + if found_error and error_action != "ask": + return self.handle_import_action(error_action, "error") + elif found_warning and warning_action != "ask": + return self.handle_import_action(warning_action, "warning") + ui.print_() ui.print_("What would you like to do?") diff --git a/docs/changelog.rst b/docs/changelog.rst index 711749a9f7..ff4f286e24 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -119,6 +119,7 @@ been dropped. New features ~~~~~~~~~~~~ +- :doc:`plugins/badfiles`: Added settings for auto error and warning actions. - :doc:`plugins/fetchart`: Added config setting for a fallback cover art image. - :doc:`plugins/ftintitle`: Added argument for custom feat. words in ftintitle. - :doc:`plugins/ftintitle`: Added album template value ``album_artist_no_feat``. diff --git a/docs/plugins/badfiles.rst b/docs/plugins/badfiles.rst index 8f496cfce7..605bd46bc2 100644 --- a/docs/plugins/badfiles.rst +++ b/docs/plugins/badfiles.rst @@ -20,6 +20,8 @@ You can also add custom commands for a specific extension, like this: badfiles: check_on_import: yes + import_action_on_error: skip + import_action_on_warning: continue commands: ogg: myoggchecker --opt1 --opt2 flac: flac --test --warnings-as-errors --silent @@ -32,6 +34,11 @@ You can run the checkers when importing files by using the ``check_on_import`` option. When on, checkers will be run against every imported file and warnings and errors will be presented when selecting a tagging option. +`import_action_on_error` and `import_action_on_warning` can be used to take +automatic action on warnings and errors. Both options default to `ask`. Valid +options for both `import_action_on_(warning|error)` are `ask skip abort +continue`. + .. _flac: https://xiph.org/flac/ .. _mp3val: http://mp3val.sourceforge.net/