mirror of
https://github.com/navidrome/navidrome.git
synced 2025-07-14 15:41:18 +03:00
* feat(agents): Add Deezer API artist image provider agent * fix(agents): Use proper naming convention of consts * fix(agents): Check if json test data can be read * fix(agents): Use underscores for unused function arguments * fix(agents): Move int literal to deezerArtistSearchLimit const * feat: add Deezer configuration option to disable it. Signed-off-by: Deluan <deluan@navidrome.org> --------- Signed-off-by: Deluan <deluan@navidrome.org> Co-authored-by: Deluan Quintão <deluan@navidrome.org>
98 lines
2.4 KiB
Go
98 lines
2.4 KiB
Go
package deezer
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"net/http"
|
|
"strings"
|
|
|
|
"github.com/navidrome/navidrome/conf"
|
|
"github.com/navidrome/navidrome/consts"
|
|
"github.com/navidrome/navidrome/core/agents"
|
|
"github.com/navidrome/navidrome/log"
|
|
"github.com/navidrome/navidrome/model"
|
|
"github.com/navidrome/navidrome/utils/cache"
|
|
)
|
|
|
|
const deezerAgentName = "deezer"
|
|
const deezerApiPictureXlSize = 1000
|
|
const deezerApiPictureBigSize = 500
|
|
const deezerApiPictureMediumSize = 250
|
|
const deezerApiPictureSmallSize = 56
|
|
const deezerArtistSearchLimit = 50
|
|
|
|
type deezerAgent struct {
|
|
dataStore model.DataStore
|
|
client *client
|
|
}
|
|
|
|
func deezerConstructor(dataStore model.DataStore) agents.Interface {
|
|
agent := &deezerAgent{dataStore: dataStore}
|
|
httpClient := &http.Client{
|
|
Timeout: consts.DefaultHttpClientTimeOut,
|
|
}
|
|
cachedHttpClient := cache.NewHTTPClient(httpClient, consts.DefaultHttpClientTimeOut)
|
|
agent.client = newClient(cachedHttpClient)
|
|
return agent
|
|
}
|
|
|
|
func (s *deezerAgent) AgentName() string {
|
|
return deezerAgentName
|
|
}
|
|
|
|
func (s *deezerAgent) GetArtistImages(ctx context.Context, _, name, _ string) ([]agents.ExternalImage, error) {
|
|
artist, err := s.searchArtist(ctx, name)
|
|
if err != nil {
|
|
if errors.Is(err, agents.ErrNotFound) {
|
|
log.Warn(ctx, "Artist not found in deezer", "artist", name)
|
|
} else {
|
|
log.Error(ctx, "Error calling deezer", "artist", name, err)
|
|
}
|
|
return nil, err
|
|
}
|
|
|
|
var res []agents.ExternalImage
|
|
possibleImages := []struct {
|
|
URL string
|
|
Size int
|
|
}{
|
|
{artist.PictureXl, deezerApiPictureXlSize},
|
|
{artist.PictureBig, deezerApiPictureBigSize},
|
|
{artist.PictureMedium, deezerApiPictureMediumSize},
|
|
{artist.PictureSmall, deezerApiPictureSmallSize},
|
|
}
|
|
for _, imgData := range possibleImages {
|
|
if imgData.URL != "" {
|
|
res = append(res, agents.ExternalImage{
|
|
URL: imgData.URL,
|
|
Size: imgData.Size,
|
|
})
|
|
}
|
|
}
|
|
return res, nil
|
|
}
|
|
|
|
func (s *deezerAgent) searchArtist(ctx context.Context, name string) (*Artist, error) {
|
|
artists, err := s.client.searchArtists(ctx, name, deezerArtistSearchLimit)
|
|
if errors.Is(err, ErrNotFound) || len(artists) == 0 {
|
|
return nil, agents.ErrNotFound
|
|
}
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// If the first one has the same name, that's the one
|
|
if !strings.EqualFold(artists[0].Name, name) {
|
|
return nil, agents.ErrNotFound
|
|
}
|
|
return &artists[0], err
|
|
}
|
|
|
|
func init() {
|
|
conf.AddHook(func() {
|
|
if conf.Server.Deezer.Enabled {
|
|
agents.Register(deezerAgentName, deezerConstructor)
|
|
}
|
|
})
|
|
}
|