diff options
| author | Christophe Besson <cbesson@gmail.com> | 2026-08-26 18:09:44 +0200 |
|---|---|---|
| committer | Christophe Besson <cbesson@gmail.com> | 2026-08-26 18:09:44 +0200 |
| commit | 6fb948045b9c563ce591da289cdac1df6bed360c (patch) | |
| tree | 1a783c4ed5dcf23bc65d6bb8825906473670d3aa /packages/meshbay-node/tests/test_enrich_audio.py | |
| parent | 80cb6c4dc5f22336387f2ac74ef2cb85cf2cf7d4 (diff) | |
| download | meshbay-6fb948045b9c563ce591da289cdac1df6bed360c.tar.gz | |
fix(music): stop sharing one folder's cover across unrelated tracks, and merge various-artists compilations into one album
Two real, confirmed bugs in a large flat music library:
- enrich_audio.py's sibling-cover fallback assumed one folder is one
release. A large flat "chart ranking" folder mixing dozens of unrelated
artists carried several distinct WMP AlbumArt-cache guids (one per
original album a track was ripped from), and the fallback picked
whichever one WMP had copied to Folder.jpg — attaching one unrelated
release's cover to every other track in the folder. Now refuses to pick
a cover at all once 2+ distinct guids show up, rather than guess.
- music-app.js's groupMusicEntries grouped by artist first, album second,
so a various-artists compilation (many genuinely different per-track
artists, one shared album tag, no album-artist tag at all — a real
~20-track soundtrack rip has exactly this shape) could never be
recognized as one release: every track landed alone in its own artist's
bucket and got folded into a singleton pile. Now detects an album key
shared across 2+ distinct artist keys and merges those tracks into one
compilation card under a "Various" heading instead.
Both verified against real, previously-affected files and live in the
browser: the shared wrong cover is gone, and the compilation renders as
one card with all its tracks in order.
Diffstat (limited to 'packages/meshbay-node/tests/test_enrich_audio.py')
| -rw-r--r-- | packages/meshbay-node/tests/test_enrich_audio.py | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/packages/meshbay-node/tests/test_enrich_audio.py b/packages/meshbay-node/tests/test_enrich_audio.py index 1485a1f..d69a097 100644 --- a/packages/meshbay-node/tests/test_enrich_audio.py +++ b/packages/meshbay-node/tests/test_enrich_audio.py @@ -12,6 +12,7 @@ from meshbay_node.indexer.enrich_audio import ( _artist_album_from_ancestors, _clean_tag, _extract_cover, + _find_sibling_cover, _musepack_tags_from_object, _split_top_level_folder, ) @@ -292,6 +293,43 @@ async def test_enricher_uses_a_sibling_cover_file_when_no_embedded_art(tmp_path, assert stored == b"\xff\xd8\xff\xe0fake-jpeg-bytes" +def test_find_sibling_cover_refuses_a_folder_that_mixes_several_releases(tmp_path): + """ + A real case: dozens of individually-ripped tracks by unrelated artists + sitting flat in one folder (an informal "chart ranking" compilation, + never a real per-album folder). The ripper left one `AlbumArt_{guid}_*` + thumbnail pair *per original release* it pulled a track from, plus its + own arbitrary `Folder.jpg` copy of just one of them. Two or more distinct + guids among the candidates is direct proof this folder is not a single + release, so no image here can be safely called "the" cover — picking + `Folder.jpg` anyway (the pre-fix behavior) silently attached one + unrelated release's art to every other track in the folder. + """ + folder = tmp_path / "_SomeChartFolder" + folder.mkdir() + (folder / "AlbumArt_{2C5E5D27-1075-43B9-92EE-351846034C67}_Large.jpg").write_bytes(b"one") + (folder / "AlbumArt_{2C5E5D27-1075-43B9-92EE-351846034C67}_Small.jpg").write_bytes(b"one") + (folder / "AlbumArt_{427CA566-E7E9-4ECD-9ED1-1DDADB9D07E8}_Large.jpg").write_bytes(b"two") + (folder / "AlbumArt_{427CA566-E7E9-4ECD-9ED1-1DDADB9D07E8}_Small.jpg").write_bytes(b"two") + (folder / "AlbumArtSmall.jpg").write_bytes(b"whichever") + (folder / "Folder.jpg").write_bytes(b"whichever") + + assert _find_sibling_cover(folder) is None + + +def test_find_sibling_cover_still_picks_folder_jpg_for_a_single_release(tmp_path): + """Regression guard: a real single-release folder (one guid, or none at + all, same shape as the existing sibling-cover test above) must keep + picking its Folder.jpg exactly as before this fix.""" + folder = tmp_path / "Some Artist" / "Some Album" + folder.mkdir(parents=True) + (folder / "AlbumArt_{2C5E5D27-1075-43B9-92EE-351846034C67}_Large.jpg").write_bytes(b"one") + (folder / "AlbumArt_{2C5E5D27-1075-43B9-92EE-351846034C67}_Small.jpg").write_bytes(b"one") + (folder / "Folder.jpg").write_bytes(b"one") + + assert _find_sibling_cover(folder) == folder / "Folder.jpg" + + async def _run(enricher, entry, path, root_path=None): done = asyncio.get_event_loop().create_future() |