diff --git a/beetsplug/fetchart.py b/beetsplug/fetchart.py index ef311cbbd8..57e517e408 100644 --- a/beetsplug/fetchart.py +++ b/beetsplug/fetchart.py @@ -1445,6 +1445,16 @@ def _is_source_file_removal_enabled() -> bool: "move" ].get(bool) + def _is_candidate_fallback(self, candidate: Candidate) -> bool: + try: + return ( + candidate.path is not None + and self.fallback is not None + and os.path.samefile(candidate.path, self.fallback) + ) + except OSError: + return False + # Asynchronous; after music is added to the library. def fetch_art(self, session: ImportSession, task: ImportTask) -> None: """Find art for the album being imported.""" @@ -1493,7 +1503,7 @@ def assign_art(self, session: ImportSession, task: ImportTask): self._set_art(task.album, candidate, not removal_enabled) - if removal_enabled: + if removal_enabled and not self._is_candidate_fallback(candidate): task.prune(candidate.path) # Manual album art fetching. diff --git a/docs/changelog.rst b/docs/changelog.rst index 25a0c13650..f419c1d7e8 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -11,6 +11,8 @@ New features: Bug fixes: +- :doc:`plugins/fetchart`: Prevent deletion of configured fallback cover art + For packagers: Other changes: diff --git a/test/plugins/test_art.py b/test/plugins/test_art.py index 02d23d59b7..9f5e6c216d 100644 --- a/test/plugins/test_art.py +++ b/test/plugins/test_art.py @@ -310,6 +310,16 @@ def test_precedence_amongst_correct_files(self): ] assert candidates == paths + @patch("os.path.samefile") + def test_is_candidate_fallback_os_error(self, mock_samefile): + mock_samefile.side_effect = OSError("os error") + fallback = os.path.join(self.temp_dir, b"a.jpg") + self.plugin.fallback = fallback + candidate = fetchart.Candidate(logger, self.source.ID, fallback) + result = self.plugin._is_candidate_fallback(candidate) + mock_samefile.assert_called_once() + assert not result + class CombinedTest(FetchImageTestCase, CAAHelper): ASIN = "xxxx"