mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-09-02 16:20:57 +02:00
fix(metadata): preserve selected release artwork and title
This commit is contained in:
@@ -150,9 +150,9 @@ func buildDownloadSuccessResponse(
|
||||
filePath string,
|
||||
alreadyExists bool,
|
||||
) DownloadResponse {
|
||||
title := result.Title
|
||||
title := strings.TrimSpace(req.TrackName)
|
||||
if title == "" {
|
||||
title = req.TrackName
|
||||
title = strings.TrimSpace(result.Title)
|
||||
}
|
||||
|
||||
artist := result.Artist
|
||||
@@ -207,9 +207,9 @@ func buildDownloadSuccessResponse(
|
||||
upc = req.UPC
|
||||
}
|
||||
|
||||
coverURL := strings.TrimSpace(result.CoverURL)
|
||||
coverURL := strings.TrimSpace(req.CoverURL)
|
||||
if coverURL == "" {
|
||||
coverURL = strings.TrimSpace(req.CoverURL)
|
||||
coverURL = strings.TrimSpace(result.CoverURL)
|
||||
}
|
||||
|
||||
return DownloadResponse{
|
||||
|
||||
@@ -105,9 +105,54 @@ func TestPreferredReleaseMetadataPrefersRequestValues(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildDownloadSuccessResponsePrefersProviderCoverURL(t *testing.T) {
|
||||
func TestBuildDownloadSuccessResponsePreservesRequestedTrackAndCover(t *testing.T) {
|
||||
req := DownloadRequest{
|
||||
TrackName: "Album Track Title",
|
||||
ArtistName: "Artist",
|
||||
AlbumName: "Original Album",
|
||||
AlbumArtist: "Artist",
|
||||
CoverURL: "https://cdn.source.test/original-album.jpg",
|
||||
ISRC: "USAAA2600001",
|
||||
}
|
||||
|
||||
result := DownloadResult{
|
||||
Title: "Single Version Title",
|
||||
Artist: "Artist",
|
||||
Album: "Single Version Title",
|
||||
CoverURL: "https://cdn.provider.test/single.jpg",
|
||||
ISRC: "USAAA2600001",
|
||||
}
|
||||
|
||||
resp := buildDownloadSuccessResponse(
|
||||
req,
|
||||
result,
|
||||
"generic-provider",
|
||||
"ok",
|
||||
"/tmp/test.flac",
|
||||
false,
|
||||
)
|
||||
overlayExtensionDownloadMetadata(&resp, &ExtDownloadResult{
|
||||
Title: result.Title,
|
||||
Artist: result.Artist,
|
||||
Album: result.Album,
|
||||
CoverURL: result.CoverURL,
|
||||
ISRC: result.ISRC,
|
||||
})
|
||||
applyExtensionRequestFallbacks(&resp, req)
|
||||
|
||||
if resp.Title != req.TrackName {
|
||||
t.Fatalf("title = %q, want requested title %q", resp.Title, req.TrackName)
|
||||
}
|
||||
if resp.Album != req.AlbumName {
|
||||
t.Fatalf("album = %q, want requested album %q", resp.Album, req.AlbumName)
|
||||
}
|
||||
if resp.CoverURL != req.CoverURL {
|
||||
t.Fatalf("cover url = %q, want requested album cover %q", resp.CoverURL, req.CoverURL)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildDownloadSuccessResponseFallsBackToProviderTrackAndCover(t *testing.T) {
|
||||
req := DownloadRequest{
|
||||
TrackName: "Track",
|
||||
ArtistName: "Artist",
|
||||
AlbumName: "Album",
|
||||
AlbumArtist: "Artist",
|
||||
@@ -117,20 +162,23 @@ func TestBuildDownloadSuccessResponsePrefersProviderCoverURL(t *testing.T) {
|
||||
Title: "Track",
|
||||
Artist: "Artist",
|
||||
Album: "Album",
|
||||
CoverURL: "https://cdn.qobuz.test/cover.jpg",
|
||||
CoverURL: "https://cdn.provider.test/cover.jpg",
|
||||
}
|
||||
|
||||
resp := buildDownloadSuccessResponse(
|
||||
req,
|
||||
result,
|
||||
"qobuz",
|
||||
"generic-provider",
|
||||
"ok",
|
||||
"/tmp/test.flac",
|
||||
false,
|
||||
)
|
||||
|
||||
if resp.Title != result.Title {
|
||||
t.Fatalf("title = %q, want provider fallback %q", resp.Title, result.Title)
|
||||
}
|
||||
if resp.CoverURL != result.CoverURL {
|
||||
t.Fatalf("cover url = %q, want %q", resp.CoverURL, result.CoverURL)
|
||||
t.Fatalf("cover url = %q, want provider fallback %q", resp.CoverURL, result.CoverURL)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -430,30 +430,7 @@ func DownloadWithExtensionFallback(req DownloadRequest) (*DownloadResponse, erro
|
||||
GoLog("[DownloadWithExtensionFallback] Enriching track from extension '%s'...\n", req.Source)
|
||||
|
||||
provider := newExtensionProviderWrapper(ext)
|
||||
trackMeta := &ExtTrackMetadata{
|
||||
ID: req.SpotifyID,
|
||||
Name: req.TrackName,
|
||||
Artists: req.ArtistName,
|
||||
AlbumName: req.AlbumName,
|
||||
AlbumArtist: req.AlbumArtist,
|
||||
DurationMS: req.DurationMS,
|
||||
CoverURL: req.CoverURL,
|
||||
ISRC: req.ISRC,
|
||||
ReleaseDate: req.ReleaseDate,
|
||||
TrackNumber: req.TrackNumber,
|
||||
TotalTracks: req.TotalTracks,
|
||||
DiscNumber: req.DiscNumber,
|
||||
TotalDiscs: req.TotalDiscs,
|
||||
ProviderID: req.Source,
|
||||
AlbumType: req.AlbumType,
|
||||
Explicit: req.Explicit,
|
||||
UPC: req.UPC,
|
||||
Label: req.Label,
|
||||
Copyright: req.Copyright,
|
||||
Genre: req.Genre,
|
||||
Composer: req.Composer,
|
||||
Comment: req.Comment,
|
||||
}
|
||||
trackMeta := buildSourceExtensionTrackMetadata(req)
|
||||
|
||||
enrichedTrack, err := provider.EnrichTrackForItemID(trackMeta, req.ItemID)
|
||||
if shouldAbortCancelledFallback(req.ItemID, err) {
|
||||
@@ -476,12 +453,7 @@ func DownloadWithExtensionFallback(req DownloadRequest) (*DownloadResponse, erro
|
||||
GoLog("[DownloadWithExtensionFallback] Deezer ID from Odesli: %s\n", enrichedTrack.DeezerID)
|
||||
req.DeezerID = enrichedTrack.DeezerID
|
||||
}
|
||||
if enrichedTrack.Name != "" {
|
||||
req.TrackName = enrichedTrack.Name
|
||||
}
|
||||
if enrichedTrack.Artists != "" {
|
||||
req.ArtistName = enrichedTrack.Artists
|
||||
}
|
||||
overlaySourceExtensionTrackIdentity(&req, *enrichedTrack)
|
||||
overlayStr(&req.AlbumName, enrichedTrack.AlbumName, "AlbumName")
|
||||
overlayStr(&req.AlbumArtist, enrichedTrack.AlbumArtist, "")
|
||||
overlayInt(&req.DurationMS, enrichedTrack.DurationMS, "DurationMS")
|
||||
|
||||
@@ -72,6 +72,49 @@ func trimKnownProviderPrefix(trackID, providerID string) string {
|
||||
return trimmedID
|
||||
}
|
||||
|
||||
func buildSourceExtensionTrackMetadata(req DownloadRequest) *ExtTrackMetadata {
|
||||
return &ExtTrackMetadata{
|
||||
ID: req.SpotifyID,
|
||||
Name: req.TrackName,
|
||||
Artists: req.ArtistName,
|
||||
AlbumName: req.AlbumName,
|
||||
AlbumArtist: req.AlbumArtist,
|
||||
DurationMS: req.DurationMS,
|
||||
CoverURL: req.CoverURL,
|
||||
ISRC: req.ISRC,
|
||||
ReleaseDate: req.ReleaseDate,
|
||||
TrackNumber: req.TrackNumber,
|
||||
TotalTracks: req.TotalTracks,
|
||||
DiscNumber: req.DiscNumber,
|
||||
TotalDiscs: req.TotalDiscs,
|
||||
ProviderID: req.Source,
|
||||
AlbumType: req.AlbumType,
|
||||
Explicit: req.Explicit,
|
||||
UPC: req.UPC,
|
||||
TidalID: req.TidalID,
|
||||
QobuzID: req.QobuzID,
|
||||
DeezerID: req.DeezerID,
|
||||
SpotifyID: req.SpotifyID,
|
||||
Label: req.Label,
|
||||
Copyright: req.Copyright,
|
||||
Genre: req.Genre,
|
||||
Composer: req.Composer,
|
||||
Comment: req.Comment,
|
||||
}
|
||||
}
|
||||
|
||||
func overlaySourceExtensionTrackIdentity(req *DownloadRequest, enrichedTrack ExtTrackMetadata) {
|
||||
if req == nil {
|
||||
return
|
||||
}
|
||||
|
||||
// The queued track describes the release selected by the user. Enrichment
|
||||
// may fill missing identity fields, but must not rename it to another
|
||||
// release's display title or artist spelling.
|
||||
overlayStr(&req.TrackName, enrichedTrack.Name, "TrackName")
|
||||
overlayStr(&req.ArtistName, enrichedTrack.Artists, "ArtistName")
|
||||
}
|
||||
|
||||
func resolvePreferredTrackIDForExtension(ext *loadedExtension, req DownloadRequest, explicitTrackID string) string {
|
||||
candidates := make([]string, 0, 8)
|
||||
appendCandidate := func(value string) {
|
||||
|
||||
@@ -55,3 +55,51 @@ func TestOverlayExtensionReleaseMetadataDoesNotEraseExistingValues(t *testing.T)
|
||||
t.Fatalf("existing release metadata changed: %#v", req)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildSourceExtensionTrackMetadataCarriesKnownIdentifiers(t *testing.T) {
|
||||
req := DownloadRequest{
|
||||
SpotifyID: "source-id",
|
||||
TidalID: "alternate-id-a",
|
||||
QobuzID: "alternate-id-b",
|
||||
DeezerID: "alternate-id-c",
|
||||
}
|
||||
|
||||
track := buildSourceExtensionTrackMetadata(req)
|
||||
if track.ID != req.SpotifyID || track.SpotifyID != req.SpotifyID {
|
||||
t.Fatalf("primary identifier was not propagated: %#v", track)
|
||||
}
|
||||
if track.TidalID != req.TidalID || track.QobuzID != req.QobuzID || track.DeezerID != req.DeezerID {
|
||||
t.Fatalf("alternate identifiers were not propagated: %#v", track)
|
||||
}
|
||||
}
|
||||
|
||||
func TestOverlaySourceExtensionTrackIdentityPreservesRequestedValues(t *testing.T) {
|
||||
req := DownloadRequest{
|
||||
TrackName: "Album Display Title",
|
||||
ArtistName: "Album Artist Credit",
|
||||
}
|
||||
|
||||
overlaySourceExtensionTrackIdentity(&req, ExtTrackMetadata{
|
||||
Name: "Single Display Title",
|
||||
Artists: "Provider Artist Credit",
|
||||
})
|
||||
|
||||
if req.TrackName != "Album Display Title" {
|
||||
t.Fatalf("track name = %q, want requested title", req.TrackName)
|
||||
}
|
||||
if req.ArtistName != "Album Artist Credit" {
|
||||
t.Fatalf("artist name = %q, want requested credit", req.ArtistName)
|
||||
}
|
||||
}
|
||||
|
||||
func TestOverlaySourceExtensionTrackIdentityFillsMissingValues(t *testing.T) {
|
||||
req := DownloadRequest{}
|
||||
overlaySourceExtensionTrackIdentity(&req, ExtTrackMetadata{
|
||||
Name: "Resolved Title",
|
||||
Artists: "Resolved Artist",
|
||||
})
|
||||
|
||||
if req.TrackName != "Resolved Title" || req.ArtistName != "Resolved Artist" {
|
||||
t.Fatalf("missing identity fields were not enriched: %#v", req)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user