fix(reenrich): keep release identity when the matched track is from another album

An ISRC identifies a recording, not a release, so identifier-first and
search matches could resolve to a compilation of the same song and
overwrite the file's album, cover, track position, and date with the
compilation's. When the file already knows its album and the candidate's
album doesn't match, those release-scoped fields are now preserved;
recording-level fields (title, artist, ISRC, genre) still enrich.
This commit is contained in:
zarzet
2026-07-14 09:10:14 +07:00
parent 266b08a80d
commit b53146c599
2 changed files with 68 additions and 10 deletions
+29 -8
View File
@@ -74,11 +74,30 @@ func (r *reEnrichRequest) lyricsSidecarEnabled() bool {
return mode == "external" || mode == "both"
}
// reEnrichSameRelease reports whether the candidate track appears to come
// from the same release as the file's existing album. An ISRC identifies a
// recording, not a release: the same song often also resolves to a
// compilation, whose album name, cover, and track positions must not
// replace the original release's.
func reEnrichSameRelease(currentAlbum, candidateAlbum string) bool {
if isPlaceholderReEnrichValue(currentAlbum) ||
strings.TrimSpace(candidateAlbum) == "" {
return true
}
return titlesMatch(currentAlbum, candidateAlbum)
}
func applyReEnrichTrackMetadata(req *reEnrichRequest, track ExtTrackMetadata) {
if req == nil {
return
}
sameRelease := reEnrichSameRelease(req.AlbumName, track.AlbumName)
if !sameRelease {
GoLog("[ReEnrich] Candidate album %q differs from file album %q; keeping release identity (album, cover, positions, date)\n",
track.AlbumName, req.AlbumName)
}
if track.SpotifyID != "" {
req.SpotifyID = track.SpotifyID
} else if track.DeezerID != "" {
@@ -98,14 +117,16 @@ func applyReEnrichTrackMetadata(req *reEnrichRequest, track ExtTrackMetadata) {
if track.Artists != "" {
req.ArtistName = track.Artists
}
if track.AlbumName != "" {
req.AlbumName = track.AlbumName
}
if track.AlbumArtist != "" {
req.AlbumArtist = track.AlbumArtist
if sameRelease {
if track.AlbumName != "" {
req.AlbumName = track.AlbumName
}
if track.AlbumArtist != "" {
req.AlbumArtist = track.AlbumArtist
}
}
}
if req.shouldUpdateField("track_info") {
if sameRelease && req.shouldUpdateField("track_info") {
if track.TrackNumber > 0 {
req.TrackNumber = track.TrackNumber
}
@@ -120,14 +141,14 @@ func applyReEnrichTrackMetadata(req *reEnrichRequest, track ExtTrackMetadata) {
}
}
if req.shouldUpdateField("release_info") {
if track.ReleaseDate != "" {
if sameRelease && track.ReleaseDate != "" {
req.ReleaseDate = track.ReleaseDate
}
if track.ISRC != "" {
req.ISRC = track.ISRC
}
}
if req.shouldUpdateField("cover") {
if sameRelease && req.shouldUpdateField("cover") {
if coverURL := track.ResolvedCoverURL(); coverURL != "" {
req.CoverURL = coverURL
}
+39 -2
View File
@@ -352,7 +352,7 @@ func TestApplyReEnrichTrackMetadataPreservesExistingReleaseDateWhenCandidateMiss
}
applyReEnrichTrackMetadata(&req, ExtTrackMetadata{
AlbumName: "Resolved Album",
AlbumName: "Original Album (Deluxe)",
ReleaseDate: "",
ISRC: "",
})
@@ -360,7 +360,7 @@ func TestApplyReEnrichTrackMetadataPreservesExistingReleaseDateWhenCandidateMiss
if req.ReleaseDate != "2024-01-01" {
t.Fatalf("release date = %q, want existing value preserved", req.ReleaseDate)
}
if req.AlbumName != "Resolved Album" {
if req.AlbumName != "Original Album (Deluxe)" {
t.Fatalf("album = %q, want updated album", req.AlbumName)
}
if req.ISRC != "REQ123" {
@@ -368,6 +368,43 @@ func TestApplyReEnrichTrackMetadataPreservesExistingReleaseDateWhenCandidateMiss
}
}
func TestApplyReEnrichTrackMetadataKeepsReleaseIdentityOnAlbumMismatch(t *testing.T) {
req := reEnrichRequest{
TrackName: "Afsana",
ArtistName: "Artist Name",
AlbumName: "Original Soundtrack",
CoverURL: "https://covers/original.jpg",
TrackNumber: 3,
ReleaseDate: "2005-01-01",
}
applyReEnrichTrackMetadata(&req, ExtTrackMetadata{
Name: "Afsana",
Artists: "Artist Name",
AlbumName: "The Hit Machine",
CoverURL: "https://covers/compilation.jpg",
TrackNumber: 17,
ReleaseDate: "2010-01-01",
ISRC: "NEW123",
})
if req.AlbumName != "Original Soundtrack" {
t.Fatalf("album = %q, want original release kept", req.AlbumName)
}
if req.CoverURL != "https://covers/original.jpg" {
t.Fatalf("cover = %q, want original release cover kept", req.CoverURL)
}
if req.TrackNumber != 3 {
t.Fatalf("track number = %d, want original position kept", req.TrackNumber)
}
if req.ReleaseDate != "2005-01-01" {
t.Fatalf("release date = %q, want original date kept", req.ReleaseDate)
}
if req.ISRC != "NEW123" {
t.Fatalf("isrc = %q, want recording-level fields still enriched", req.ISRC)
}
}
func TestSelectBestReEnrichTrackPrefersCandidateWithReleaseDate(t *testing.T) {
req := reEnrichRequest{
TrackName: "Song Title",