fix: detect archive duplicates by print name in list view (#315)

The duplicate badge on archive cards only matched by content hash,
so re-sliced prints of the same model (different GCODE, same name)
were not flagged. Now also matches by print name (case-insensitive),
consistent with the detail view's find_duplicates() logic.
This commit is contained in:
maziggy
2026-02-15 14:05:11 +01:00
parent aa9db501ec
commit 2de2d3be8d
3 changed files with 21 additions and 8 deletions
+6 -4
View File
@@ -134,13 +134,15 @@ async def list_archives(
offset=offset,
)
# Get set of hashes that have duplicates (efficient single query)
duplicate_hashes = await service.get_duplicate_hashes()
# Get sets of hashes and names that have duplicates (efficient single queries)
duplicate_hashes, duplicate_names = await service.get_duplicate_hashes_and_names()
# Mark archives that have duplicates
# Mark archives that have duplicates (by hash or by print name)
result = []
for a in archives:
has_duplicate = a.content_hash in duplicate_hashes if a.content_hash else False
has_hash_dup = a.content_hash in duplicate_hashes if a.content_hash else False
has_name_dup = a.print_name and a.print_name.lower() in duplicate_names
has_duplicate = has_hash_dup or has_name_dup
result.append(archive_to_response(a, duplicate_count=1 if has_duplicate else 0))
return result
+14 -4
View File
@@ -727,10 +727,10 @@ class ArchiveService:
sha256.update(chunk)
return sha256.hexdigest()
async def get_duplicate_hashes(self) -> set[str]:
"""Get all content hashes that appear more than once.
async def get_duplicate_hashes_and_names(self) -> tuple[set[str], set[str]]:
"""Get all content hashes and print names that appear more than once.
Returns a set of hashes that have duplicates.
Returns a tuple of (duplicate_hashes, duplicate_names).
"""
from sqlalchemy import func
@@ -740,7 +740,17 @@ class ArchiveService:
.group_by(PrintArchive.content_hash)
.having(func.count(PrintArchive.id) > 1)
)
return {row[0] for row in result.all()}
duplicate_hashes = {row[0] for row in result.all()}
result = await self.db.execute(
select(func.lower(PrintArchive.print_name))
.where(PrintArchive.print_name.isnot(None))
.group_by(func.lower(PrintArchive.print_name))
.having(func.count(PrintArchive.id) > 1)
)
duplicate_names = {row[0] for row in result.all()}
return duplicate_hashes, duplicate_names
async def find_duplicates(
self,