diff --git a/spotify.go b/spotify.go index 20cec67..ef9b862 100644 --- a/spotify.go +++ b/spotify.go @@ -116,8 +116,8 @@ func isValidSpotifyID(id string) bool { // resolveSpotifyURL resolves a direct Spotify track URL via ListenBrainz Labs, // falling back to a search URL. Results are cached. func resolveSpotifyURL(track scrobbler.TrackInfo) string { - primary, _ := parsePrimaryArtist(track.Artist) - if primary == "" && len(track.Artists) > 0 { + var primary string + if len(track.Artists) > 0 { primary = track.Artists[0].Name } @@ -159,28 +159,3 @@ func resolveSpotifyURL(track scrobbler.TrackInfo) string { pdk.Log(pdk.LogInfo, fmt.Sprintf("Spotify resolution missed, falling back to search URL for %q - %q: %s", primary, track.Title, searchURL)) return searchURL } - -// parsePrimaryArtist returns the primary artist (before "Feat." / "Ft." / "Featuring") -// and the optional feat suffix. For artist resolution, only the primary artist is used; -// co-artists identified by "Feat.", "Ft.", "Featuring", "&", or "/" are stripped. -func parsePrimaryArtist(artist string) (primary, featSuffix string) { - artist = strings.TrimSpace(artist) - if artist == "" { - return "", "" - } - lower := strings.ToLower(artist) - for _, sep := range []string{" feat. ", " ft. ", " featuring "} { - if i := strings.Index(lower, sep); i >= 0 { - primary = strings.TrimSpace(artist[:i]) - featSuffix = strings.TrimSpace(artist[i:]) - return primary, featSuffix - } - } - // Split on co-artist separators; take only the first artist. - for _, sep := range []string{" & ", " / "} { - if i := strings.Index(artist, sep); i >= 0 { - return strings.TrimSpace(artist[:i]), "" - } - } - return artist, "" -} diff --git a/spotify_test.go b/spotify_test.go index 99719ec..73e9dc3 100644 --- a/spotify_test.go +++ b/spotify_test.go @@ -14,23 +14,6 @@ import ( ) var _ = Describe("Spotify", func() { - Describe("parsePrimaryArtist", func() { - DescribeTable("extracts primary artist and feat suffix", - func(input, expectedPrimary, expectedFeat string) { - primary, feat := parsePrimaryArtist(input) - Expect(primary).To(Equal(expectedPrimary)) - Expect(feat).To(Equal(expectedFeat)) - }, - Entry("simple artist", "Radiohead", "Radiohead", ""), - Entry("Feat. separator", "Wretch 32 Feat. Badness & Ghetts", "Wretch 32", "Feat. Badness & Ghetts"), - Entry("Ft. separator", "Artist Ft. Guest", "Artist", "Ft. Guest"), - Entry("Featuring separator", "Artist Featuring Someone", "Artist", "Featuring Someone"), - Entry("& co-artist", "PinkPantheress & Ice Spice", "PinkPantheress", ""), - Entry("/ co-artist", "Artist A / Artist B", "Artist A", ""), - Entry("empty string", "", "", ""), - ) - }) - Describe("spotifySearchURL", func() { DescribeTable("constructs Spotify search URL", func(expectedURL string, terms ...string) { @@ -142,9 +125,10 @@ var _ = Describe("Spotify", func() { host.CacheMock.On("GetString", spotifyURLKey).Return("https://open.spotify.com/track/cached123", true, nil) url := resolveSpotifyURL(scrobbler.TrackInfo{ - Title: "Karma Police", - Artist: "Radiohead", - Album: "OK Computer", + Title: "Karma Police", + Artist: "Radiohead", + Artists: []scrobbler.ArtistRef{{Name: "Radiohead"}}, + Album: "OK Computer", }) Expect(url).To(Equal("https://open.spotify.com/track/cached123")) }) @@ -162,6 +146,7 @@ var _ = Describe("Spotify", func() { url := resolveSpotifyURL(scrobbler.TrackInfo{ Title: "Karma Police", Artist: "Radiohead", + Artists: []scrobbler.ArtistRef{{Name: "Radiohead"}}, Album: "OK Computer", MBZRecordingID: "mbid-123", }) @@ -187,6 +172,7 @@ var _ = Describe("Spotify", func() { url := resolveSpotifyURL(scrobbler.TrackInfo{ Title: "Karma Police", Artist: "Radiohead", + Artists: []scrobbler.ArtistRef{{Name: "Radiohead"}}, Album: "OK Computer", MBZRecordingID: "mbid-123", }) @@ -203,16 +189,17 @@ var _ = Describe("Spotify", func() { pdk.PDKMock.On("Send", metaReq).Return(pdk.NewStubHTTPResponse(500, nil, []byte(`error`))) url := resolveSpotifyURL(scrobbler.TrackInfo{ - Title: "Karma Police", - Artist: "Radiohead", - Album: "OK Computer", + Title: "Karma Police", + Artist: "Radiohead", + Artists: []scrobbler.ArtistRef{{Name: "Radiohead"}}, + Album: "OK Computer", }) Expect(url).To(HavePrefix("https://open.spotify.com/search/")) Expect(url).To(ContainSubstring("Radiohead")) host.CacheMock.AssertCalled(GinkgoT(), "SetString", spotifyURLKey, mock.Anything, spotifyCacheTTLMiss) }) - It("uses Artists fallback when primary artist parse is empty", func() { + It("uses Artists[0] for primary artist", func() { host.CacheMock.On("GetString", spotifyURLKey).Return("", false, nil) host.CacheMock.On("SetString", spotifyURLKey, mock.Anything, mock.Anything).Return(nil)