Skip to content

Commit 8e0360e

Browse files
committed
Fix buggy Last.FM by falling back to artist search
1 parent 9ff97e8 commit 8e0360e

File tree

2 files changed

+38
-6
lines changed

2 files changed

+38
-6
lines changed

api/service.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package api
22

33
import (
44
"errors"
5+
"fmt"
56
"time"
67

78
"github.com/go-kit/kit/log"
@@ -138,22 +139,31 @@ func (s *service) GenerateTaste(username string, period string, limit int) ([]la
138139
if err != nil {
139140
// If we don't have it in our store we get the unique top tag for the first 4 artists
140141
start = time.Now()
141-
tt, err := s.client.GetTopTags(ta.Mbid)
142+
143+
// We try to get the top tags by mbid, but if this doesn't work because of the Last.FM bug we fallback to the artist name:
144+
// https://www.reddit.com/r/lastfm/comments/1g9suo3/api_problem/
145+
tt, err := s.client.GetTopTags(ta.Mbid, ta.Name)
142146
fetchDurationHistogram.WithLabelValues(period, "get_top_tags").Observe(time.Since(start).Seconds())
143147
cacheMissTotalCounter.Add(1)
144148
if err != nil {
145149
s.l.Log("err", err)
146150
continue
147151
}
152+
// If we don't get any top tags, we just append the artist without tags
148153
if len(tt) > 1 {
149154
ta.Genre = tt[0]
150155
if _, ok := m[ta.Genre]; !ok {
151156
al = append(al, ta)
152157
m[ta.Genre] = struct{}{}
153158
}
154159
// We store the newly fetched information in our storage backend so we don't have to fetch it again for the next user
155-
s.storageRepository.Save(ta.Mbid, tt[0])
160+
if err := s.storageRepository.Save(ta.Mbid, tt[0]); err != nil {
161+
s.l.Log("msg", fmt.Sprintf("failed to save artist key: %s,", err), "backend", s.cfg.StorageBackend)
162+
}
163+
} else {
164+
al = append(al, ta)
156165
}
166+
157167
continue
158168
}
159169
cacheHitTotalCounter.Add(1)

client/lastfm/lastfm.go

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"errors"
66
"fmt"
77
"net/http"
8+
"net/url"
89
)
910

1011
// Client contains everything needed for a Last.FM client
@@ -76,7 +77,8 @@ type TopArtist struct {
7677

7778
// GetTopArtists gets the top artist of a user from Last.FM
7879
func (c *Client) GetTopArtists(username string, period string, limit int) ([]TopArtist, error) {
79-
req, err := http.NewRequest("GET", fmt.Sprintf("http://ws.audioscrobbler.com/2.0/?method=user.gettopartists&user=%s&api_key=%s&format=json&period=%s&limit=%d", username, c.APIKey, period, limit), nil)
80+
call := fmt.Sprintf("http://ws.audioscrobbler.com/2.0/?method=user.gettopartists&user=%s&api_key=%s&format=json&period=%s&limit=%d", username, c.APIKey, period, limit)
81+
req, err := http.NewRequest("GET", call, nil)
8082
if err != nil {
8183
return nil, err
8284
}
@@ -146,9 +148,29 @@ func (c *Client) GetWeeklyArtistChart(username string, from, to int64, limit int
146148
return tal, nil
147149
}
148150

149-
// GetTopTags gets the top tags for an artist from the Last.FM API
150-
func (c *Client) GetTopTags(mbid string) ([]string, error) {
151-
req, err := http.NewRequest("GET", fmt.Sprintf("http://ws.audioscrobbler.com/2.0/?method=artist.gettoptags&mbid=%s&api_key=%s&format=json", mbid, c.APIKey), nil)
151+
// GetTopTags gets the top tags for an artist from the Last.FM API by mbid, or artist as a fallback
152+
func (c *Client) GetTopTags(mbid string, artist string) ([]string, error) {
153+
if mbid == "" {
154+
return c.getTopTags("artist", artist)
155+
}
156+
return c.getTopTags("mbid", mbid)
157+
}
158+
159+
func (c *Client) getTopTags(by string, value string) ([]string, error) {
160+
call := fmt.Sprintf("http://ws.audioscrobbler.com/2.0/?method=artist.gettoptags&api_key=%s&format=json", c.APIKey)
161+
u, err := url.Parse(call)
162+
if err != nil {
163+
return nil, err
164+
}
165+
q := u.Query()
166+
switch by {
167+
case "mbid":
168+
q.Add("mbid", value)
169+
default:
170+
q.Add("artist", value)
171+
}
172+
u.RawQuery = q.Encode()
173+
req, err := http.NewRequest("GET", u.String(), nil)
152174
if err != nil {
153175
return nil, err
154176
}

0 commit comments

Comments
 (0)