From 90f0ae2d93c389dd2b8713872bfabff53efb190e Mon Sep 17 00:00:00 2001 From: Max Goltzsche Date: Tue, 14 May 2024 00:44:02 +0200 Subject: [PATCH 1/2] fetchart: defer file removal config option eval Defer the evaluation of the source file removal options (`import.delete` and `import.move`) to the point where the fetchart plugin is actually called instead of only evaluating those configuration options on plugin initialization. This is to allow other plugins (such as the [ytimport](https://github.com/mgoltzsche/beets-ytimport/blob/v1.8.1/beetsplug/ytimport/__init__.py#L194) plugin) to invoke the import directly (within the same python process; implicitly invoking the fetchart plugin) with temporarily overwritten configuration options. Relates to https://github.com/beetbox/beets/issues/5167#issuecomment-2106465172 --- beetsplug/fetchart.py | 15 +++++++++------ docs/changelog.rst | 2 ++ test/plugins/test_art.py | 10 +++++++--- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/beetsplug/fetchart.py b/beetsplug/fetchart.py index a3bac19a1c..2104d1bcae 100644 --- a/beetsplug/fetchart.py +++ b/beetsplug/fetchart.py @@ -1253,10 +1253,6 @@ def __init__(self): self.cautious = self.config["cautious"].get(bool) self.store_source = self.config["store_source"].get(bool) - self.src_removed = config["import"]["delete"].get(bool) or config[ - "import" - ]["move"].get(bool) - self.cover_format = self.config["cover_format"].get( confuse.Optional(str) ) @@ -1340,10 +1336,11 @@ def assign_art(self, session, task): """Place the discovered art in the filesystem.""" if task in self.art_candidates: candidate = self.art_candidates.pop(task) + removal_enabled = _is_source_file_removal_enabled() - self._set_art(task.album, candidate, not self.src_removed) + self._set_art(task.album, candidate, not removal_enabled) - if self.src_removed: + if removal_enabled: task.prune(candidate.path) # Manual album art fetching. @@ -1443,3 +1440,9 @@ def batch_fetch_art(self, lib, albums, force, quiet): else: message = ui.colorize("text_error", "no art found") self._log.info("{0}: {1}", album, message) + + +def _is_source_file_removal_enabled(): + delete_enabled = config["import"]["delete"].get(bool) + move_enabled = config["import"]["move"].get(bool) + return delete_enabled or move_enabled diff --git a/docs/changelog.rst b/docs/changelog.rst index f02ba89803..98fda24783 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -208,6 +208,8 @@ New features: * Add support for `barcode` field. :bug:`3172` * :doc:`/plugins/smartplaylist`: Add new config option `smartplaylist.fields`. +* :doc:`/plugins/fetchart`: Defer source removal config option evaluation to + the point where they are used really, supporting temporary config changes. Bug fixes: diff --git a/test/plugins/test_art.py b/test/plugins/test_art.py index 6e877917d7..db3ef8e72e 100644 --- a/test/plugins/test_art.py +++ b/test/plugins/test_art.py @@ -825,9 +825,13 @@ def test_leave_original_file_in_place(self): self.assertExists(self.art_file) def test_delete_original_file(self): - self.plugin.src_removed = True - self._fetch_art(True) - self.assertNotExists(self.art_file) + prev_move = config["import"]["move"].get() + try: + config["import"]["move"] = True + self._fetch_art(True) + self.assertNotExists(self.art_file) + finally: + config["import"]["move"] = prev_move def test_do_not_delete_original_if_already_in_place(self): artdest = os.path.join(os.path.dirname(self.i.path), b"cover.jpg") From 00add272ced01ac342235134d0b29ed6edcc298b Mon Sep 17 00:00:00 2001 From: Max Goltzsche Date: Fri, 13 Sep 2024 22:46:15 +0200 Subject: [PATCH 2/2] fetchart: apply review remarks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit simplifying config access Co-authored-by: Šarūnas Nejus --- beetsplug/fetchart.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/beetsplug/fetchart.py b/beetsplug/fetchart.py index 2104d1bcae..b31ca626bb 100644 --- a/beetsplug/fetchart.py +++ b/beetsplug/fetchart.py @@ -1294,6 +1294,10 @@ def __init__(self): for s, c in sources ] + @staticmethod + def _is_source_file_removal_enabled(): + return config["import"]["delete"] or config["import"]["move"] + # Asynchronous; after music is added to the library. def fetch_art(self, session, task): """Find art for the album being imported.""" @@ -1336,7 +1340,7 @@ def assign_art(self, session, task): """Place the discovered art in the filesystem.""" if task in self.art_candidates: candidate = self.art_candidates.pop(task) - removal_enabled = _is_source_file_removal_enabled() + removal_enabled = FetchArtPlugin._is_source_file_removal_enabled() self._set_art(task.album, candidate, not removal_enabled) @@ -1440,9 +1444,3 @@ def batch_fetch_art(self, lib, albums, force, quiet): else: message = ui.colorize("text_error", "no art found") self._log.info("{0}: {1}", album, message) - - -def _is_source_file_removal_enabled(): - delete_enabled = config["import"]["delete"].get(bool) - move_enabled = config["import"]["move"].get(bool) - return delete_enabled or move_enabled