diff --git a/beets/importer/stages.py b/beets/importer/stages.py index 0f8cf922b..64d305aa8 100644 --- a/beets/importer/stages.py +++ b/beets/importer/stages.py @@ -230,6 +230,7 @@ def import_asis(session: ImportSession, task: ImportTask): log.info("{}", displayable_path(task.paths)) task.set_choice(Action.ASIS) + _resolve_duplicates(session, task) _apply_choice(session, task) diff --git a/docs/changelog.rst b/docs/changelog.rst index 6a0fa5d7d..b7a284587 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -44,15 +44,18 @@ Bug fixes - :doc:`plugins/zero`: When the ``omit_single_disc`` option is set, ``disctotal`` is zeroed alongside ``disc``. - :doc:`plugins/fetchart`: Prevent deletion of configured fallback cover art -- In autotagging, initialise empty multi-valued fields with ``None`` instead of - empty list, which caused beets to overwrite existing metadata with empty list - values instead of leaving them unchanged. :bug:`6403` +- :ref:`import-cmd` When autotagging, initialise empty multi-valued fields with + ``None`` instead of empty list, which caused beets to overwrite existing + metadata with empty list values instead of leaving them unchanged. :bug:`6403` - :doc:`plugins/fuzzy`: Improve fuzzy matching when the query is shorter than the field value so substring-style searches produce more useful results. :bug:`2043` - :doc:`plugins/fuzzy`: Force slow query evaluation whenever the fuzzy prefix is used (for example ``~foo`` or ``%%foo``), so fuzzy matching is applied consistently. :bug:`5638` +- :ref:`import-cmd` Duplicate detection now works for as-is imports (when + ``autotag`` is disabled). Previously, ``duplicate_keys`` and + ``duplicate_action`` config options were silently ignored for as-is imports. For plugin developers ~~~~~~~~~~~~~~~~~~~~~ diff --git a/test/test_importer.py b/test/test_importer.py index 56327af06..fe37072fe 100644 --- a/test/test_importer.py +++ b/test/test_importer.py @@ -954,29 +954,34 @@ class ImportDuplicateAlbumTest(PluginMixin, ImportTestCase): item = self.lib.items().get() assert item.title == "new title" - def test_no_autotag_keeps_duplicate_album(self): + def test_no_autotag_removes_duplicate_album(self): config["import"]["autotag"] = False + album = self.lib.albums().get() item = self.lib.items().get() assert item.title == "t\xeftle 0" assert item.filepath.exists() - # Imported item has the same artist and album as the one in the - # library. + # Imported item has the same albumartist and album as the one in the + # library album. We use album metadata (not item metadata) since + # duplicate detection uses album-level fields. import_file = os.path.join( self.importer.paths[0], b"album", b"track_1.mp3" ) import_file = MediaFile(import_file) - import_file.artist = item["artist"] - import_file.albumartist = item["artist"] - import_file.album = item["album"] + import_file.artist = album.albumartist + import_file.albumartist = album.albumartist + import_file.album = album.album import_file.title = "new title" + import_file.save() self.importer.default_resolution = self.importer.Resolution.REMOVE self.importer.run() - assert item.filepath.exists() - assert len(self.lib.albums()) == 2 - assert len(self.lib.items()) == 2 + # Old duplicate should be removed, new one imported + assert len(self.lib.albums()) == 1 + assert len(self.lib.items()) == 1 + # The new item should be in the library + assert self.lib.items().get().title == "new title" def test_keep_duplicate_album(self): self.importer.default_resolution = self.importer.Resolution.KEEPBOTH @@ -1105,6 +1110,32 @@ class ImportDuplicateSingletonTest(ImportTestCase): assert len(self.lib.items()) == 2 + def test_no_autotag_removes_duplicate_singleton(self): + config["import"]["autotag"] = False + item = self.lib.items().get() + assert item.mb_trackid == "old trackid" + assert item.filepath.exists() + + # Imported item has the same artist and title as the one in the + # library. We use item metadata since duplicate detection uses + # item-level fields for singletons. + import_file = os.path.join( + self.importer.paths[0], b"album", b"track_1.mp3" + ) + import_file = MediaFile(import_file) + import_file.artist = item.artist + import_file.title = item.title + import_file.mb_trackid = "new trackid" + import_file.save() + + self.importer.default_resolution = self.importer.Resolution.REMOVE + self.importer.run() + + # Old duplicate should be removed, new one imported + assert len(self.lib.items()) == 1 + # The new item should be in the library + assert self.lib.items().get().mb_trackid == "new trackid" + def test_twice_in_import_dir(self): self.skipTest("write me")