2016-03-04 16:08:02 +00:00
|
|
|
package discogs
|
|
|
|
|
|
|
|
import (
|
2018-03-12 16:30:58 +00:00
|
|
|
"encoding/json"
|
2019-06-06 12:18:10 +00:00
|
|
|
"fmt"
|
2018-03-12 16:30:58 +00:00
|
|
|
"io/ioutil"
|
2016-03-04 16:08:02 +00:00
|
|
|
"net/http"
|
2018-03-12 16:30:58 +00:00
|
|
|
"net/url"
|
2016-03-04 16:08:02 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
2018-03-21 18:17:40 +00:00
|
|
|
discogsAPI = "https://api.discogs.com"
|
2016-03-04 16:08:02 +00:00
|
|
|
)
|
|
|
|
|
2018-03-17 20:12:25 +00:00
|
|
|
// Options is a set of options to use discogs API client
|
2018-02-20 15:13:04 +00:00
|
|
|
type Options struct {
|
2020-03-24 10:11:44 +00:00
|
|
|
// Discogs API endpoint (optional).
|
|
|
|
URL string
|
|
|
|
// Currency to use (optional, default is USD).
|
|
|
|
Currency string
|
|
|
|
// UserAgent to to call discogs api with.
|
2018-02-20 15:13:04 +00:00
|
|
|
UserAgent string
|
2020-03-24 10:11:44 +00:00
|
|
|
// Token provided by discogs (optional).
|
|
|
|
Token string
|
2018-02-20 15:13:04 +00:00
|
|
|
}
|
|
|
|
|
2020-06-01 07:08:11 +00:00
|
|
|
// Discogs is an interface for making Discogs API requests.
|
|
|
|
type Discogs interface {
|
2021-02-17 16:26:29 +00:00
|
|
|
CollectionService
|
2020-06-01 07:08:11 +00:00
|
|
|
DatabaseService
|
2021-02-18 14:16:09 +00:00
|
|
|
MarketPlaceService
|
2020-06-01 07:08:11 +00:00
|
|
|
SearchService
|
|
|
|
}
|
|
|
|
|
|
|
|
type discogs struct {
|
2021-02-17 16:26:29 +00:00
|
|
|
CollectionService
|
2020-06-01 07:08:11 +00:00
|
|
|
DatabaseService
|
|
|
|
SearchService
|
2021-02-18 14:16:09 +00:00
|
|
|
MarketPlaceService
|
2016-03-04 16:08:02 +00:00
|
|
|
}
|
|
|
|
|
2018-03-12 16:30:58 +00:00
|
|
|
var header *http.Header
|
|
|
|
|
2020-03-24 10:11:44 +00:00
|
|
|
// New returns a new discogs API client.
|
2020-06-01 07:08:11 +00:00
|
|
|
func New(o *Options) (Discogs, error) {
|
2018-03-12 16:30:58 +00:00
|
|
|
header = &http.Header{}
|
|
|
|
|
|
|
|
if o == nil || o.UserAgent == "" {
|
2018-03-24 13:14:54 +00:00
|
|
|
return nil, ErrUserAgentInvalid
|
2018-02-20 15:13:04 +00:00
|
|
|
}
|
2017-04-25 16:39:32 +00:00
|
|
|
|
2018-03-12 16:30:58 +00:00
|
|
|
header.Add("User-Agent", o.UserAgent)
|
|
|
|
|
2018-02-20 15:13:04 +00:00
|
|
|
cur, err := currency(o.Currency)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
2016-03-04 16:08:02 +00:00
|
|
|
}
|
2018-02-20 15:13:04 +00:00
|
|
|
|
2018-02-20 15:16:34 +00:00
|
|
|
// set token, it's required for some queries like search
|
|
|
|
if o.Token != "" {
|
2018-02-20 16:26:00 +00:00
|
|
|
header.Add("Authorization", "Discogs token="+o.Token)
|
2018-02-20 15:16:34 +00:00
|
|
|
}
|
2018-02-20 15:13:04 +00:00
|
|
|
|
2018-03-12 16:30:58 +00:00
|
|
|
if o.URL == "" {
|
|
|
|
o.URL = discogsAPI
|
|
|
|
}
|
|
|
|
|
2020-06-01 07:08:11 +00:00
|
|
|
return discogs{
|
2021-02-17 16:26:29 +00:00
|
|
|
newCollectionService(o.URL + "/users"),
|
2020-06-01 07:08:11 +00:00
|
|
|
newDatabaseService(o.URL, cur),
|
|
|
|
newSearchService(o.URL + "/database/search"),
|
2021-02-18 14:16:09 +00:00
|
|
|
newMarketPlaceService(o.URL+"/marketplace", cur),
|
2018-02-20 15:13:04 +00:00
|
|
|
}, nil
|
2016-03-04 16:08:02 +00:00
|
|
|
}
|
2017-04-25 16:39:32 +00:00
|
|
|
|
2018-02-20 15:13:04 +00:00
|
|
|
// currency validates currency for marketplace data.
|
2017-04-25 16:39:32 +00:00
|
|
|
// Defaults to the authenticated users currency. Must be one of the following:
|
|
|
|
// USD GBP EUR CAD AUD JPY CHF MXN BRL NZD SEK ZAR
|
2018-02-20 15:13:04 +00:00
|
|
|
func currency(c string) (string, error) {
|
|
|
|
switch c {
|
2017-04-26 12:57:03 +00:00
|
|
|
case "USD", "GBP", "EUR", "CAD", "AUD", "JPY", "CHF", "MXN", "BRL", "NZD", "SEK", "ZAR":
|
2018-02-20 15:13:04 +00:00
|
|
|
return c, nil
|
2018-02-20 17:00:24 +00:00
|
|
|
case "":
|
|
|
|
return "USD", nil
|
2017-04-26 12:57:03 +00:00
|
|
|
default:
|
2018-03-24 13:14:54 +00:00
|
|
|
return "", ErrCurrencyNotSupported
|
2017-04-26 12:57:03 +00:00
|
|
|
}
|
2017-04-25 16:39:32 +00:00
|
|
|
}
|
2018-03-12 16:30:58 +00:00
|
|
|
|
|
|
|
func request(path string, params url.Values, resp interface{}) error {
|
|
|
|
r, err := http.NewRequest("GET", path+"?"+params.Encode(), nil)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
r.Header = *header
|
|
|
|
|
|
|
|
client := &http.Client{}
|
|
|
|
response, err := client.Do(r)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2018-03-12 17:51:06 +00:00
|
|
|
defer response.Body.Close()
|
2018-03-12 16:30:58 +00:00
|
|
|
|
2019-06-06 12:18:10 +00:00
|
|
|
if response.StatusCode != http.StatusOK {
|
|
|
|
switch response.StatusCode {
|
|
|
|
case http.StatusUnauthorized:
|
|
|
|
return ErrUnauthorized
|
2021-12-09 11:38:29 +00:00
|
|
|
case http.StatusTooManyRequests:
|
|
|
|
return ErrTooManyRequests
|
2019-06-06 12:18:10 +00:00
|
|
|
default:
|
|
|
|
return fmt.Errorf("unknown error: %s", response.Status)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-12 16:30:58 +00:00
|
|
|
body, err := ioutil.ReadAll(response.Body)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return json.Unmarshal(body, &resp)
|
|
|
|
}
|