Skip to content

Commit

Permalink
Merge pull request #173 from camphor-/add-api-cache
Browse files Browse the repository at this point in the history
  • Loading branch information
p1ass authored Aug 5, 2020
2 parents 622cb15 + 47a57bf commit 1758f33
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 14 deletions.
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ require (
github.com/gorilla/websocket v1.4.2
github.com/labstack/echo/v4 v4.1.16
github.com/labstack/gommon v0.3.0
github.com/patrickmn/go-cache v2.1.0+incompatible
github.com/zmb3/spotify v0.0.0-20200422222148-5fe5f9535a2c
golang.org/x/crypto v0.0.0-20200423211502-4bdfaf469ed5 // indirect
golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0 // indirect
Expand All @@ -20,4 +21,4 @@ require (
google.golang.org/appengine v1.6.6 // indirect
)

replace github.com/zmb3/spotify => github.com/p1ass/spotify v0.0.0-20200804070451-35a3efb1eefb
replace github.com/zmb3/spotify => github.com/p1ass/spotify v0.0.0-20200804070451-35a3efb1eefb
9 changes: 2 additions & 7 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ github.com/go-gorp/gorp/v3 v3.0.2/go.mod h1:BJ3q1ejpV8cVALtcXvXaXyTOlMmJhWDxTmnc
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/golang/mock v1.4.3 h1:GV+pQPG/EUUbkh47niozDcADz6go/dUwhVzdUQHIVRw=
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc=
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
Expand Down Expand Up @@ -50,6 +48,8 @@ github.com/mattn/go-sqlite3 v1.11.0 h1:LDdKkqtYlom37fkvqs8rMPFKAMe8+SgjbwZ6ex1/A
github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/p1ass/spotify v0.0.0-20200804070451-35a3efb1eefb h1:1SzuWPo6QDjBEDEh4e13eVpP917MMl0uoQV0yEShGEg=
github.com/p1ass/spotify v0.0.0-20200804070451-35a3efb1eefb/go.mod h1:CYu0Uo+YYMlUX39zUTsCU9j3SpK3l1eB8oLykXF7R7w=
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/poy/onpar v0.0.0-20190519213022-ee068f8ea4d1 h1:oL4IBbcqwhhNWh31bjOX8C/OCy0zs9906d/VUru+bqg=
Expand All @@ -64,8 +64,6 @@ github.com/valyala/fasttemplate v1.1.0 h1:RZqt0yGBsps8NGvLSGW804QQqCUYYLsaOjTVHy
github.com/valyala/fasttemplate v1.1.0/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs=
github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
github.com/zmb3/spotify v0.0.0-20200422222148-5fe5f9535a2c h1:BHOHTZS4eVhPUoiwttNT4zdvkAzquBeD7bF5qEztKgs=
github.com/zmb3/spotify v0.0.0-20200422222148-5fe5f9535a2c/go.mod h1:CYu0Uo+YYMlUX39zUTsCU9j3SpK3l1eB8oLykXF7R7w=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d h1:1ZiEyfaQIg3Qh0EoqpwAakHVhecoE5wlSg5GjnafJGw=
golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
Expand Down Expand Up @@ -94,7 +92,6 @@ golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f h1:gWF768j/LaZugp8dyS4UwsslYCYz9XgFxvlgsn0n9H8=
golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
Expand All @@ -120,5 +117,3 @@ gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
7 changes: 5 additions & 2 deletions spotify/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,26 @@ package spotify

import (
"fmt"
"time"

"github.com/camphor-/relaym-server/config"

"github.com/patrickmn/go-cache"
"github.com/zmb3/spotify"
"golang.org/x/oauth2"
)

// Client はSpotifyのWeb APIをコールするクライアントです。
type Client struct {
auth spotify.Authenticator
auth spotify.Authenticator
cache *cache.Cache
}

// NewClient はClientのポインタを生成する関数です。
func NewClient(cfg *config.Spotify) *Client {
auth := spotify.NewAuthenticator(cfg.RedirectURL(), spotify.ScopeUserReadPrivate, spotify.ScopeUserReadPlaybackState, spotify.ScopeUserModifyPlaybackState)
auth.SetAuthInfo(cfg.ClientID(), cfg.ClientSecret())
return &Client{auth: auth}
return &Client{auth: auth, cache: cache.New(10*time.Minute, 20*time.Minute)}
}

// GetAuthURL はSpotifyの認証画面のURLを取得します。
Expand Down
39 changes: 35 additions & 4 deletions spotify/track.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package spotify

import (
"bytes"
"context"
"fmt"
"math"
Expand All @@ -14,22 +15,33 @@ import (

// Search はSpotify APIを通して、与えられたクエリを用い音楽を検索します。
func (c *Client) Search(ctx context.Context, q string) ([]*entity.Track, error) {
const searchKey = "searchKey"

token, ok := service.GetTokenFromContext(ctx)
if !ok {
return nil, fmt.Errorf("token not found")
}

cached, ok := c.cache.Get(searchKey + q)
if result, typeOK := cached.(*spotify.SearchResult); ok && typeOK {
return c.toTracks(result.Tracks.Tracks), nil
}

cli := c.auth.NewClient(token)
cli.AcceptLanguage = "ja,en;q=0.9"
result, err := cli.Search(q, spotify.SearchTypeTrack)
if err != nil {
return nil, fmt.Errorf("search q=%s: %w", q, err)
}
return c.toTracks(result.Tracks.Tracks), nil
c.cache.SetDefault(searchKey+q, result)
tracks := c.toTracks(result.Tracks.Tracks)

return tracks, nil
}

// GetTrackFromURI はSpotify APIを通して、与えられたTrack URIを用い音楽を取得します。
func (c *Client) GetTracksFromURI(ctx context.Context, trackURIs []string) ([]*entity.Track, error) {
const getTracksKey = "getTracksKey"
if len(trackURIs) == 0 {
return nil, nil
}
Expand Down Expand Up @@ -57,9 +69,20 @@ func (c *Client) GetTracksFromURI(ctx context.Context, trackURIs []string) ([]*e
} else {
idsForAPI = ids[i*50 : (i+1)*50]
}
resultTracks, err := cli.GetTracks(idsForAPI...)
if err != nil {
return nil, fmt.Errorf("get track uris=%s: %w", trackURIs, err)

var resultTracks []*spotify.FullTrack

key := c.idsToCacheKey(idsForAPI)
cached, ok := c.cache.Get(getTracksKey + key)
if v, typeOK := cached.([]*spotify.FullTrack); ok && typeOK {
resultTracks = v
} else {
var err error
resultTracks, err = cli.GetTracks(idsForAPI...)
if err != nil {
return nil, fmt.Errorf("get track uris=%s: %w", trackURIs, err)
}
c.cache.SetDefault(getTracksKey+key, resultTracks)
}

for j, rt := range resultTracks {
Expand All @@ -72,6 +95,14 @@ func (c *Client) GetTracksFromURI(ctx context.Context, trackURIs []string) ([]*e
return tracks, nil
}

func (c *Client) idsToCacheKey(ids []spotify.ID) string {
buff := bytes.Buffer{}
for _, id := range ids {
buff.WriteString(string(id))
}
return buff.String()
}

func (c *Client) toTracks(resultTracks []spotify.FullTrack) []*entity.Track {
tracks := make([]*entity.Track, len(resultTracks))

Expand Down

0 comments on commit 1758f33

Please sign in to comment.