spotify-client 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8369fd39e93441e6443010c7f9f4d3795fbef619
4
+ data.tar.gz: b8202b9abf4963f52ca4b0be762cc586a681ac21
5
+ SHA512:
6
+ metadata.gz: 4f3bb1b197542fca61f12021e919e48626893c96b11987123c4232b1d7831ae78d679d706947fb787e34dc6a4200c7be5398335dc4f132e02c3fa81d3caa8f97
7
+ data.tar.gz: ed067b3f2c46a1aa0fc52ee959dea624fd19924938276d052a2949da17829489ac814f1f2ec1fbe4ebb4e9f7dd7e3d8688ec07ff8adf0e8cd643278e547d62d4
@@ -0,0 +1 @@
1
+ require File.dirname(__FILE__) + '/spotify_client'
@@ -0,0 +1,9 @@
1
+ module Spotify
2
+ class ImplementationError < StandardError; end
3
+ class Error < StandardError; end
4
+ class AuthenticationError < Error; end
5
+ class HTTPError < Error; end
6
+ class InsufficientClienScopeError < Error; end
7
+ class BadRequest < Error; end
8
+ class ResourceNotFound < Error; end
9
+ end
@@ -0,0 +1,11 @@
1
+ class Array
2
+ def self.wrap(object)
3
+ if object.nil?
4
+ []
5
+ elsif object.respond_to?(:to_ary)
6
+ object.to_ary || [object]
7
+ else
8
+ [object]
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,3 @@
1
+ module Spotify
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,190 @@
1
+ require 'excon'
2
+ require 'json'
3
+
4
+ require File.dirname(__FILE__) + '/spotify/utils'
5
+ require File.dirname(__FILE__) + '/spotify/exceptions'
6
+
7
+ module Spotify
8
+ class Client
9
+ BASE_URI = 'https://api.spotify.com'.freeze
10
+
11
+ attr_accessor :access_token
12
+
13
+ # Initialize the client.
14
+ #
15
+ # @example
16
+ # client = Spotify::Client.new(:access_token => 'longtoken', retries: 0, raise_errors: true)
17
+ #
18
+ # @param [Hash] configuration.
19
+ def initialize(config = {})
20
+ @access_token = config[:access_token]
21
+ @raise_errors = config[:raise_errors] || false
22
+ @retries = config[:retries] || 0
23
+ @read_timeout = config[:read_timeout] || 10
24
+ @write_timeout = config[:write_timeout] || 10
25
+ @connection = Excon.new(BASE_URI, :persistent => config[:persistent] || false)
26
+ end
27
+
28
+ def inspect
29
+ vars = self.instance_variables.map{ |v| "#{v}=#{instance_variable_get(v).inspect}"}.join(', ')
30
+ "<#{self.class}: #{vars}>"
31
+ end
32
+
33
+ # Closes the connection underlying socket.
34
+ # Use when you employ persistent connections and are done with your requests.
35
+ def close_connection
36
+ @connection.reset
37
+ end
38
+
39
+ def me
40
+ run(:get, "/v1/me", [200])
41
+ end
42
+
43
+ def user(user_id)
44
+ run(:get, "/v1/users/#{user_id}", [200])
45
+ end
46
+
47
+ def user_playlists(user_id)
48
+ run(:get, "/v1/users/#{user_id}/playlists", [200])
49
+ end
50
+
51
+ def user_playlist(user_id, playlist_id)
52
+ run(:get, "/v1/users/#{user_id}/playlists/#{playlist_id}", [200])
53
+ end
54
+
55
+ def user_playlist_tracks(user_id, playlist_id)
56
+ run(:get, "/v1/users/#{user_id}/playlists/#{playlist_id}/tracks", [200])
57
+ end
58
+
59
+ # Create a playlist for a Spotify user. The playlist will be empty until you add tracks.
60
+ #
61
+ # Requires playlist-modify for a public playlist.
62
+ # Requires playlist-modify-private for a private playlist.
63
+ def create_user_playlist(user_id, name, is_public = true)
64
+ run(:post, "/v1/users/#{user_id}/playlists", [201], JSON.dump({ :name => name, :public => is_public }))
65
+ end
66
+
67
+ # Add an Array of track uris to an existing playlist.
68
+ #
69
+ # Adding tracks to a user's public playlist requires authorization of the playlist-modify scope;
70
+ # adding tracks to a private playlist requires the playlist-modify-private scope.
71
+ #
72
+ # client.add_user_tracks_to_playlist('1181346016', '7i3thJWDtmX04dJhFwYb0x', %w(spotify:track:4iV5W9uYEdYUVa79Axb7Rh spotify:track:2lzEz3A3XIFyhMDqzMdcss))
73
+ def add_user_tracks_to_playlist(user_id, playlist_id, uris = [], position = nil)
74
+ params = { :uris => Array.wrap(uris)[0..99].join(',') }
75
+ if position
76
+ params.merge!(:position => position)
77
+ end
78
+ run(:post, "/v1/users/#{user_id}/playlists/#{playlist_id}/tracks", [201], params)
79
+ end
80
+
81
+ def album(album_id)
82
+ run(:get, "/v1/albums/#{album_id}", [200])
83
+ end
84
+
85
+ def album_tracks(album_id)
86
+ run(:get, "/v1/albums/#{album_id}/tracks", [200])
87
+ end
88
+
89
+ def albums(album_ids)
90
+ params = { :ids => Array.wrap(album_ids).join(',') }
91
+ run(:get, "/v1/albums", [200], params)
92
+ end
93
+
94
+ def track(track_id)
95
+ run(:get, "/v1/tracks/#{track_id}", [200])
96
+ end
97
+
98
+ def tracks(track_ids)
99
+ params = { :ids => Array.wrap(track_ids).join(',') }
100
+ run(:get, "/v1/tracks", [200], params)
101
+ end
102
+
103
+ def artist(artist_id)
104
+ run(:get, "/v1/artists/#{artist_id}", [200])
105
+ end
106
+
107
+ def artists(artist_ids)
108
+ params = { :ids => Array.wrap(artist_ids).join(',') }
109
+ run(:get, "/v1/tracks", [200], params)
110
+ end
111
+
112
+ def artist_albums(artist_id)
113
+ run(:get, "/v1/artists/#{artist_id}/albums", [200])
114
+ end
115
+
116
+ def search(entity, term)
117
+ unless [:artist, :album, :track].include?(entity.to_sym)
118
+ raise(ImplementationError, "entity needs to be either artist, album or track, got: #{entity}")
119
+ end
120
+ run(:get, "/v1/search", [200], { :q => term.to_s, type: entity })
121
+ end
122
+
123
+ # Get Spotify catalog information about an artist’s top 10 tracks by country.
124
+ #
125
+ # +country_id+ is required. An ISO 3166-1 alpha-2 country code.
126
+ def artist_top_tracks(artist_id, country_id)
127
+ run(:get, "/v1/artists/#{artist_id}/top-tracks", [200], { :country => country_id })
128
+ end
129
+
130
+ protected
131
+
132
+ def run(verb, path, expected_status_codes, params = {}, idempotent = true)
133
+ begin
134
+ run!(verb, path, expected_status_codes, params)
135
+ rescue Error => e
136
+ if @raise_errors
137
+ raise e
138
+ else
139
+ false
140
+ end
141
+ end
142
+ end
143
+
144
+ def run!(verb, path, expected_status_codes, params_or_body = nil, idempotent = true)
145
+ packet = {
146
+ :idempotent => idempotent,
147
+ :expects => expected_status_codes,
148
+ :method => verb,
149
+ :path => path,
150
+ :read_timeout => @read_timeout,
151
+ :write_timeout => @write_timeout,
152
+ :retry_limit => @retries,
153
+ :headers => {
154
+ 'Content-Type' => 'application/json',
155
+ 'User-Agent' => 'Spotify Ruby Client'
156
+ }
157
+ }
158
+ if params_or_body.is_a?(Hash)
159
+ packet.merge!(:query => params_or_body)
160
+ else
161
+ packet.merge!(:body => params_or_body)
162
+ end
163
+
164
+ if @access_token != nil && @access_token != ""
165
+ packet[:headers].merge!('Authorization' => "Bearer #{@access_token}")
166
+ end
167
+
168
+ # puts "\033[31m [Spotify] HTTP Request: #{verb.upcase} #{BASE_URI}#{path} #{packet[:headers].inspect} \e[0m"
169
+ response = @connection.request(packet)
170
+ ::JSON.load(response.body)
171
+
172
+ rescue Excon::Errors::NotFound => exception
173
+ raise(ResourceNotFound, "Error: #{exception.message}")
174
+ rescue Excon::Errors::BadRequest => exception
175
+ raise(BadRequest, "Error: #{exception.message}")
176
+ rescue Excon::Errors::Forbidden => exception
177
+ raise(InsufficientClienScopeError, "Error: #{exception.message}")
178
+ rescue Excon::Errors::Unauthorized => exception
179
+ raise(AuthenticationError, "Error: #{exception.message}")
180
+ rescue Excon::Errors::Error => exception
181
+ # Catch all others errors. Samples:
182
+ #
183
+ #<Excon::Errors::SocketError: Connection refused - connect(2) (Errno::ECONNREFUSED)>
184
+ #<Excon::Errors::InternalServerError: Expected([200, 204, 404]) <=> Actual(500 InternalServerError)>
185
+ #<Excon::Errors::Timeout: read timeout reached>
186
+ #<Excon::Errors::BadGateway: Expected([200]) <=> Actual(502 Bad Gateway)>
187
+ raise(HTTPError, "Error: #{exception.message}")
188
+ end
189
+ end
190
+ end
metadata ADDED
@@ -0,0 +1,90 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: spotify-client
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Claudio Poli
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-06-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: excon
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.37'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.37'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '3.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '3.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: guard-rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: Ruby client for the Spotify Web API
56
+ email:
57
+ - claudio@icorete.ch
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - lib/spotify-client.rb
63
+ - lib/spotify/exceptions.rb
64
+ - lib/spotify/utils.rb
65
+ - lib/spotify/version.rb
66
+ - lib/spotify_client.rb
67
+ homepage: https://github.com/icoretech/spotify-client
68
+ licenses: []
69
+ metadata: {}
70
+ post_install_message:
71
+ rdoc_options: []
72
+ require_paths:
73
+ - lib
74
+ required_ruby_version: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ required_rubygems_version: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ requirements: []
85
+ rubyforge_project: "[none]"
86
+ rubygems_version: 2.2.2
87
+ signing_key:
88
+ specification_version: 4
89
+ summary: Ruby client for the Spotify Web API
90
+ test_files: []