Merge pull request #6 from irlndts/Rewrite

Improvement and Rating
This commit is contained in:
Artem Piskun 2018-03-12 20:00:30 +03:00 committed by GitHub
commit 8d359bb193
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 168 additions and 144 deletions

View File

@ -28,17 +28,17 @@ 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: This is token way example:
```go ```go
client := discogs.NewClient().UserAgent("TestDiscogsClient/0.0.1 +example.com").Token("Some Token") client, err := discogs.NewClient(&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",
})
``` ```
Don't forget to set required currency ("USD", "GBP", "EUR", "CAD", "AUD", "JPY", "CHF", "MXN", "BRL", "NZD", "SEK", "ZAR" are allowed):
```go
err := client.Currency("EUR");
```
#### Releases #### Releases
```go ```go
release, err := client.Release(9893847) release, err := client.Release.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
``` ```

View File

@ -1,26 +0,0 @@
package discogs
import (
"fmt"
"testing"
)
func TestArtistService_Artist(t *testing.T) {
expectedId := 1000
d := NewClient(testUserAgent, testToken)
artist, _, err := d.Artist.Artist(&ArtistParams{Artist_id: "1000"})
check(t, err)
assert(t, artist.Id == expectedId, fmt.Sprintf("Release.Title looked for %s, and received %s ", expectedId, artist.Id))
}
func TestArtistService_Releases(t *testing.T) {
expectedArtist := "Dave Clarke"
d := NewClient(testUserAgent, testToken)
releases, _, err := d.Artist.Releases(&ArtistParams{Artist_id: "1000", Sort: "year", Sort_order: "desc"})
check(t, err)
assert(t, releases.Releases[0].Artist == expectedArtist, fmt.Sprintf("Releses.Artist looked for %s, and received %s ", expectedArtist, releases.Releases[0].Artist))
}

View File

@ -1,8 +1,11 @@
package discogs package discogs
import ( import (
"encoding/json"
"fmt" "fmt"
"io/ioutil"
"net/http" "net/http"
"net/url"
"github.com/irlndts/go-apirequest" "github.com/irlndts/go-apirequest"
) )
@ -11,53 +14,91 @@ const (
discogsAPI = "https://api.discogs.com/" discogsAPI = "https://api.discogs.com/"
) )
type Options struct {
URL string
Currency string
UserAgent string
Token string
}
// Client is a Discogs client for making Discogs API requests. // Client is a Discogs client for making Discogs API requests.
type Client struct { type Client struct {
api *apirequest.API Release *ReleaseService
currency string Master *MasterService
Master *MasterService Artist *ArtistService
Artist *ArtistService Label *LabelService
Label *LabelService Search *SearchService
Search *SearchService
} }
var header *http.Header
// NewClient returns a new Client. // NewClient returns a new Client.
func NewClient() *Client { func NewClient(o *Options) (*Client, error) {
header = &http.Header{}
base := apirequest.New().Client(&http.Client{}).Base(discogsAPI) base := apirequest.New().Client(&http.Client{}).Base(discogsAPI)
return &Client{
api: base,
currency: "USD",
Artist: newArtistService(base.New()), if o == nil || o.UserAgent == "" {
Label: newLabelService(base.New()), return nil, fmt.Errorf("failed to set user-agent")
Master: newMasterService(base.New()),
Search: newSearchService(base.New()),
} }
base.Set("User-Agent", o.UserAgent)
header.Add("User-Agent", o.UserAgent)
cur, err := currency(o.Currency)
if err != nil {
return nil, err
}
// set token, it's required for some queries like search
if o.Token != "" {
base.Set("Authorization", "Discogs token="+o.Token)
header.Add("Authorization", "Discogs token="+o.Token)
}
if o.URL == "" {
o.URL = discogsAPI
}
return &Client{
Release: newReleaseService(o.URL+"/releases/", cur),
Artist: newArtistService(base.New()),
Label: newLabelService(base.New()),
Master: newMasterService(base.New()),
Search: newSearchService(base.New()),
}, nil
} }
// Token sets tokens, it's required for some queries like search // currency validates currency for marketplace data.
func (c *Client) Token(token string) *Client {
c.api.Set("Authorization", "Discogs token="+token)
return c
}
// UserAgent sets specified user agent
// Discogs requires it
func (c *Client) UserAgent(useragent string) *Client {
c.api.Set("User-Agent", useragent)
return c
}
// SetCurrency determines currency for marketplace data.
// Defaults to the authenticated users currency. Must be one of the following: // Defaults to the authenticated users currency. Must be one of the following:
// USD GBP EUR CAD AUD JPY CHF MXN BRL NZD SEK ZAR // USD GBP EUR CAD AUD JPY CHF MXN BRL NZD SEK ZAR
func (c *Client) Currency(currency string) error { func currency(c string) (string, error) {
switch currency { switch c {
case "USD", "GBP", "EUR", "CAD", "AUD", "JPY", "CHF", "MXN", "BRL", "NZD", "SEK", "ZAR": case "USD", "GBP", "EUR", "CAD", "AUD", "JPY", "CHF", "MXN", "BRL", "NZD", "SEK", "ZAR":
c.currency = currency return c, nil
case "":
return "USD", nil
default: default:
return fmt.Errorf("%v\n", "Invalid currency abbreviation.") return "", fmt.Errorf("%v\n", "Invalid currency abbreviation.")
}
}
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
} }
return nil body, err := ioutil.ReadAll(response.Body)
if err != nil {
return err
}
return json.Unmarshal(body, &resp)
} }

View File

