diff --git a/go_backend/download_comment_test.go b/go_backend/download_comment_test.go new file mode 100644 index 00000000..f156d5df --- /dev/null +++ b/go_backend/download_comment_test.go @@ -0,0 +1,34 @@ +package gobackend + +import "testing" + +func TestBuildDownloadedFileCommentKeepsSourceLinkAndAddsCredit(t *testing.T) { + const source = "https://music.apple.com/us/album/example/123" + got := buildDownloadedFileComment(source, "https://music.amazon.com/albums/example") + want := source + "\n" + downloadCommentCredit + if got != want { + t.Fatalf("comment = %q, want %q", got, want) + } +} + +func TestBuildDownloadedFileCommentUsesProviderCommentWhenSourceIsEmpty(t *testing.T) { + const provider = "https://music.amazon.com/albums/example" + got := buildDownloadedFileComment("", provider) + want := provider + "\n" + downloadCommentCredit + if got != want { + t.Fatalf("comment = %q, want %q", got, want) + } +} + +func TestBuildDownloadedFileCommentAddsCreditWithoutLink(t *testing.T) { + if got := buildDownloadedFileComment("", ""); got != downloadCommentCredit { + t.Fatalf("comment = %q, want credit only", got) + } +} + +func TestBuildDownloadedFileCommentDoesNotDuplicateCredit(t *testing.T) { + original := "https://example.test/album/1\n" + downloadCommentCredit + if got := buildDownloadedFileComment(original, ""); got != original { + t.Fatalf("credit was duplicated: %q", got) + } +} diff --git a/go_backend/exports_download.go b/go_backend/exports_download.go index bd2b6eeb..ebcee941 100644 --- a/go_backend/exports_download.go +++ b/go_backend/exports_download.go @@ -134,6 +134,24 @@ type DownloadResult struct { RequiresContainerConversion bool } +const downloadCommentCredit = "Downloaded with SpotiFLAC Mobile. Enjoy your music!" + +func buildDownloadedFileComment(sourceComment, providerComment string) string { + comment := strings.TrimSpace(sourceComment) + if comment == "" { + comment = strings.TrimSpace(providerComment) + } + for _, line := range strings.Split(strings.ReplaceAll(comment, "\r\n", "\n"), "\n") { + if strings.EqualFold(strings.TrimSpace(line), downloadCommentCredit) { + return comment + } + } + if comment == "" { + return downloadCommentCredit + } + return comment + "\n" + downloadCommentCredit +} + func buildDownloadSuccessResponse( req DownloadRequest, result DownloadResult, @@ -187,10 +205,7 @@ func buildDownloadSuccessResponse( if composer == "" { composer = req.Composer } - comment := result.Comment - if comment == "" { - comment = req.Comment - } + comment := buildDownloadedFileComment(req.Comment, result.Comment) albumType := result.AlbumType if albumType == "" { diff --git a/go_backend/extension_fallback_metadata_test.go b/go_backend/extension_fallback_metadata_test.go index 7b978c25..4f2780be 100644 --- a/go_backend/extension_fallback_metadata_test.go +++ b/go_backend/extension_fallback_metadata_test.go @@ -34,8 +34,9 @@ func TestOverlayExtensionReleaseMetadataFillsMissingRequestFields(t *testing.T) "song.m4a", false, ) + expectedComment := track.Comment + "\n" + downloadCommentCredit if response.UPC != track.UPC || response.AlbumType != "single" || - !response.Explicit || response.Comment != track.Comment { + !response.Explicit || response.Comment != expectedComment { t.Fatalf("enriched metadata was lost in download response: %#v", response) } } diff --git a/lib/providers/download_queue_provider_embedding.dart b/lib/providers/download_queue_provider_embedding.dart index c28e3b09..53475255 100644 --- a/lib/providers/download_queue_provider_embedding.dart +++ b/lib/providers/download_queue_provider_embedding.dart @@ -528,6 +528,7 @@ extension _DownloadQueueEmbedding on DownloadQueueNotifier { final backendComment = normalizeOptionalString( backendResult['comment']?.toString(), ); + final resolvedComment = backendComment ?? sourceComment; final backendAlbumType = normalizeOptionalString( backendResult['album_type']?.toString(), ); @@ -572,7 +573,7 @@ extension _DownloadQueueEmbedding on DownloadQueueNotifier { (sourceGenre == null && backendGenre != null) || (sourceLabel == null && backendLabel != null) || (sourceCopyright == null && backendCopyright != null) || - (sourceComment == null && backendComment != null) || + resolvedComment != sourceComment || (baseTrack.explicit != true && backendExplicit) || (sourceUpc == null && backendUpc != null); @@ -604,7 +605,7 @@ extension _DownloadQueueEmbedding on DownloadQueueNotifier { genre: sourceGenre ?? backendGenre, label: sourceLabel ?? backendLabel, copyright: sourceCopyright ?? backendCopyright, - comment: sourceComment ?? backendComment, + comment: resolvedComment, source: baseTrack.source, itemType: baseTrack.itemType, audioQuality: baseTrack.audioQuality,