diff --git a/README.md b/README.md index 3f99bfc..0bccd82 100644 --- a/README.md +++ b/README.md @@ -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). This is token way example: ```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 ```go - release, err := client.Release(9893847) + release, err := client.Release.Release(9893847) fmt.Println(release.Artists[0].Name, " - ", release.Title) // St. Petersburg Ska-Jazz Review - Elephant Riddim ``` diff --git a/artists_test.go b/artists_test.go deleted file mode 100644 index a31d616..0000000 --- a/artists_test.go +++ /dev/null @@ -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)) -} diff --git a/discogs.go b/discogs.go index fef0762..58f1fa9 100644 --- a/discogs.go +++ b/discogs.go @@ -1,8 +1,11 @@ package discogs import ( + "encoding/json" "fmt" + "io/ioutil" "net/http" + "net/url" "github.com/irlndts/go-apirequest" ) @@ -11,53 +14,91 @@ const ( 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. type Client struct { - api *apirequest.API - currency string - Master *MasterService - Artist *ArtistService - Label *LabelService - Search *SearchService + Release *ReleaseService + Master *MasterService + Artist *ArtistService + Label *LabelService + Search *SearchService } +var header *http.Header + // 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) - return &Client{ - api: base, - currency: "USD", - Artist: newArtistService(base.New()), - Label: newLabelService(base.New()), - Master: newMasterService(base.New()), - Search: newSearchService(base.New()), + if o == nil || o.UserAgent == "" { + return nil, fmt.Errorf("failed to set user-agent") } + + 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 -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. +// currency validates currency for marketplace data. // Defaults to the authenticated users currency. Must be one of the following: // USD GBP EUR CAD AUD JPY CHF MXN BRL NZD SEK ZAR -func (c *Client) Currency(currency string) error { - switch currency { +func currency(c string) (string, error) { + switch c { case "USD", "GBP", "EUR", "CAD", "AUD", "JPY", "CHF", "MXN", "BRL", "NZD", "SEK", "ZAR": - c.currency = currency + return c, nil + case "": + return "USD", nil 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) } diff --git a/discogs_test.go b/discogs_test.go index b58defb..00a1624 100644 --- a/discogs_test.go +++ b/discogs_test.go @@ -9,14 +9,23 @@ const ( testToken = "" ) -func check(t *testing.T, e error) { - if e != nil { - t.Error(e) +func initDiscogsClient(t *testing.T, options *Options) *Client { + if options == nil { + options = &Options{ + UserAgent: testUserAgent, + Currency: "USD", + Token: testToken, + } } -} -func assert(t *testing.T, condition bool, assertion string) { - if !condition { - t.Errorf("Assertion failed: %v", assertion) + if options.UserAgent == "" { + options.UserAgent = testUserAgent } + + client, err := NewClient(options) + if err != nil { + t.Fatalf("failed to create client: %s", err) + } + + return client } diff --git a/examples/discogs_example.go b/examples/discogs_example.go index 1d334d1..12997bc 100644 --- a/examples/discogs_example.go +++ b/examples/discogs_example.go @@ -7,13 +7,17 @@ import ( ) func main() { - d := discogs.NewClient().UserAgent("TestDiscogsClient/0.0.1 +http://example.com") - if err := d.Currency("EUR"); err != nil { + d, err := discogs.NewClient(&discogs.Options{ + UserAgent: "TestDiscogsClient/0.0.1 +http://example.com", + Currency: "EUR", + Token: "", + }) + if err != nil { fmt.Println(err) return } - release, err := d.Release(9893847) + release, err := d.Release.Rating(9893847) if err != nil { fmt.Println(err) return diff --git a/labels_test.go b/labels_test.go deleted file mode 100644 index a50413c..0000000 --- a/labels_test.go +++ /dev/null @@ -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)) -} diff --git a/masters_test.go b/masters_test.go deleted file mode 100644 index 5a5a792..0000000 --- a/masters_test.go +++ /dev/null @@ -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)) -} diff --git a/releases.go b/releases.go index fcb4be5..b9ac9a8 100644 --- a/releases.go +++ b/releases.go @@ -1,9 +1,28 @@ package discogs import ( + "net/url" "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 type Release struct { Title string `json:"title"` @@ -41,16 +60,31 @@ type Release struct { Year int `json:"year"` } -type ReqRelease struct { - CurrAbbr string -} - // Release returns release by release's ID -func (c *Client) Release(releaseID int) (*Release, error) { - release := new(Release) - apiError := new(APIError) +func (s *ReleaseService) Release(releaseID int) (*Release, error) { + params := url.Values{} + params.Set("CurrAbbr", s.currency) - req := &ReqRelease{CurrAbbr: c.currency} - _, err := c.api.New().Get("releases/"+strconv.Itoa(releaseID)).QueryStruct(req).Receive(release, apiError) - return release, relevantError(err, *apiError) + var release *Release + if err := request(s.url+strconv.Itoa(releaseID), params, &release); err != nil { + 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 } diff --git a/releases_test.go b/releases_test.go index ae6ae65..75fb4e9 100644 --- a/releases_test.go +++ b/releases_test.go @@ -1,16 +1,30 @@ package discogs import ( - "fmt" + "io" + "net/http" + "net/http/httptest" "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" - d := NewClient(testUserAgent, testToken) - release, err := d.Release.Release(8138518) + ts := httptest.NewServer(http.HandlerFunc(ReleaseServer)) + defer ts.Close() - check(t, err) - assert(t, release.Title == expectedTitle, fmt.Sprintf("Release.Title looked for %s, and received %s ", expectedTitle, release.Title)) + d := initDiscogsClient(t, &Options{URL: ts.URL}) + 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) + } }