fix(download): stop wrong album/cover from same-titled tracks; add MusicBrainz fallback
Root cause: deezer pickTrackMatch fell back to a blind title-only match, grabbing a
same-titled song by a completely different artist (e.g. 'Memories' by Rab Noakes for
'☆NoAki☆') and applying its album/cover/year. The download's clean fallback existed
but was never reached because the lookup almost always returned *something*.
Stufe A — deezer.js: the title-only fallback now REQUIRES an artist correspondence
(equal, or one name contained in the other after normalization). No match → {} →
the existing clean fallback finally runs (album_artist = song artist, album =
'Singles', cover = source thumbnail, year/genre untouched). Test that encoded the old
blind behaviour replaced; NoAki + loose-match regression tests added.
Stufe B — musicbrainz.js: a rate-limited (~1/s, User-Agent) MusicBrainz recording
lookup with the SAME artist discipline + Cover Art Archive cover. trackmeta.js is the
single resolver (Deezer → MusicBrainz → clean fallback); the three single-track call
sites use it (album batch stays Deezer-only to avoid MB rate-limit slowdowns).
Unit-tested (17/17) + live-verified: NoAki→clean fallback, real track→Deezer, MB finds
real albums when Deezer misses. Backend-only; no frontend/Android change.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
16f76a4236
commit
6d084a7b7a
6 files changed
+200
-9
No files matched your search
@@ -0,0 +1,22 @@
|
||||
// Single-track metadata resolver — the ONE place callers use to enrich a downloaded single.
|
||||
// Order: Deezer (artist-verified) → MusicBrainz (artist-verified) → nothing.
|
||||
// Returning {} is intentional and safe: the download then uses its clean fallback
|
||||
// (album_artist = song artist, album = "Singles", cover = source thumbnail, year/genre untouched).
|
||||
//
|
||||
// Both sources apply the SAME discipline — the artist must correspond — so a same-titled song by a
|
||||
// different artist can never contaminate album/cover/year again.
|
||||
|
||||
const dz = require('./deezer');
|
||||
const mb = require('./musicbrainz');
|
||||
|
||||
async function lookupTrackMeta(artist, title) {
|
||||
const d = await dz.lookupTrackMeta(artist, title).catch(() => ({}));
|
||||
if (d && d.album) return d; // Deezer matched (artist-verified)
|
||||
|
||||
const m = await mb.lookupTrackMeta(artist, title).catch(() => ({}));
|
||||
if (m && m.album) return m; // MusicBrainz matched (artist-verified)
|
||||
|
||||
return d || {}; // nothing convincing → clean fallback
|
||||
}
|
||||
|
||||
module.exports = { lookupTrackMeta };
|
||||
Reference in new issue
Block a user