Move to interfaces

This commit is contained in:
Artem Piskun 2020-05-31 21:45:30 +03:00 committed by irlndts
parent aa374638bf
commit 9e62844f82
9 changed files with 105 additions and 88 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
examples/

View File

@ -20,7 +20,7 @@ The lib is under MIT but be sure you are familiar with [Discogs API Terms of Use
Install Install
-------- --------
go get -u github.com/irlndts/go-discogs go get github.com/irlndts/go-discogs
Usage Usage
--------- ---------
@ -31,7 +31,7 @@ import "github.com/irlndts/go-discogs"
``` ```
Some requests require authentification (as any user). According to [Discogs](https://www.discogs.com/developers/#page:authentication,header:authentication-discogs-auth-flow), to send requests with Discogs Auth, you have two options: sending your credentials in the query string with key and secret parameters or a [token parameter](https://www.discogs.com/settings/developers). Some requests require authentification (as any user). According to [Discogs](https://www.discogs.com/developers/#page:authentication,header:authentication-discogs-auth-flow), to send requests with Discogs Auth, you have two options: sending your credentials in the query string with key and secret parameters or a [token parameter](https://www.discogs.com/settings/developers).
This is token way example:
```go ```go
client, err := discogs.New(&discogs.Options{ client, err := discogs.New(&discogs.Options{
UserAgent: "Some Name", UserAgent: "Some Name",
@ -43,7 +43,7 @@ client, err := discogs.New(&discogs.Options{
#### Releases #### Releases
```go ```go
release, _ := client.Database.Release(9893847) release, _ := client.Release(9893847)
fmt.Println(release.Artists[0].Name, " - ", release.Title) fmt.Println(release.Artists[0].Name, " - ", release.Title)
// St. Petersburg Ska-Jazz Review - Elephant Riddim // St. Petersburg Ska-Jazz Review - Elephant Riddim
``` ```
@ -82,7 +82,7 @@ type SearchRequest struct {
Example Example
```go ```go
request := discogs.SearchRequest{Artist: "reggaenauts", ReleaseTitle: "river rock", Page: 0, PerPage: 1} request := discogs.SearchRequest{Artist: "reggaenauts", ReleaseTitle: "river rock", Page: 0, PerPage: 1}
search, _ := client.Search.Search(request) search, _ := client.Search(request)
for _, r := range search.Results { for _, r := range search.Results {
fmt.Println(r.Title) fmt.Println(r.Title)

View File

@ -12,20 +12,39 @@ const (
mastersURI = "/masters/" mastersURI = "/masters/"
) )
// DatabaseService ... // DatabaseService is an interface to work with database.
type DatabaseService struct { type DatabaseService interface {
// Artist represents a person in the discogs database.
Artist(artistID int) (*Artist, error)
// ArtistReleases returns a list of releases and masters associated with the artist.
ArtistReleases(artistID int, pagination *Pagination) (*ArtistReleases, error)
// Label returns a label.
Label(labelID int) (*Label, error)
// LabelReleases returns a list of Releases associated with the label.
LabelReleases(labelID int, pagination *Pagination) (*LabelReleases, error)
// Master returns a master release.
Master(masterID int) (*Master, error)
// MasterVersions retrieves a list of all Releases that are versions of this master.
MasterVersions(masterID int, pagination *Pagination) (*MasterVersions, error)
// Release returns release by release's ID.
Release(releaseID int) (*Release, error)
// ReleaseRating retruns community release rating.
ReleaseRating(releaseID int) (*ReleaseRating, error)
}
type databaseService struct {
url string url string
currency string currency string
} }
func newDatabaseService(url string, currency string) *DatabaseService { func newDatabaseService(url string, currency string) DatabaseService {
return &DatabaseService{ return &databaseService{
url: url, url: url,
currency: currency, currency: currency,
} }
} }
// Release serves relesase response from discogs // Release serves relesase response from discogs.
type Release struct { type Release struct {
Title string `json:"title"` Title string `json:"title"`
ID int `json:"id"` ID int `json:"id"`
@ -63,8 +82,7 @@ type Release struct {
Year int `json:"year"` Year int `json:"year"`
} }
// Release returns release by release's ID func (s *databaseService) Release(releaseID int) (*Release, error) {
func (s *DatabaseService) Release(releaseID int) (*Release, error) {
params := url.Values{} params := url.Values{}
params.Set("curr_abbr", s.currency) params.Set("curr_abbr", s.currency)
@ -73,14 +91,13 @@ func (s *DatabaseService) Release(releaseID int) (*Release, error) {
return release, err return release, err
} }
// ReleaseRating serves response for community release rating request // ReleaseRating serves response for community release rating request.
type ReleaseRating struct { type ReleaseRating struct {
ID int `json:"release_id"` ID int `json:"release_id"`
Rating Rating `json:"rating"` Rating Rating `json:"rating"`
} }
// ReleaseRating retruns community release rating func (s *databaseService) ReleaseRating(releaseID int) (*ReleaseRating, error) {
func (s *DatabaseService) ReleaseRating(releaseID int) (*ReleaseRating, error) {
var rating *ReleaseRating var rating *ReleaseRating
err := request(s.url+releasesURI+strconv.Itoa(releaseID)+"/rating", nil, &rating) err := request(s.url+releasesURI+strconv.Itoa(releaseID)+"/rating", nil, &rating)
return rating, err return rating, err
@ -105,8 +122,7 @@ type Artist struct {
DataQuality string `json:"data_quality"` DataQuality string `json:"data_quality"`
} }
// Artist represents a person in the discogs database func (s *databaseService) Artist(artistID int) (*Artist, error) {
func (s *DatabaseService) Artist(artistID int) (*Artist, error) {
var artist *Artist var artist *Artist
err := request(s.url+artistsURI+strconv.Itoa(artistID), nil, &artist) err := request(s.url+artistsURI+strconv.Itoa(artistID), nil, &artist)
return artist, err return artist, err
@ -118,8 +134,7 @@ type ArtistReleases struct {
Releases []ReleaseSource `json:"releases"` Releases []ReleaseSource `json:"releases"`
} }
// ArtistReleases returns a list of releases and masters associated with the artist. func (s *databaseService) ArtistReleases(artistID int, pagination *Pagination) (*ArtistReleases, error) {
func (s *DatabaseService) ArtistReleases(artistID int, pagination *Pagination) (*ArtistReleases, error) {
var releases *ArtistReleases var releases *ArtistReleases
err := request(s.url+artistsURI+strconv.Itoa(artistID)+"/releases", pagination.params(), &releases) err := request(s.url+artistsURI+strconv.Itoa(artistID)+"/releases", pagination.params(), &releases)
return releases, err return releases, err
@ -141,8 +156,7 @@ type Label struct {
DataQuality string `json:"data_quality"` DataQuality string `json:"data_quality"`
} }
// Label returns a label. func (s *databaseService) Label(labelID int) (*Label, error) {
func (s *DatabaseService) Label(labelID int) (*Label, error) {
var label *Label var label *Label
err := request(s.url+labelsURI+strconv.Itoa(labelID), nil, &label) err := request(s.url+labelsURI+strconv.Itoa(labelID), nil, &label)
return label, err return label, err
@ -154,8 +168,7 @@ type LabelReleases struct {
Releases []ReleaseSource `json:"releases"` Releases []ReleaseSource `json:"releases"`
} }
// LabelReleases returns a list of Releases associated with the label. func (s *databaseService) LabelReleases(labelID int, pagination *Pagination) (*LabelReleases, error) {
func (s *DatabaseService) LabelReleases(labelID int, pagination *Pagination) (*LabelReleases, error) {
var releases *LabelReleases var releases *LabelReleases
err := request(s.url+labelsURI+strconv.Itoa(labelID)+"/releases", pagination.params(), &releases) err := request(s.url+labelsURI+strconv.Itoa(labelID)+"/releases", pagination.params(), &releases)
return releases, err return releases, err
@ -187,8 +200,7 @@ type Master struct {
DataQuality string `json:"data_quality"` DataQuality string `json:"data_quality"`
} }
// Master returns a master release func (s *databaseService) Master(masterID int) (*Master, error) {
func (s *DatabaseService) Master(masterID int) (*Master, error) {
var master *Master var master *Master
err := request(s.url+mastersURI+strconv.Itoa(masterID), nil, &master) err := request(s.url+mastersURI+strconv.Itoa(masterID), nil, &master)
return master, err return master, err
@ -200,8 +212,7 @@ type MasterVersions struct {
Versions []Version `json:"versions"` Versions []Version `json:"versions"`
} }
// MasterVersions retrieves a list of all Releases that are versions of this master func (s *databaseService) MasterVersions(masterID int, pagination *Pagination) (*MasterVersions, error) {
func (s *DatabaseService) MasterVersions(masterID int, pagination *Pagination) (*MasterVersions, error) {
var versions *MasterVersions var versions *MasterVersions
err := request(s.url+mastersURI+strconv.Itoa(masterID)+"/versions", pagination.params(), &versions) err := request(s.url+mastersURI+strconv.Itoa(masterID)+"/versions", pagination.params(), &versions)
return versions, err return versions, err

View File

@ -60,7 +60,7 @@ func TestDatabaseServiceRelease(t *testing.T) {
defer ts.Close() defer ts.Close()
d := initDiscogsClient(t, &Options{URL: ts.URL}) d := initDiscogsClient(t, &Options{URL: ts.URL})
release, err := d.Database.Release(8138518) release, err := d.Release(8138518)
if err != nil { if err != nil {
t.Fatalf("failed to get release: %s", err) t.Fatalf("failed to get release: %s", err)
} }
@ -78,7 +78,7 @@ func TestDatabaseServiceMaster(t *testing.T) {
defer ts.Close() defer ts.Close()
d := initDiscogsClient(t, &Options{URL: ts.URL}) d := initDiscogsClient(t, &Options{URL: ts.URL})
master, err := d.Database.Master(718441) master, err := d.Master(718441)
if err != nil { if err != nil {
t.Fatalf("failed to get master: %s", err) t.Fatalf("failed to get master: %s", err)
} }
@ -95,7 +95,7 @@ func TestDatabaseServiceArtist(t *testing.T) {
defer ts.Close() defer ts.Close()
d := initDiscogsClient(t, &Options{URL: ts.URL}) d := initDiscogsClient(t, &Options{URL: ts.URL})
artist, err := d.Database.Artist(38661) artist, err := d.Artist(38661)
if err != nil { if err != nil {
t.Fatalf("failed to get master: %s", err) t.Fatalf("failed to get master: %s", err)
} }

View File

@ -24,16 +24,21 @@ type Options struct {
Token string Token string
} }
// Discogs is a Discogs' client for making Discogs API requests. // Discogs is an interface for making Discogs API requests.
type Discogs struct { type Discogs interface {
Database *DatabaseService DatabaseService
Search *SearchService SearchService
}
type discogs struct {
DatabaseService
SearchService
} }
var header *http.Header var header *http.Header
// New returns a new discogs API client. // New returns a new discogs API client.
func New(o *Options) (*Discogs, error) { func New(o *Options) (Discogs, error) {
header = &http.Header{} header = &http.Header{}
if o == nil || o.UserAgent == "" { if o == nil || o.UserAgent == "" {
@ -56,9 +61,9 @@ func New(o *Options) (*Discogs, error) {
o.URL = discogsAPI o.URL = discogsAPI
} }
return &Discogs{ return discogs{
Database: newDatabaseService(o.URL, cur), newDatabaseService(o.URL, cur),
Search: newSearchService(o.URL + "/database/search"), newSearchService(o.URL + "/database/search"),
}, nil }, nil
} }

View File

@ -5,11 +5,11 @@ import (
) )
const ( const (
testUserAgent = "UnitTestClient/0.0.2 +https://github.com/irlndts/go-discogs" testUserAgent = "UnitTestClient/0.0.2"
testToken = "" testToken = ""
) )
func initDiscogsClient(t *testing.T, options *Options) *Discogs { func initDiscogsClient(t *testing.T, options *Options) Discogs {
if options == nil { if options == nil {
options = &Options{ options = &Options{
UserAgent: testUserAgent, UserAgent: testUserAgent,
@ -66,19 +66,19 @@ func TestCurrency(t *testing.T) {
want string want string
err error err error
}{ }{
{currency: "", want: "USD", err: nil}, {currency: "", want: "USD"},
{currency: "USD", want: "USD", err: nil}, {currency: "USD", want: "USD"},
{currency: "GBP", want: "GBP", err: nil}, {currency: "GBP", want: "GBP"},
{currency: "EUR", want: "EUR", err: nil}, {currency: "EUR", want: "EUR"},
{currency: "CAD", want: "CAD", err: nil}, {currency: "CAD", want: "CAD"},
{currency: "AUD", want: "AUD", err: nil}, {currency: "AUD", want: "AUD"},
{currency: "JPY", want: "JPY", err: nil}, {currency: "JPY", want: "JPY"},
{currency: "CHF", want: "CHF", err: nil}, {currency: "CHF", want: "CHF"},
{currency: "MXN", want: "MXN", err: nil}, {currency: "MXN", want: "MXN"},
{currency: "BRL", want: "BRL", err: nil}, {currency: "BRL", want: "BRL"},
{currency: "NZD", want: "NZD", err: nil}, {currency: "NZD", want: "NZD"},
{currency: "SEK", want: "SEK", err: nil}, {currency: "SEK", want: "SEK"},
{currency: "ZAR", want: "ZAR", err: nil}, {currency: "ZAR", want: "ZAR"},
{currency: "RUR", want: "", err: ErrCurrencyNotSupported}, {currency: "RUR", want: "", err: ErrCurrencyNotSupported},
} }
for i, tt := range tests { for i, tt := range tests {

21
doc.go Normal file
View File

@ -0,0 +1,21 @@
/*
Package discogs is a Go client library for the Discogs API.
The discogs package provides a client for accessing the Discogs API.
First of all import library and init client variable.
According to discogs api documentation you must provide your user-agent.
Some requests require authentification (as any user).
According to Discogs, to send requests with Discogs Auth, you have two options:
sending your credentials in the query string with key and secret parameters or
a token parameter. This is token way example:
client, err := discogs.New(&discogs.Options{
UserAgent: "Some Name",
Currency: "EUR", // optional, "USD" (default), "GBP", "EUR", "CAD", "AUD", "JPY", "CHF", "MXN", "BRL", "NZD", "SEK", "ZAR" are allowed
Token: "Some Token", // optional
URL: "https://api.discogs.com", // optional
})
*/
package discogs

View File

@ -1,26 +0,0 @@
package main
import (
"fmt"
"github.com/irlndts/go-discogs"
)
func main() {
d, err := discogs.New(&discogs.Options{
UserAgent: "TestDiscogsClient/0.0.1 +http://example.com",
Currency: "USD",
Token: "",
})
if err != nil {
fmt.Println(err)
return
}
master, err := d.Database.Master(718441)
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("%+v\n", master)
}

View File

@ -5,13 +5,22 @@ import (
"strconv" "strconv"
) )
// SearchService ... // SearchService is an interface to work with search.
type SearchService struct { type SearchService interface {
// Search makes search request to discogs.
// Issue a search query to database. This endpoint accepts pagination parameters.
// Authentication (as any user) is required.
// https://www.discogs.com/developers/#page:database,header:database-search
Search(req SearchRequest) (*Search, error)
}
// searchService ...
type searchService struct {
url string url string
} }
func newSearchService(url string) *SearchService { func newSearchService(url string) SearchService {
return &SearchService{ return &searchService{
url: url, url: url,
} }
} }
@ -136,11 +145,7 @@ type Result struct {
MasterID int `json:"master_id,omitempty"` MasterID int `json:"master_id,omitempty"`
} }
// Search makes search request to discogs. func (s *searchService) Search(req SearchRequest) (*Search, error) {
// Issue a search query to our database. This endpoint accepts pagination parameters.
// Authentication (as any user) is required.
// https://www.discogs.com/developers/#page:database,header:database-search
func (s *SearchService) Search(req SearchRequest) (*Search, error) {
var search *Search var search *Search
err := request(s.url, req.params(), &search) err := request(s.url, req.params(), &search)
return search, err return search, err