@ -9,14 +9,23 @@ const (
testToken = "" testToken = ""
) )
func check(t *testing.T, e error) { func initDiscogsClient(t *testing.T, options *Options) *Client {
if e != nil { if options == nil {
t.Error(e) options = &Options{
UserAgent: testUserAgent,
Currency: "USD",
Token: testToken,
}
} }
}
func assert(t *testing.T, condition bool, assertion string) { if options.UserAgent == "" {
if !condition { options.UserAgent = testUserAgent
t.Errorf("Assertion failed: %v", assertion)
} }
client, err := NewClient(options)
if err != nil {
t.Fatalf("failed to create client: %s", err)
}
return client
} }

View File

@ -7,13 +7,17 @@ import (
) )
func main() { func main() {
d := discogs.NewClient().UserAgent("TestDiscogsClient/0.0.1 +http://example.com") d, err := discogs.NewClient(&discogs.Options{
if err := d.Currency("EUR"); err != nil { UserAgent: "TestDiscogsClient/0.0.1 +http://example.com",
Currency: "EUR",
Token: "",
})
if err != nil {
fmt.Println(err) fmt.Println(err)
return return
} }
release, err := d.Release(9893847) release, err := d.Release.Rating(9893847)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
return return

View File

@ -1,26 +0,0 @@
package discogs
import (
"fmt"
"testing"
)
func TestLabelService_Label(t *testing.T) {
expectedId := 1000
d := NewClient(testUserAgent, testToken)
label, _, err := d.Label.Label(&LabelParams{Label_id: "1000"})
check(t, err)
assert(t, label.Id == expectedId, fmt.Sprintf("Release.Title looked for %s, and received %s ", expectedId, label.Id))
}
func TestLabelService_Releases(t *testing.T) {
expectedId := "Ghetto Sol"
d := NewClient(testUserAgent, testToken)
label, _, err := d.Label.Releases(&LabelParams{Label_id: "1000"})
check(t, err)
assert(t, label.Releases[0].Title == expectedId, fmt.Sprintf("Release.Title looked for %s, and received %s ", expectedId, label.Releases[0].Title))
}

View File

@ -1,26 +0,0 @@
package discogs
import (
"fmt"
"testing"
)
func TestMasterService_Master(t *testing.T) {
expectedTitle := "Elephant Riddim"
d := NewClient(testUserAgent, testToken)
master, _, err := d.Master.Master(&MasterParams{Master_id: "960657"})
check(t, err)
assert(t, master.Title == expectedTitle, fmt.Sprintf("master.Title looked for %s, and received %s ", expectedTitle, master.Title))
}
func TestMasterService_Versions(t *testing.T) {
expectedTitle := "Stardiver"
d := NewClient(testUserAgent, testToken)
versions, _, err := d.Master.Versions(&MasterVersionParams{Master_id: "1000", Page: 1, Per_page: 1})
check(t, err)
assert(t, versions.Versions[0].Title == expectedTitle, fmt.Sprintf("master.Title looked for %s, and received %s ", expectedTitle, versions.Versions[0].Title))
}

View File

@ -1,9 +1,28 @@
package discogs package discogs
import ( import (
"net/url"
"strconv" "strconv"
) )
// ReleaseService ...
type ReleaseService struct {
url string
currency string
}
func newReleaseService(url string, currency string) *ReleaseService {
return &ReleaseService{
url: url,
currency: currency,
}
}
// ReqRelease serves release request
type ReqRelease struct {
CurrAbbr string
}
// 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"`
@ -41,16 +60,31 @@ type Release struct {
Year int `json:"year"` Year int `json:"year"`
} }
type ReqRelease struct {
CurrAbbr string
}
// Release returns release by release's ID // Release returns release by release's ID
func (c *Client) Release(releaseID int) (*Release, error) { func (s *ReleaseService) Release(releaseID int) (*Release, error) {
release := new(Release) params := url.Values{}
apiError := new(APIError) params.Set("CurrAbbr", s.currency)
req := &ReqRelease{CurrAbbr: c.currency} var release *Release
_, err := c.api.New().Get("releases/"+strconv.Itoa(releaseID)).QueryStruct(req).Receive(release, apiError) if err := request(s.url+strconv.Itoa(releaseID), params, &release); err != nil {
return release, relevantError(err, *apiError) return nil, err
}
return release, nil
}
// ReleaseRating serves response for community release rating request
type ReleaseRating struct {
ID int `json:"release_id"`
Rating Rating `json:"rating"`
}
// Ratings retruns community release rating
func (s *ReleaseService) Rating(releaseID int) (*ReleaseRating, error) {
var rating *ReleaseRating
if err := request(s.url+strconv.Itoa(releaseID)+"/rating", nil, &rating); err != nil {
return nil, err
}
return rating, nil
} }

View File

@ -1,16 +1,30 @@
package discogs package discogs
import ( import (
"fmt" "io"
"net/http"
"net/http/httptest"
"testing" "testing"
) )
func TestReleaseService_Release(t *testing.T) { func ReleaseServer(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
io.WriteString(w, `{"title":"Elephant Riddim"}`)
}
func TestReleaseServiceRelease(t *testing.T) {
expectedTitle := "Elephant Riddim" expectedTitle := "Elephant Riddim"
d := NewClient(testUserAgent, testToken) ts := httptest.NewServer(http.HandlerFunc(ReleaseServer))
release, err := d.Release.Release(8138518) defer ts.Close()
check(t, err) d := initDiscogsClient(t, &Options{URL: ts.URL})
assert(t, release.Title == expectedTitle, fmt.Sprintf("Release.Title looked for %s, and received %s ", expectedTitle, release.Title)) release, err := d.Release.Release(8138518)
if err != nil {
t.Fatalf("failed to get release: %s", err)
}
if release.Title != expectedTitle {
t.Fatalf("release title got=%s want=%s ", expectedTitle, release.Title)
}
} }