Enable duplicate detection for as-is imports

When importing with autotag=no, duplicate detection was skipped entirely
because the import_asis stage called _apply_choice() directly without
first calling _resolve_duplicates(). This meant the duplicate_keys and
duplicate_action config options were ignored for as-is imports.

This was a known limitation documented by a FIXME comment added in
commit 79d1203541 (Sep 2014): "We should also resolve duplicates when
not autotagging." The FIXME was later removed during a comment cleanup
(f145e3b18) but the issue was never addressed.

This commit adds the _resolve_duplicates() call to import_asis, ensuring
duplicate detection works consistently regardless of the autotag setting.
This applies to both album imports and singleton imports.

Test changes:
- Renamed test_no_autotag_keeps_duplicate_album to
  test_no_autotag_removes_duplicate_album to verify the corrected behavior
- Added test_no_autotag_removes_duplicate_singleton to verify singleton
  duplicate detection also works with autotag=no

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Axel Wikström 2026-01-10 20:03:50 +02:00
parent c04fc95e59
commit b21c231048
2 changed files with 41 additions and 9 deletions

View file

@ -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)

View file

@ -945,29 +945,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
@ -1096,6 +1101,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")