Skip to content

Commit

Permalink
Merge pull request #145 from zmb3/v2
Browse files Browse the repository at this point in the history
V2
  • Loading branch information
strideynet authored Aug 16, 2021
2 parents 1fa84a5 + ae714dd commit c44aaf9
Show file tree
Hide file tree
Showing 48 changed files with 1,252 additions and 1,157 deletions.
17 changes: 17 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: golangci-lint
on:
push:
branches:
- master
pull_request:
jobs:
golangci:
name: lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: golangci-lint
uses: golangci/golangci-lint-action@v2
with:
# Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version.
version: v1.39
16 changes: 16 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name: test
on:
push:
branches:
- master
pull_request:
jobs:
unit:
name: unit
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-go@v2
with:
go-version: '1.16.3' # The Go version to download (if necessary) and use.
- run: go test ./...
17 changes: 17 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib

# Test binary, built with `go test -c`
*.test

# Output of the go coverage tool, specifically when used with LiteIDE
*.out

# Dependency directories (remove the comment below to include it)
# vendor/

.idea/
11 changes: 0 additions & 11 deletions .travis.yml

This file was deleted.

22 changes: 4 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ Spotify
=======

[![GoDoc](https://godoc.org/github.com/zmb3/spotify?status.svg)](http://godoc.org/github.com/zmb3/spotify)
[![Build status](https://ci.appveyor.com/api/projects/status/1nr9vv0jqq438nj2?svg=true)](https://ci.appveyor.com/project/zmb3/spotify)
[![Build Status](https://travis-ci.org/zmb3/spotify.svg)](https://travis-ci.org/zmb3/spotify)

This is a Go wrapper for working with Spotify's
[Web API](https://developer.spotify.com/web-api/).
Expand All @@ -19,7 +17,7 @@ By using this library you agree to Spotify's

To install the library, simply

`go get github.com/zmb3/spotify`
`go get github.com/zmb3/spotify/v2`

## Authentication

Expand All @@ -44,11 +42,7 @@ provide this data manually.
````Go
// the redirect URL must be an exact match of a URL you've registered for your application
// scopes determine which permissions the user is prompted to authorize
auth := spotify.NewAuthenticator(redirectURL, spotify.ScopeUserReadPrivate)

// if you didn't store your ID and secret key in the specified environment variables,
// you can set them manually here
auth.SetAuthInfo(clientID, secretKey)
auth := spotifyauth.New(spotifyauth.WithRedirectURL(redirectURL), spotifyauth.WithScopes(spotifyauth.ScopeUserReadPrivate))

// get the user to this URL - how you do that is up to you
// you should specify a unique state string to identify the session
Expand All @@ -58,13 +52,13 @@ url := auth.AuthURL(state)
// typically you'll have a handler set up like the following:
func redirectHandler(w http.ResponseWriter, r *http.Request) {
// use the same state string here that you used to generate the URL
token, err := auth.Token(state, r)
token, err := auth.Token(r.Context(), state, r)
if err != nil {
http.Error(w, "Couldn't get token", http.StatusNotFound)
return
}
// create a client using the specified token
client := auth.NewClient(token)
client := spotify.New(auth.Client(r.Context(), token))

// the client can now be used to make authenticated requests
}
Expand All @@ -81,14 +75,6 @@ https://godoc.org/golang.org/x/oauth2/google

## Helpful Hints


### Optional Parameters

Many of the functions in this package come in two forms - a simple version that
omits optional parameters and uses reasonable defaults, and a more sophisticated
version that accepts additional parameters. The latter is suffixed with `Opt`
to indicate that it accepts some optional parameters.

### Automatic Retries

The API will throttle your requests if you are sending them too rapidly.
Expand Down
69 changes: 18 additions & 51 deletions album.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package spotify

import (
"context"
"errors"
"fmt"
"net/url"
"strconv"
"strings"
"time"
Expand Down Expand Up @@ -102,21 +102,17 @@ type SavedAlbum struct {
}

// GetAlbum gets Spotify catalog information for a single album, given its Spotify ID.
func (c *Client) GetAlbum(id ID) (*FullAlbum, error) {
return c.GetAlbumOpt(id, nil)
}

// GetAlbum is like GetAlbumOpt but it accepts an additional country option for track relinking
func (c *Client) GetAlbumOpt(id ID, opt *Options) (*FullAlbum, error) {
// Supported options: Market
func (c *Client) GetAlbum(ctx context.Context, id ID, opts ...RequestOption) (*FullAlbum, error) {
spotifyURL := fmt.Sprintf("%salbums/%s", c.baseURL, id)

if opt != nil && opt.Country != nil {
spotifyURL += "?market=" + *opt.Country
if params := processOptions(opts...).urlParams.Encode(); params != "" {
spotifyURL += "?" + params
}

var a FullAlbum

err := c.get(spotifyURL, &a)
err := c.get(ctx, spotifyURL, &a)
if err != nil {
return nil, err
}
Expand All @@ -136,31 +132,24 @@ func toStringSlice(ids []ID) []string {
// Spotify IDs. It supports up to 20 IDs in a single call. Albums are returned
// in the order requested. If an album is not found, that position in the
// result slice will be nil.
func (c *Client) GetAlbums(ids ...ID) ([]*FullAlbum, error) {
return c.GetAlbumsOpt(nil, ids...)
}

// GetAlbumsOpt is like GetAlbums but it accepts an additional country option for track relinking
//
// Doc API: https://developer.spotify.com/documentation/web-api/reference/albums/get-several-albums/
func (c *Client) GetAlbumsOpt(opt *Options, ids ...ID) ([]*FullAlbum, error) {
//
// Supported options: Market
func (c *Client) GetAlbums(ctx context.Context, ids []ID, opts ...RequestOption) ([]*FullAlbum, error) {
if len(ids) > 20 {
return nil, errors.New("spotify: exceeded maximum number of albums")
}

params := url.Values{}
params := processOptions(opts...).urlParams
params.Set("ids", strings.Join(toStringSlice(ids), ","))

if opt != nil && opt.Country != nil {
params.Set("market", *opt.Country)
}

spotifyURL := fmt.Sprintf("%salbums?%s", c.baseURL, params.Encode())

var a struct {
Albums []*FullAlbum `json:"albums"`
}

err := c.get(spotifyURL, &a)
err := c.get(ctx, spotifyURL, &a)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -202,39 +191,17 @@ func (at AlbumType) encode() string {
// GetAlbumTracks gets the tracks for a particular album.
// If you only care about the tracks, this call is more efficient
// than GetAlbum.
func (c *Client) GetAlbumTracks(id ID) (*SimpleTrackPage, error) {
return c.GetAlbumTracksOpt(id, nil)
}

// GetAlbumTracksOpt behaves like GetAlbumTracks, with the exception that it
// allows you to specify options that limit the number of results returned and if
// track relinking should be used.
// The maximum number of results to return is specified by limit.
// The offset argument can be used to specify the index of the first track to return.
// It can be used along with limit to request the next set of results.
// Track relinking can be enabled by setting the Country option
func (c *Client) GetAlbumTracksOpt(id ID, opt *Options) (*SimpleTrackPage, error) {
//
// Supported Options: Market, Limit, Offset
func (c *Client) GetAlbumTracks(ctx context.Context, id ID, opts ...RequestOption) (*SimpleTrackPage, error) {
spotifyURL := fmt.Sprintf("%salbums/%s/tracks", c.baseURL, id)

if opt != nil {
v := url.Values{}
if opt.Limit != nil {
v.Set("limit", strconv.Itoa(*opt.Limit))
}
if opt.Offset != nil {
v.Set("offset", strconv.Itoa(*opt.Offset))
}
if opt.Country != nil {
v.Set("market", *opt.Country)
}
optional := v.Encode()
if optional != "" {
spotifyURL += "?" + optional
}
if params := processOptions(opts...).urlParams.Encode(); params != "" {
spotifyURL += "?" + params
}

var result SimpleTrackPage
err := c.get(spotifyURL, &result)
err := c.get(ctx, spotifyURL, &result)
if err != nil {
return nil, err
}
Expand Down
10 changes: 5 additions & 5 deletions album_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package spotify

import (
"context"
"net/http"
"testing"
)
Expand All @@ -10,7 +11,7 @@ func TestFindAlbum(t *testing.T) {
client, server := testClientFile(http.StatusOK, "test_data/find_album.txt")
defer server.Close()

album, err := client.GetAlbum(ID("0sNOF9WDwhWunNAHPD3Baj"))
album, err := client.GetAlbum(context.Background(), ID("0sNOF9WDwhWunNAHPD3Baj"))
if err != nil {
t.Fatal(err)
}
Expand All @@ -30,7 +31,7 @@ func TestFindAlbumBadID(t *testing.T) {
client, server := testClientString(http.StatusNotFound, `{ "error": { "status": 404, "message": "non existing id" } }`)
defer server.Close()

album, err := client.GetAlbum(ID("asdf"))
album, err := client.GetAlbum(context.Background(), ID("asdf"))
if album != nil {
t.Fatal("Expected nil album, got", album.Name)
}
Expand All @@ -51,7 +52,7 @@ func TestFindAlbums(t *testing.T) {
client, server := testClientFile(http.StatusOK, "test_data/find_albums.txt")
defer server.Close()

res, err := client.GetAlbums(ID("41MnTivkwTO3UUJ8DrqEJJ"), ID("6JWc4iAiJ9FjyK0B59ABb4"), ID("6UXCm6bOO4gFlDQZV5yL37"), ID("0X8vBD8h1Ga9eLT8jx9VCC"))
res, err := client.GetAlbums(context.Background(), []ID{"41MnTivkwTO3UUJ8DrqEJJ", "6JWc4iAiJ9FjyK0B59ABb4", "6UXCm6bOO4gFlDQZV5yL37", "0X8vBD8h1Ga9eLT8jx9VCC"})
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -89,8 +90,7 @@ func TestFindAlbumTracks(t *testing.T) {
client, server := testClientFile(http.StatusOK, "test_data/find_album_tracks.txt")
defer server.Close()

limit := 1
res, err := client.GetAlbumTracksOpt(ID("0sNOF9WDwhWunNAHPD3Baj"), &Options{Limit: &limit})
res, err := client.GetAlbumTracks(context.Background(), ID("0sNOF9WDwhWunNAHPD3Baj"), Limit(1))
if err != nil {
t.Fatal(err)
}
Expand Down
Loading

0 comments on commit c44aaf9

Please sign in to comment.