aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-node
diff options
context:
space:
mode:
Diffstat (limited to 'packages/meshbay-node')
-rw-r--r--packages/meshbay-node/src/meshbay_node/indexer/enrich_audio.py15
-rw-r--r--packages/meshbay-node/tests/test_enrich_audio.py39
2 files changed, 27 insertions, 27 deletions
diff --git a/packages/meshbay-node/src/meshbay_node/indexer/enrich_audio.py b/packages/meshbay-node/src/meshbay_node/indexer/enrich_audio.py
index 9ecf1b9..5225d4f 100644
--- a/packages/meshbay-node/src/meshbay_node/indexer/enrich_audio.py
+++ b/packages/meshbay-node/src/meshbay_node/indexer/enrich_audio.py
@@ -198,8 +198,8 @@ def _read_tags_and_cover(path: Path) -> tuple[dict, float | None, bytes | None]:
# A folder name used as a last-resort artist/album, cleaned of the
# punctuation-as-separator and release-tag noise this era of rip is full of
-# ("L_Oeuf_Raide_-_Berlin_Eggsile", "Sinsemilia - Premiere Recolte [MP3
-# 320kbps Album]"). Same spirit as title_parse.naive_title for video, kept
+# (underscores standing in for spaces, a bitrate/quality tag still attached
+# to the name). Same spirit as title_parse.naive_title for video, kept
# separate because the junk vocabulary differs (bitrates and rip tags, not
# edition/language tags).
# A whole bracketed/parenthesized group is dropped if it contains any rip-tag
@@ -228,12 +228,11 @@ def _split_top_level_folder(name: str) -> tuple[str, str | None]:
directly under the group's root (§ below) — there is no further
ancestor to call "artist" without leaving the root entirely. The common
convention for a single-release folder at that level is
- "Artist - Album ...junk..." ("GHOST DOG - Soundtrack",
- "cypress_hill_-los_grandes__xitos_en_espa_ol"); split on the first
- " - " when the cleaned name has one. Otherwise the whole (cleaned) name
- becomes the artist alone, which is the *more* common real shape here —
- a flat per-artist folder with no album subfolder at all ("Ben Harper",
- "bob_marley", "Renaud").
+ "Artist - Album ...junk..." (e.g. a soundtrack folder named after the
+ film, or a release folder with the ripper's tags still attached); split
+ on the first " - " when the cleaned name has one. Otherwise the whole
+ (cleaned) name becomes the artist alone, which is the *more* common real
+ shape here — a flat per-artist folder with no album subfolder at all.
"""
cleaned = _clean_folder_name(name)
m = re.match(r"^(.{2,60}?)\s*-\s*(.{2,80})$", cleaned)
diff --git a/packages/meshbay-node/tests/test_enrich_audio.py b/packages/meshbay-node/tests/test_enrich_audio.py
index 221f1c6..0fd8e17 100644
--- a/packages/meshbay-node/tests/test_enrich_audio.py
+++ b/packages/meshbay-node/tests/test_enrich_audio.py
@@ -68,18 +68,18 @@ def test_artist_album_from_ancestors_refuses_to_name_the_root_as_artist(tmp_path
The regression this whole revision exists for: a flat `Artist/track.mp3`
layout (no album subfolder) used to read the *root's own directory
name* as the artist, because the walk always climbed two levels with no
- idea where the root was. Measured live: 289 tracks across 41 real,
- unrelated artists collapsed into one fake "artist" this way — the
+ idea where the root was. Measured live against a real library: dozens
+ of unrelated artists collapsed into one fake "artist" this way — the
single biggest bucket in the whole library.
"""
- folder = tmp_path / "Ben Harper"
+ folder = tmp_path / "Some Flat Artist"
folder.mkdir(parents=True)
- track = folder / "Ashes.mp3"
+ track = folder / "A Track.mp3"
track.touch()
artist, album = _artist_album_from_ancestors(track, tmp_path)
- assert artist == "Ben Harper"
+ assert artist == "Some Flat Artist"
assert album is None, "no album folder exists — must not invent one, or swap artist/album"
@@ -106,22 +106,22 @@ def test_artist_album_from_ancestors_without_a_root_keeps_the_old_two_level_beha
def test_split_top_level_folder_splits_artist_dash_album():
- artist, album = _split_top_level_folder("GHOST DOG - Soundtrack")
- assert artist == "GHOST DOG"
+ artist, album = _split_top_level_folder("Some Movie - Soundtrack")
+ assert artist == "Some Movie"
assert album == "Soundtrack"
def test_split_top_level_folder_with_no_separator_is_artist_only():
- artist, album = _split_top_level_folder("Ben Harper")
- assert artist == "Ben Harper"
+ artist, album = _split_top_level_folder("Some Flat Artist")
+ assert artist == "Some Flat Artist"
assert album is None
def test_split_top_level_folder_cleans_rip_tag_noise():
artist, album = _split_top_level_folder(
- "Sinsemilia - Premiere Recolte [MP3 320kbps Album]")
- assert artist == "Sinsemilia"
- assert album == "Premiere Recolte"
+ "Some Artist - Some Release [MP3 320kbps Album]")
+ assert artist == "Some Artist"
+ assert album == "Some Release"
def test_clean_tag_filters_known_placeholders():
@@ -139,16 +139,17 @@ def test_clean_tag_keeps_various_artists_as_a_real_credit():
def test_clean_tag_keeps_a_real_value():
- assert _clean_tag("Björk") == "Björk"
+ # Non-ASCII must not be mistaken for a placeholder pattern.
+ assert _clean_tag("Ünïqùé Ärtïst") == "Ünïqùé Ärtïst"
def test_strip_track_prefix_removes_a_leaked_filename_number():
- assert strip_track_prefix("01 - Venus As A Boy (Edited Lp Version)") == \
- "Venus As A Boy (Edited Lp Version)"
+ assert strip_track_prefix("01 - Some Track (Edited Version)") == \
+ "Some Track (Edited Version)"
def test_strip_track_prefix_is_a_noop_on_a_clean_title():
- assert strip_track_prefix("Venus As A Boy") == "Venus As A Boy"
+ assert strip_track_prefix("Some Track") == "Some Track"
# ── end-to-end against a real (tiny, synthetic) MP3 file ────────────────────
@@ -234,9 +235,9 @@ async def test_enricher_falls_back_to_filename_and_folder_when_tags_absent(tmp_p
@pytest.mark.asyncio
async def test_enricher_falls_back_to_artist_only_for_a_flat_top_level_dir(tmp_path, media_cache):
"""The real-world regression case, end to end through the whole pool."""
- folder = tmp_path / "Ben Harper"
+ folder = tmp_path / "Some Flat Artist"
folder.mkdir(parents=True)
- clip = folder / "Ashes.mp3"
+ clip = folder / "A Track.mp3"
_make_clip(clip) # no metadata tags at all
entry = IndexEntry(id="fileid3", name=clip.name,
path=str(clip.relative_to(tmp_path)),
@@ -251,7 +252,7 @@ async def test_enricher_falls_back_to_artist_only_for_a_flat_top_level_dir(tmp_p
enricher.spawn(entry, clip, on_done, tmp_path)
_, fields = await asyncio.wait_for(done, timeout=30)
- assert fields["artist"] == "Ben Harper"
+ assert fields["artist"] == "Some Flat Artist"
assert fields["album"] is None
assert fields["artist"] != tmp_path.name, \
"must never fall back to the shared root's own directory name"