Retry calls to Last.FM without MBIDs when if returns artist invalid (#1138)

* Call Last.FM's getInfo again without mbid when artist is not found

* Call Last.FM's getSimilar again without mbid when artist is not found

* Call Last.FM's getTopTracks again without mbid when artist is not found
This commit is contained in:
Deluan Quintão
2021-05-27 20:53:24 -04:00
committed by GitHub
parent 4e0177ee53
commit 89b12b34be
12 changed files with 288 additions and 112 deletions
+18 -2
View File
@@ -113,6 +113,12 @@ func (l *lastfmAgent) GetTopSongs(id, artistName, mbid string, count int) ([]Son
func (l *lastfmAgent) callArtistGetInfo(name string, mbid string) (*lastfm.Artist, error) {
a, err := l.client.ArtistGetInfo(l.ctx, name, mbid)
lfErr, isLastFMError := err.(*lastfm.Error)
if mbid != "" && (err == nil && a.Name == "[unknown]") || (isLastFMError && lfErr.Code == 6) {
log.Warn(l.ctx, "LastFM/artist.getInfo could not find artist by mbid, trying again", "artist", name, "mbid", mbid)
return l.callArtistGetInfo(name, "")
}
if err != nil {
log.Error(l.ctx, "Error calling LastFM/artist.getInfo", "artist", name, "mbid", mbid, err)
return nil, err
@@ -122,20 +128,30 @@ func (l *lastfmAgent) callArtistGetInfo(name string, mbid string) (*lastfm.Artis
func (l *lastfmAgent) callArtistGetSimilar(name string, mbid string, limit int) ([]lastfm.Artist, error) {
s, err := l.client.ArtistGetSimilar(l.ctx, name, mbid, limit)
lfErr, isLastFMError := err.(*lastfm.Error)
if mbid != "" && (err == nil && s.Attr.Artist == "[unknown]") || (isLastFMError && lfErr.Code == 6) {
log.Warn(l.ctx, "LastFM/artist.getSimilar could not find artist by mbid, trying again", "artist", name, "mbid", mbid)
return l.callArtistGetSimilar(name, "", limit)
}
if err != nil {
log.Error(l.ctx, "Error calling LastFM/artist.getSimilar", "artist", name, "mbid", mbid, err)
return nil, err
}
return s, nil
return s.Artists, nil
}
func (l *lastfmAgent) callArtistGetTopTracks(artistName, mbid string, count int) ([]lastfm.Track, error) {
t, err := l.client.ArtistGetTopTracks(l.ctx, artistName, mbid, count)
lfErr, isLastFMError := err.(*lastfm.Error)
if mbid != "" && (err == nil && t.Attr.Artist == "[unknown]") || (isLastFMError && lfErr.Code == 6) {
log.Warn(l.ctx, "LastFM/artist.getTopTracks could not find artist by mbid, trying again", "artist", artistName, "mbid", mbid)
return l.callArtistGetTopTracks(artistName, "", count)
}
if err != nil {
log.Error(l.ctx, "Error calling LastFM/artist.getTopTracks", "artist", artistName, "mbid", mbid, err)
return nil, err
}
return t, nil
return t.Track, nil
}
func init() {
+171
View File
@@ -2,6 +2,12 @@ package agents
import (
"context"
"errors"
"net/http"
"os"
"github.com/navidrome/navidrome/tests"
"github.com/navidrome/navidrome/utils/lastfm"
"github.com/navidrome/navidrome/conf"
. "github.com/onsi/ginkgo"
@@ -25,4 +31,169 @@ var _ = Describe("lastfmAgent", func() {
Expect(agent.(*lastfmAgent).lang).To(Equal("pt"))
})
})
Describe("GetBiography", func() {
var agent *lastfmAgent
var httpClient *tests.FakeHttpClient
BeforeEach(func() {
httpClient = &tests.FakeHttpClient{}
client := lastfm.NewClient("API_KEY", "pt", httpClient)
agent = lastFMConstructor(context.TODO()).(*lastfmAgent)
agent.client = client
})
It("returns the biography", func() {
f, _ := os.Open("tests/fixtures/lastfm.artist.getinfo.json")
httpClient.Res = http.Response{Body: f, StatusCode: 200}
Expect(agent.GetBiography("123", "U2", "mbid-1234")).To(Equal("U2 é uma das mais importantes bandas de rock de todos os tempos. Formada em 1976 em Dublin, composta por Bono (vocalista e guitarrista), The Edge (guitarrista, pianista e backing vocal), Adam Clayton (baixista), Larry Mullen, Jr. (baterista e percussionista).\n\nDesde a década de 80, U2 é uma das bandas mais populares no mundo. Seus shows são únicos e um verdadeiro festival de efeitos especiais, além de serem um dos que mais arrecadam anualmente. <a href=\"https://www.last.fm/music/U2\">Read more on Last.fm</a>"))
Expect(httpClient.RequestCount).To(Equal(1))
Expect(httpClient.SavedRequest.URL.Query().Get("mbid")).To(Equal("mbid-1234"))
})
It("returns an error if Last.FM call fails", func() {
httpClient.Err = errors.New("error")
_, err := agent.GetBiography("123", "U2", "mbid-1234")
Expect(err).To(HaveOccurred())
Expect(httpClient.RequestCount).To(Equal(1))
Expect(httpClient.SavedRequest.URL.Query().Get("mbid")).To(Equal("mbid-1234"))
})
It("returns an error if Last.FM call returns an error", func() {
f, _ := os.Open("tests/fixtures/lastfm.artist.error3.json")
httpClient.Res = http.Response{Body: f, StatusCode: 200}
_, err := agent.GetBiography("123", "U2", "mbid-1234")
Expect(err).To(HaveOccurred())
Expect(httpClient.RequestCount).To(Equal(1))
Expect(httpClient.SavedRequest.URL.Query().Get("mbid")).To(Equal("mbid-1234"))
})
Context("MBID not existent in Last.FM", func() {
It("calls again when the response is artist == [unknown]", func() {
f, _ := os.Open("tests/fixtures/lastfm.artist.getinfo.unknown.json")
httpClient.Res = http.Response{Body: f, StatusCode: 200}
_, _ = agent.GetBiography("123", "U2", "mbid-1234")
Expect(httpClient.RequestCount).To(Equal(2))
Expect(httpClient.SavedRequest.URL.Query().Get("mbid")).To(BeEmpty())
})
It("calls again when last.fm returns an error 6", func() {
f, _ := os.Open("tests/fixtures/lastfm.artist.error6.json")
httpClient.Res = http.Response{Body: f, StatusCode: 200}
_, _ = agent.GetBiography("123", "U2", "mbid-1234")
Expect(httpClient.RequestCount).To(Equal(2))
Expect(httpClient.SavedRequest.URL.Query().Get("mbid")).To(BeEmpty())
})
})
})
Describe("GetSimilar", func() {
var agent *lastfmAgent
var httpClient *tests.FakeHttpClient
BeforeEach(func() {
httpClient = &tests.FakeHttpClient{}
client := lastfm.NewClient("API_KEY", "pt", httpClient)
agent = lastFMConstructor(context.TODO()).(*lastfmAgent)
agent.client = client
})
It("returns similar artists", func() {
f, _ := os.Open("tests/fixtures/lastfm.artist.getsimilar.json")
httpClient.Res = http.Response{Body: f, StatusCode: 200}
Expect(agent.GetSimilar("123", "U2", "mbid-1234", 2)).To(Equal([]Artist{
{Name: "Passengers", MBID: "e110c11f-1c94-4471-a350-c38f46b29389"},
{Name: "INXS", MBID: "481bf5f9-2e7c-4c44-b08a-05b32bc7c00d"},
}))
Expect(httpClient.RequestCount).To(Equal(1))
Expect(httpClient.SavedRequest.URL.Query().Get("mbid")).To(Equal("mbid-1234"))
})
It("returns an error if Last.FM call fails", func() {
httpClient.Err = errors.New("error")
_, err := agent.GetSimilar("123", "U2", "mbid-1234", 2)
Expect(err).To(HaveOccurred())
Expect(httpClient.RequestCount).To(Equal(1))
Expect(httpClient.SavedRequest.URL.Query().Get("mbid")).To(Equal("mbid-1234"))
})
It("returns an error if Last.FM call returns an error", func() {
f, _ := os.Open("tests/fixtures/lastfm.artist.error3.json")
httpClient.Res = http.Response{Body: f, StatusCode: 200}
_, err := agent.GetSimilar("123", "U2", "mbid-1234", 2)
Expect(err).To(HaveOccurred())
Expect(httpClient.RequestCount).To(Equal(1))
Expect(httpClient.SavedRequest.URL.Query().Get("mbid")).To(Equal("mbid-1234"))
})
Context("MBID not existent in Last.FM", func() {
It("calls again when the response is artist == [unknown]", func() {
f, _ := os.Open("tests/fixtures/lastfm.artist.getsimilar.unknown.json")
httpClient.Res = http.Response{Body: f, StatusCode: 200}
_, _ = agent.GetSimilar("123", "U2", "mbid-1234", 2)
Expect(httpClient.RequestCount).To(Equal(2))
Expect(httpClient.SavedRequest.URL.Query().Get("mbid")).To(BeEmpty())
})
It("calls again when last.fm returns an error 6", func() {
f, _ := os.Open("tests/fixtures/lastfm.artist.error6.json")
httpClient.Res = http.Response{Body: f, StatusCode: 200}
_, _ = agent.GetSimilar("123", "U2", "mbid-1234", 2)
Expect(httpClient.RequestCount).To(Equal(2))
Expect(httpClient.SavedRequest.URL.Query().Get("mbid")).To(BeEmpty())
})
})
})
Describe("GetTopSongs", func() {
var agent *lastfmAgent
var httpClient *tests.FakeHttpClient
BeforeEach(func() {
httpClient = &tests.FakeHttpClient{}
client := lastfm.NewClient("API_KEY", "pt", httpClient)
agent = lastFMConstructor(context.TODO()).(*lastfmAgent)
agent.client = client
})
It("returns top songs", func() {
f, _ := os.Open("tests/fixtures/lastfm.artist.gettoptracks.json")
httpClient.Res = http.Response{Body: f, StatusCode: 200}
Expect(agent.GetTopSongs("123", "U2", "mbid-1234", 2)).To(Equal([]Song{
{Name: "Beautiful Day", MBID: "f7f264d0-a89b-4682-9cd7-a4e7c37637af"},
{Name: "With or Without You", MBID: "6b9a509f-6907-4a6e-9345-2f12da09ba4b"},
}))
Expect(httpClient.RequestCount).To(Equal(1))
Expect(httpClient.SavedRequest.URL.Query().Get("mbid")).To(Equal("mbid-1234"))
})
It("returns an error if Last.FM call fails", func() {
httpClient.Err = errors.New("error")
_, err := agent.GetTopSongs("123", "U2", "mbid-1234", 2)
Expect(err).To(HaveOccurred())
Expect(httpClient.RequestCount).To(Equal(1))
Expect(httpClient.SavedRequest.URL.Query().Get("mbid")).To(Equal("mbid-1234"))
})
It("returns an error if Last.FM call returns an error", func() {
f, _ := os.Open("tests/fixtures/lastfm.artist.error3.json")
httpClient.Res = http.Response{Body: f, StatusCode: 200}
_, err := agent.GetTopSongs("123", "U2", "mbid-1234", 2)
Expect(err).To(HaveOccurred())
Expect(httpClient.RequestCount).To(Equal(1))
Expect(httpClient.SavedRequest.URL.Query().Get("mbid")).To(Equal("mbid-1234"))
})
Context("MBID not existent in Last.FM", func() {
It("calls again when the response is artist == [unknown]", func() {
f, _ := os.Open("tests/fixtures/lastfm.artist.gettoptracks.unknown.json")
httpClient.Res = http.Response{Body: f, StatusCode: 200}
_, _ = agent.GetTopSongs("123", "U2", "mbid-1234", 2)
Expect(httpClient.RequestCount).To(Equal(2))
Expect(httpClient.SavedRequest.URL.Query().Get("mbid")).To(BeEmpty())
})
It("calls again when last.fm returns an error 6", func() {
f, _ := os.Open("tests/fixtures/lastfm.artist.error6.json")
httpClient.Res = http.Response{Body: f, StatusCode: 200}
_, _ = agent.GetTopSongs("123", "U2", "mbid-1234", 2)
Expect(httpClient.RequestCount).To(Equal(2))
Expect(httpClient.SavedRequest.URL.Query().Get("mbid")).To(BeEmpty())
})
})
})
})