mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-08-26 21:02:28 +02:00
fix(download): accept matching tracks across releases
This commit is contained in:
@@ -369,10 +369,52 @@ type resolvedTrackInfo struct {
|
||||
SkipNameVerification bool
|
||||
}
|
||||
|
||||
func exactLooseIdentityMatch(expected, found string, normalize func(string) string) bool {
|
||||
normExpected := normalize(expected)
|
||||
normFound := normalize(found)
|
||||
if normExpected != "" && normFound != "" {
|
||||
return normExpected == normFound
|
||||
}
|
||||
return strings.EqualFold(strings.TrimSpace(expected), strings.TrimSpace(found))
|
||||
}
|
||||
|
||||
func durationMatchesRequest(req DownloadRequest, resolved resolvedTrackInfo) bool {
|
||||
expectedDurationSec := req.DurationMS / 1000
|
||||
if expectedDurationSec <= 0 || resolved.Duration <= 0 {
|
||||
return false
|
||||
}
|
||||
diff := expectedDurationSec - resolved.Duration
|
||||
if diff < 0 {
|
||||
diff = -diff
|
||||
}
|
||||
return diff <= 10
|
||||
}
|
||||
|
||||
func hasStrongTrackIdentity(req DownloadRequest, resolved resolvedTrackInfo) bool {
|
||||
if req.TrackName == "" || resolved.Title == "" ||
|
||||
req.ArtistName == "" || resolved.ArtistName == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
titleExact := exactLooseIdentityMatch(req.TrackName, resolved.Title, normalizeLooseTitle)
|
||||
if !titleExact {
|
||||
return false
|
||||
}
|
||||
|
||||
artistExact := exactLooseIdentityMatch(
|
||||
req.ArtistName,
|
||||
resolved.ArtistName,
|
||||
normalizeLooseArtistName,
|
||||
)
|
||||
return artistExact || (artistsMatch(req.ArtistName, resolved.ArtistName) &&
|
||||
durationMatchesRequest(req, resolved))
|
||||
}
|
||||
|
||||
func trackMatchesRequest(req DownloadRequest, resolved resolvedTrackInfo, logPrefix string) bool {
|
||||
exactISRCMatch := req.ISRC != "" &&
|
||||
resolved.ISRC != "" &&
|
||||
strings.EqualFold(strings.TrimSpace(req.ISRC), strings.TrimSpace(resolved.ISRC))
|
||||
conflictingISRC := req.ISRC != "" && resolved.ISRC != "" && !exactISRCMatch
|
||||
|
||||
if !exactISRCMatch && !resolved.SkipNameVerification {
|
||||
if req.ArtistName != "" && resolved.ArtistName != "" &&
|
||||
@@ -391,9 +433,13 @@ func trackMatchesRequest(req DownloadRequest, resolved resolvedTrackInfo, logPre
|
||||
|
||||
if req.AlbumName != "" && resolved.AlbumName != "" &&
|
||||
!titlesMatch(req.AlbumName, resolved.AlbumName) {
|
||||
GoLog("[%s] Verification failed: album mismatch — expected '%s', got '%s'\n",
|
||||
if conflictingISRC || !hasStrongTrackIdentity(req, resolved) {
|
||||
GoLog("[%s] Verification failed: album mismatch — expected '%s', got '%s'\n",
|
||||
logPrefix, req.AlbumName, resolved.AlbumName)
|
||||
return false
|
||||
}
|
||||
GoLog("[%s] Verification accepted album mismatch for matching track identity — expected '%s', got '%s'\n",
|
||||
logPrefix, req.AlbumName, resolved.AlbumName)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -91,6 +91,80 @@ func TestTrackMatchesRequestAcceptsDifferentEditionWithExactISRC(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestTrackMatchesRequestAcceptsSameTrackFromDifferentRelease(t *testing.T) {
|
||||
req := DownloadRequest{
|
||||
TrackName: "Crossing Field",
|
||||
ArtistName: "LiSA",
|
||||
AlbumName: "Crossing Field - EP",
|
||||
DurationMS: 233000,
|
||||
}
|
||||
resolved := resolvedTrackInfo{
|
||||
Title: "Crossing Field",
|
||||
ArtistName: "LiSA",
|
||||
AlbumName: "LANDSPACE",
|
||||
Duration: 233,
|
||||
}
|
||||
|
||||
if !trackMatchesRequest(req, resolved, "test") {
|
||||
t.Fatal("expected the same track to be accepted across release albums")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTrackMatchesRequestRejectsAlbumMismatchForDifferentVersion(t *testing.T) {
|
||||
req := DownloadRequest{
|
||||
TrackName: "Song (Live)",
|
||||
ArtistName: "Artist",
|
||||
AlbumName: "Live at the Theatre",
|
||||
}
|
||||
resolved := resolvedTrackInfo{
|
||||
Title: "Song",
|
||||
ArtistName: "Artist",
|
||||
AlbumName: "Studio Album",
|
||||
}
|
||||
|
||||
if trackMatchesRequest(req, resolved, "test") {
|
||||
t.Fatal("expected an album mismatch to reject a different track version")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTrackMatchesRequestRejectsConflictingISRCDespiteStrongNames(t *testing.T) {
|
||||
req := DownloadRequest{
|
||||
TrackName: "Song",
|
||||
ArtistName: "Artist",
|
||||
AlbumName: "Original Album",
|
||||
ISRC: "USAAA2600001",
|
||||
}
|
||||
resolved := resolvedTrackInfo{
|
||||
Title: "Song",
|
||||
ArtistName: "Artist",
|
||||
AlbumName: "Other Album",
|
||||
ISRC: "USAAA2600002",
|
||||
}
|
||||
|
||||
if trackMatchesRequest(req, resolved, "test") {
|
||||
t.Fatal("expected conflicting ISRCs to keep album verification strict")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTrackMatchesRequestRejectsDurationMismatchAcrossReleases(t *testing.T) {
|
||||
req := DownloadRequest{
|
||||
TrackName: "Crossing Field",
|
||||
ArtistName: "LiSA",
|
||||
AlbumName: "Crossing Field - EP",
|
||||
DurationMS: 233000,
|
||||
}
|
||||
resolved := resolvedTrackInfo{
|
||||
Title: "Crossing Field",
|
||||
ArtistName: "LiSA",
|
||||
AlbumName: "LANDSPACE",
|
||||
Duration: 280,
|
||||
}
|
||||
|
||||
if trackMatchesRequest(req, resolved, "test") {
|
||||
t.Fatal("expected a large duration mismatch to reject another recording")
|
||||
}
|
||||
}
|
||||
|
||||
func TestTitlesMatch_SeparatorVariants(t *testing.T) {
|
||||
if !titlesMatch("Doctor / Cops", "Doctor _ Cops") {
|
||||
t.Fatal("expected tidal titlesMatch to accept / vs _ variant")
|
||||
|
||||
Reference in New Issue
Block a user