badfiles: added config/cli options to automatically take action on error/warning (#6295)

Updated the `badfiles` plugin to support automatic actions taken on
warning or error imports, to be used with `check_on_import: yes`.

Example usage:
```yaml
badfiles:
    check_on_import: yes
    import_action_on_warning: continue
    import_action_on_error: skip
```
The above configuration will skip badfiles that error out, but ignore
any warnings found.
The default for both options is `ask`, preserving current behavior.
This commit is contained in:
Šarūnas Nejus
2026-06-08 17:55:47 +01:00
committed by GitHub
3 changed files with 64 additions and 3 deletions

View File

@@ -19,6 +19,7 @@ import os
import shlex
import sys
from subprocess import STDOUT, CalledProcessError, check_output, list2cmdline
from typing import Literal
import confuse
@@ -51,6 +52,10 @@ class BadFiles(BeetsPlugin):
super().__init__()
self.verbose = False
self.config.add(
{"import_action_on_warning": "ask", "import_action_on_error": "ask"}
)
self.register_listener("import_task_start", self.on_import_task_start)
self.register_listener(
"import_task_before_choice", self.on_import_task_before_choice
@@ -168,18 +173,66 @@ class BadFiles(BeetsPlugin):
if checks_failed:
task._badfiles_checks_failed = checks_failed
def on_import_task_before_choice(self, task, session):
if config["import"]["quiet"]:
return None
def handle_import_action(
self,
action: Literal["abort", "skip", "continue"],
failure_type: Literal["error", "warning"],
) -> importer.Action | None:
action_name_by_action = {
"abort": "Aborting",
"skip": "Skipping",
"continue": "Continuing",
}
ui.print_(
f"{ui.colorize('text_warning', action_name_by_action[action])}"
f" due to import_action_on_{failure_type} configuration"
)
if action == "abort":
raise importer.ImportAbortError()
if action == "skip":
return importer.Action.SKIP
return None
def on_import_task_before_choice(self, task, session):
if hasattr(task, "_badfiles_checks_failed"):
actions = confuse.Choice(["ask", "abort", "skip", "continue"])
warning_action = self.config["import_action_on_warning"].get(
actions
)
error_action = self.config["import_action_on_error"].get(actions)
ui.print_(
f"{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")
# Defer the quiet check to after automatic import action options are handled
if config["import"]["quiet"]:
return None
ui.print_()
ui.print_("What would you like to do?")

View File

@@ -26,6 +26,7 @@ New features
- :doc:`plugins/musicbrainz`: Introduce
:conf:`plugins.musicbrainz:aliases_as_credits` to make
aliases-as-artist-credit optional.
- :doc:`plugins/badfiles`: Added settings for auto error and warning actions.
Bug fixes
~~~~~~~~~

View File

@@ -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: https://sourceforge.net/projects/mp3val/