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>
84 lines
1.6 KiB
Go
84 lines
1.6 KiB
Go
package deezer
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"net/url"
|
|
"strconv"
|
|
|
|
"github.com/navidrome/navidrome/log"
|
|
)
|
|
|
|
const apiBaseURL = "https://api.deezer.com"
|
|
|
|
var (
|
|
ErrNotFound = errors.New("deezer: not found")
|
|
)
|
|
|
|
type httpDoer interface {
|
|
Do(req *http.Request) (*http.Response, error)
|
|
}
|
|
|
|
type client struct {
|
|
httpDoer httpDoer
|
|
}
|
|
|
|
func newClient(hc httpDoer) *client {
|
|
return &client{hc}
|
|
}
|
|
|
|
func (c *client) searchArtists(ctx context.Context, name string, limit int) ([]Artist, error) {
|
|
params := url.Values{}
|
|
params.Add("q", name)
|
|
params.Add("limit", strconv.Itoa(limit))
|
|
req, err := http.NewRequestWithContext(ctx, "GET", apiBaseURL+"/search/artist", nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
req.URL.RawQuery = params.Encode()
|
|
|
|
var results SearchArtistResults
|
|
err = c.makeRequest(req, &results)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if len(results.Data) == 0 {
|
|
return nil, ErrNotFound
|
|
}
|
|
return results.Data, nil
|
|
}
|
|
|
|
func (c *client) makeRequest(req *http.Request, response interface{}) error {
|
|
log.Trace(req.Context(), fmt.Sprintf("Sending Deezer %s request", req.Method), "url", req.URL)
|
|
resp, err := c.httpDoer.Do(req)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
defer resp.Body.Close()
|
|
data, err := io.ReadAll(resp.Body)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if resp.StatusCode != 200 {
|
|
return c.parseError(data)
|
|
}
|
|
|
|
return json.Unmarshal(data, response)
|
|
}
|
|
|
|
func (c *client) parseError(data []byte) error {
|
|
var deezerError Error
|
|
err := json.Unmarshal(data, &deezerError)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return fmt.Errorf("deezer error(%d): %s", deezerError.Error.Code, deezerError.Error.Message)
|
|
}
|