From cc39c94d9ccf76b3ff4ddc524f50708391776cf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mika=C3=ABl=20Hautin?= <3902243+Mikaciu@users.noreply.github.com> Date: Wed, 9 Jul 2025 21:11:44 +0200 Subject: [PATCH 1/2] feat(unimported): add a configuration option to consider ignore_subdirectories as globs Uses the same method to go through the files than the importer, `util.sorted_walk` --- beetsplug/unimported.py | 38 ++++++++++++++++++++++++++++--------- docs/plugins/unimported.rst | 5 +++++ 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/beetsplug/unimported.py b/beetsplug/unimported.py index b473a346a..2d09ab4b7 100644 --- a/beetsplug/unimported.py +++ b/beetsplug/unimported.py @@ -29,7 +29,34 @@ __author__ = "https://github.com/MrNuggelz" class Unimported(BeetsPlugin): def __init__(self): super().__init__() - self.config.add({"ignore_extensions": [], "ignore_subdirectories": []}) + self.config.add( + { + "ignore_extensions": [], + "ignore_subdirectories": [], + "ignore_as_globs": False, + } + ) + + def walk(self, lib): + ignore_subdirs = self.config["ignore_subdirectories"].as_str_seq() + if self.config["ignore_as_globs"].get(bool): + # The way beets ignore elements in the library, using globbing, + # whatever the depth + for root, _, files in util.sorted_walk( + lib.directory, ignore=ignore_subdirs + ): + yield (root, files) + else: + # the reverse-compatible search, with ignore_subdirectories as + # a direct child of the library root + ignore_dirs = [ + os.path.join(lib.directory, x.encode()) for x in ignore_subdirs + ] + for root, _, files in os.walk(lib.directory): + # do not traverse if root is a child of an ignored directory + if any(root.startswith(ignored) for ignored in ignore_dirs): + continue + yield (root, files) def commands(self): def print_unimported(lib, opts, args): @@ -37,15 +64,8 @@ class Unimported(BeetsPlugin): ("." + x).encode() for x in self.config["ignore_extensions"].as_str_seq() ] - ignore_dirs = [ - os.path.join(lib.directory, x.encode()) - for x in self.config["ignore_subdirectories"].as_str_seq() - ] in_folder = set() - for root, _, files in os.walk(lib.directory): - # do not traverse if root is a child of an ignored directory - if any(root.startswith(ignored) for ignored in ignore_dirs): - continue + for root, files in self.walk(lib): for file in files: # ignore files with ignored extensions if any(file.endswith(ext) for ext in ignore_exts): diff --git a/docs/plugins/unimported.rst b/docs/plugins/unimported.rst index 1673c9d54..62a1a6436 100644 --- a/docs/plugins/unimported.rst +++ b/docs/plugins/unimported.rst @@ -18,5 +18,10 @@ file: unimported: ignore_extensions: jpg png ignore_subdirectories: NonMusic data temp + ignore_as_globs: false The default configuration lists all unimported files, ignoring no extensions. + +When true, the ``ignore_as_globs`` parameter uses the same way of parsing files +as beets, using the ``ignore_subdirectories`` as globs whatever the depth, +instead of excluding them if they are the direct child of the library root. From 81676e538bdbdccf02a26175e5aab61f66510e99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mika=C3=ABl=20Hautin?= <3902243+Mikaciu@users.noreply.github.com> Date: Mon, 11 Aug 2025 00:27:51 +0200 Subject: [PATCH 2/2] feat(unimported): add changelog entry --- docs/changelog.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/changelog.rst b/docs/changelog.rst index ab896a7ff..a5af0a26d 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -32,6 +32,8 @@ New features: ``played_ratio_threshold``, to allow configuring the percentage the song must be played for it to be counted as played instead of skipped. - :doc:`plugins/web`: Display artist and album as part of the search results. +- :doc:`/plugins/unimported`: Add ``ignore_as_globs`` option to use globbing for + the ``ignore_subdirectories`` option. Bug fixes: