rspotify 1.14.0 → 1.15.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/rspotify/album.rb +4 -4
- data/lib/rspotify/artist.rb +7 -7
- data/lib/rspotify/base.rb +13 -13
- data/lib/rspotify/category.rb +6 -6
- data/lib/rspotify/connection.rb +8 -1
- data/lib/rspotify/playlist.rb +59 -11
- data/lib/rspotify/user.rb +29 -6
- data/lib/rspotify/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d7a369b00096dcefd7060c3d6d802dbd84c47891
|
4
|
+
data.tar.gz: 72766cf26e96b3cb2fe24df568b70a64d5683021
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b0b1c1b3a0e4651cb1fdf10c158f1ce89276450294dd18799fd72ed7006598c12f39b9220cf0a985a8e92752f37d2815ff2567f0fa7c85f5d5caa709716fe838
|
7
|
+
data.tar.gz: 8c15b7aa0844acd020380670247505ae83bff813062c12918cab4a43a1595c85921dc1f3ee711eab3575b9dc744bcb6873138e62cfb7362fbd098a42cc7f2907
|
data/lib/rspotify/album.rb
CHANGED
@@ -44,8 +44,8 @@ module RSpotify
|
|
44
44
|
def self.new_releases(limit: 20, offset: 0, country: nil)
|
45
45
|
url = "browse/new-releases?limit=#{limit}&offset=#{offset}"
|
46
46
|
url << "&country=#{country}" if country
|
47
|
-
|
48
|
-
|
47
|
+
response = RSpotify.get(url)
|
48
|
+
response['albums']['items'].map { |i| Album.new i }
|
49
49
|
end
|
50
50
|
|
51
51
|
# Returns array of Album objects matching the query, ordered by popularity. It's also possible to find the total number of search results for the query
|
@@ -105,8 +105,8 @@ module RSpotify
|
|
105
105
|
end
|
106
106
|
|
107
107
|
url = "albums/#{@id}/tracks?limit=#{limit}&offset=#{offset}"
|
108
|
-
|
109
|
-
tracks =
|
108
|
+
response = RSpotify.get(url)
|
109
|
+
tracks = response['items'].map { |i| Track.new i }
|
110
110
|
@tracks_cache = tracks if limit == 50 && offset == 0
|
111
111
|
tracks
|
112
112
|
end
|
data/lib/rspotify/artist.rb
CHANGED
@@ -16,7 +16,7 @@ module RSpotify
|
|
16
16
|
# artist = RSpotify::Artist.find('7Ln80lUS6He07XvHI8qqHH')
|
17
17
|
# artist.class #=> RSpotify::Artist
|
18
18
|
# artist.name #=> "Arctic Monkeys"
|
19
|
-
#
|
19
|
+
#
|
20
20
|
# ids = %w(7Ln80lUS6He07XvHI8qqHH 3dRfiJ2650SZu6GbydcHNb)
|
21
21
|
# artists = RSpotify::Artist.find(ids)
|
22
22
|
# artists.class #=> Array
|
@@ -72,8 +72,8 @@ module RSpotify
|
|
72
72
|
url << "&#{filter_name}=#{filter_value}"
|
73
73
|
end
|
74
74
|
|
75
|
-
|
76
|
-
|
75
|
+
response = RSpotify.get(url)
|
76
|
+
response['items'].map { |i| Album.new i }
|
77
77
|
end
|
78
78
|
|
79
79
|
# Returns array of similar artists. Similarity is based on analysis of the Spotify community’s {http://news.spotify.com/se/2010/02/03/related-artists listening history}.
|
@@ -88,8 +88,8 @@ module RSpotify
|
|
88
88
|
# related_artists.first.name #=> "Miles Kane"
|
89
89
|
def related_artists
|
90
90
|
return @related_artists unless @related_artists.nil?
|
91
|
-
|
92
|
-
@related_artists =
|
91
|
+
response = RSpotify.get("artists/#{@id}/related-artists")
|
92
|
+
@related_artists = response['artists'].map { |a| Artist.new a }
|
93
93
|
end
|
94
94
|
|
95
95
|
# Returns artist's 10 top tracks by country.
|
@@ -104,8 +104,8 @@ module RSpotify
|
|
104
104
|
# top_tracks.first.class #=> RSpotify::Track
|
105
105
|
def top_tracks(country)
|
106
106
|
return @top_tracks[country] unless @top_tracks[country].nil?
|
107
|
-
|
108
|
-
@top_tracks[country] =
|
107
|
+
response = RSpotify.get("artists/#{@id}/top-tracks?country=#{country}")
|
108
|
+
@top_tracks[country] = response['tracks'].map { |t| Track.new t }
|
109
109
|
end
|
110
110
|
end
|
111
111
|
end
|
data/lib/rspotify/base.rb
CHANGED
@@ -17,7 +17,7 @@ module RSpotify
|
|
17
17
|
# user = RSpotify::Base.find('wizzler', 'user')
|
18
18
|
# user.class #=> RSpotify::User
|
19
19
|
# user.id #=> "wizzler"
|
20
|
-
#
|
20
|
+
#
|
21
21
|
# ids = %w(2UzMpPKPhbcC8RbsmuURAZ 7Jzsc04YpkRwB1zeyM39wE)
|
22
22
|
# tracks = RSpotify::Base.find(ids, 'track')
|
23
23
|
# tracks.class #=> Array
|
@@ -40,23 +40,23 @@ module RSpotify
|
|
40
40
|
def self.find_many(ids, type)
|
41
41
|
type_class = RSpotify.const_get(type.capitalize)
|
42
42
|
path = "#{type}s?ids=#{ids.join ','}"
|
43
|
-
|
44
|
-
|
43
|
+
response = RSpotify.get path
|
44
|
+
response["#{type}s"].map { |t| type_class.new t }
|
45
45
|
end
|
46
46
|
private_class_method :find_many
|
47
47
|
|
48
48
|
def self.find_one(id, type)
|
49
49
|
type_class = RSpotify.const_get(type.capitalize)
|
50
50
|
path = "#{type}s/#{id}"
|
51
|
-
|
52
|
-
type_class.new
|
51
|
+
response = RSpotify.get path
|
52
|
+
type_class.new response
|
53
53
|
end
|
54
54
|
private_class_method :find_one
|
55
55
|
|
56
|
-
def self.insert_total(result, types,
|
56
|
+
def self.insert_total(result, types, response)
|
57
57
|
result.instance_eval do
|
58
58
|
@total = types.map do |type|
|
59
|
-
|
59
|
+
response["#{type}s"]['total']
|
60
60
|
end.reduce(:+)
|
61
61
|
|
62
62
|
define_singleton_method :total do
|
@@ -89,7 +89,7 @@ module RSpotify
|
|
89
89
|
url = "search?q=#{query}&type=#{types}"\
|
90
90
|
"&limit=#{limit}&offset=#{offset}"
|
91
91
|
|
92
|
-
|
92
|
+
response = if market.is_a? Hash
|
93
93
|
url << '&market=from_token'
|
94
94
|
User.oauth_get(market[:from].id, url)
|
95
95
|
else
|
@@ -100,10 +100,10 @@ module RSpotify
|
|
100
100
|
types = types.split(',')
|
101
101
|
result = types.flat_map do |type|
|
102
102
|
type_class = RSpotify.const_get(type.capitalize)
|
103
|
-
|
103
|
+
response["#{type}s"]['items'].map { |i| type_class.new i }
|
104
104
|
end
|
105
105
|
|
106
|
-
insert_total(result, types,
|
106
|
+
insert_total(result, types, response)
|
107
107
|
result
|
108
108
|
end
|
109
109
|
|
@@ -117,7 +117,7 @@ module RSpotify
|
|
117
117
|
|
118
118
|
# When an object is obtained undirectly, Spotify usually returns a simplified version of it.
|
119
119
|
# This method updates it into a full object, with all attributes filled.
|
120
|
-
#
|
120
|
+
#
|
121
121
|
# @note It is seldom necessary to use this method explicitly, since RSpotify takes care of it automatically when needed (see {#method_missing})
|
122
122
|
#
|
123
123
|
# @example
|
@@ -156,9 +156,9 @@ module RSpotify
|
|
156
156
|
return true if instance_variable_defined? attr
|
157
157
|
super
|
158
158
|
end
|
159
|
-
|
159
|
+
|
160
160
|
protected
|
161
|
-
|
161
|
+
|
162
162
|
def hash_for(tracks, field)
|
163
163
|
return nil unless tracks
|
164
164
|
pairs = tracks.map do |track|
|
data/lib/rspotify/category.rb
CHANGED
@@ -29,8 +29,8 @@ module RSpotify
|
|
29
29
|
url << '&' unless index == options.size-1
|
30
30
|
end
|
31
31
|
|
32
|
-
|
33
|
-
Category.new
|
32
|
+
response = RSpotify.get(url)
|
33
|
+
Category.new response
|
34
34
|
end
|
35
35
|
|
36
36
|
# Get a list of categories used to tag items in Spotify
|
@@ -50,8 +50,8 @@ module RSpotify
|
|
50
50
|
options.each do |option, value|
|
51
51
|
url << "&#{option}=#{value}"
|
52
52
|
end
|
53
|
-
|
54
|
-
|
53
|
+
response = RSpotify.get(url)
|
54
|
+
response['categories']['items'].map { |i| Category.new i }
|
55
55
|
end
|
56
56
|
|
57
57
|
# Spotify does not support search for categories.
|
@@ -91,8 +91,8 @@ module RSpotify
|
|
91
91
|
url << "&#{option}=#{value}"
|
92
92
|
end
|
93
93
|
|
94
|
-
|
95
|
-
|
94
|
+
response = RSpotify.get(url)
|
95
|
+
response['playlists']['items'].map { |i| Playlist.new i }
|
96
96
|
end
|
97
97
|
end
|
98
98
|
end
|
data/lib/rspotify/connection.rb
CHANGED
@@ -52,7 +52,14 @@ module RSpotify
|
|
52
52
|
|
53
53
|
def send_request(verb, path, *params)
|
54
54
|
url = path.start_with?("http") ? path : API_URI + path
|
55
|
-
|
55
|
+
begin
|
56
|
+
response = RestClient.send(verb, url, *params)
|
57
|
+
rescue RestClient::Unauthorized
|
58
|
+
if @client_token
|
59
|
+
authenticate(@client_id, @client_secret)
|
60
|
+
response = RestClient.send(verb, url, *params)
|
61
|
+
end
|
62
|
+
end
|
56
63
|
JSON.parse response unless response.empty?
|
57
64
|
end
|
58
65
|
|
data/lib/rspotify/playlist.rb
CHANGED
@@ -7,7 +7,7 @@ module RSpotify
|
|
7
7
|
# @attr [String] name The name of the playlist
|
8
8
|
# @attr [User] owner The user who owns the playlist
|
9
9
|
# @attr [Boolean] public true if the playlist is not marked as secret
|
10
|
-
# @attr [String] snapshot_id The version identifier for the current playlist.
|
10
|
+
# @attr [String] snapshot_id The version identifier for the current playlist. This attribute gets updated every time the playlist changes and can be supplied in other requests to target a specific playlist version
|
11
11
|
# @attr [Integer] total The total number of tracks in the playlist
|
12
12
|
# @attr [Hash] tracks_added_at A hash containing the date and time each track was added to the playlist. Note: the hash is updated only when {#tracks} is used.
|
13
13
|
# @attr [Hash] tracks_added_by A hash containing the user that added each track to the playlist. Note: the hash is updated only when {#tracks} is used.
|
@@ -32,8 +32,8 @@ module RSpotify
|
|
32
32
|
options.each do |option, value|
|
33
33
|
url << "&#{option}=#{value}"
|
34
34
|
end
|
35
|
-
|
36
|
-
|
35
|
+
response = RSpotify.get(url)
|
36
|
+
response['playlists']['items'].map { |i| Playlist.new i }
|
37
37
|
end
|
38
38
|
|
39
39
|
# Returns Playlist object with user_id and id provided. If id is "starred", returns starred playlist from user.
|
@@ -52,8 +52,8 @@ module RSpotify
|
|
52
52
|
else
|
53
53
|
"users/#{user_id}/playlists/#{id}"
|
54
54
|
end
|
55
|
-
|
56
|
-
Playlist.new
|
55
|
+
response = RSpotify.resolve_auth_request(user_id, url)
|
56
|
+
Playlist.new response
|
57
57
|
end
|
58
58
|
|
59
59
|
# Returns array of Playlist objects matching the query. It's also possible to find the total number of search results for the query
|
@@ -130,10 +130,11 @@ module RSpotify
|
|
130
130
|
url = "#{@href}/tracks?uris=#{track_uris}"
|
131
131
|
url << "&position=#{position}" if position
|
132
132
|
|
133
|
-
User.oauth_post(@owner.id, url, {})
|
133
|
+
response = User.oauth_post(@owner.id, url, {})
|
134
|
+
@snapshot_id = response['snapshot_id']
|
135
|
+
|
134
136
|
@total += tracks.size
|
135
137
|
@tracks_cache = nil
|
136
|
-
|
137
138
|
tracks
|
138
139
|
end
|
139
140
|
|
@@ -157,6 +158,7 @@ module RSpotify
|
|
157
158
|
data.each do |field, value|
|
158
159
|
instance_variable_set("@#{field}", value)
|
159
160
|
end
|
161
|
+
@snapshot_id = nil
|
160
162
|
self
|
161
163
|
end
|
162
164
|
|
@@ -222,8 +224,8 @@ module RSpotify
|
|
222
224
|
end
|
223
225
|
|
224
226
|
url = "#{@href}/tracks?limit=#{limit}&offset=#{offset}"
|
225
|
-
|
226
|
-
tracks =
|
227
|
+
response = RSpotify.resolve_auth_request(@owner.id, url)
|
228
|
+
tracks = response['items'].select { |i| i['track'] }
|
227
229
|
|
228
230
|
@tracks_added_at = hash_for(tracks, 'added_at') do |added_at|
|
229
231
|
Time.parse added_at
|
@@ -242,6 +244,52 @@ module RSpotify
|
|
242
244
|
tracks
|
243
245
|
end
|
244
246
|
|
247
|
+
# Remove one or more tracks from a user’s playlist. Removing from a public playlist requires the
|
248
|
+
# *playlist-modify-public* scope; removing from a private playlist requires the *playlist-modify-private* scope.
|
249
|
+
#
|
250
|
+
# @param tracks [Array<Track,Hash>, Array<Integer>] Tracks to be removed. Maximum: 100 per request
|
251
|
+
# @param snapshot_id [String] Optional. The playlist's snapshot ID against which you want to make the changes.
|
252
|
+
# @return [Playlist]
|
253
|
+
#
|
254
|
+
# @example
|
255
|
+
# # Remove all occurrences of one or more tracks
|
256
|
+
# love_tracks = RSpotify::Track.search('Love')
|
257
|
+
# playlist.remove_tracks!(love_tracks)
|
258
|
+
#
|
259
|
+
# # Remove specific occurrences of one or more tracks
|
260
|
+
# track = RSpotify::Track.find('tR3oH...')
|
261
|
+
# playlist.remove_tracks!([{track: track, positions: [0,3]}, other_track])
|
262
|
+
#
|
263
|
+
# # Remove tracks based only on their positions (requires snapshot id)
|
264
|
+
# positions = [0,3,8]
|
265
|
+
# playlist.remove_tracks!(positions, snapshot_id: '0ZvtH...')
|
266
|
+
def remove_tracks!(tracks, snapshot_id: nil)
|
267
|
+
positions = tracks if tracks.first.is_a? Fixnum
|
268
|
+
|
269
|
+
tracks = tracks.map do |track|
|
270
|
+
next { uri: track.uri } if track.is_a? Track
|
271
|
+
{
|
272
|
+
uri: track[:track].uri,
|
273
|
+
positions: track[:positions]
|
274
|
+
}
|
275
|
+
end unless positions
|
276
|
+
|
277
|
+
params = {
|
278
|
+
method: :delete,
|
279
|
+
url: "#{@href}/tracks",
|
280
|
+
headers: User.send(:oauth_header, @owner.id),
|
281
|
+
payload: positions ? { positions: positions } : { tracks: tracks }
|
282
|
+
}
|
283
|
+
|
284
|
+
params[:payload][:snapshot_id] = snapshot_id if snapshot_id
|
285
|
+
params[:payload] = params[:payload].to_json
|
286
|
+
response = RestClient::Request.execute(params)
|
287
|
+
|
288
|
+
@snapshot_id = JSON.parse(response)['snapshot_id']
|
289
|
+
@tracks_cache = nil
|
290
|
+
self
|
291
|
+
end
|
292
|
+
|
245
293
|
# Reorder a track or a group of tracks in a playlist. Changing a public playlist requires the
|
246
294
|
# *playlist-modify-public* scope; changing a private playlist requires the *playlist-modify-private* scope.
|
247
295
|
#
|
@@ -283,11 +331,11 @@ module RSpotify
|
|
283
331
|
def replace_tracks!(tracks)
|
284
332
|
track_uris = tracks.map(&:uri).join(',')
|
285
333
|
url = "#{@href}/tracks?uris=#{track_uris}"
|
286
|
-
|
287
334
|
User.oauth_put(@owner.id, url, {})
|
335
|
+
|
288
336
|
@total = tracks.size
|
289
337
|
@tracks_cache = nil
|
290
|
-
|
338
|
+
@snapshot_id = nil
|
291
339
|
tracks
|
292
340
|
end
|
293
341
|
|
data/lib/rspotify/user.rb
CHANGED
@@ -36,8 +36,8 @@ module RSpotify
|
|
36
36
|
refresh_token: @@users_credentials[user_id]['refresh_token']
|
37
37
|
}
|
38
38
|
response = RestClient.post(TOKEN_URI, request_body, RSpotify.send(:auth_header))
|
39
|
-
|
40
|
-
@@users_credentials[user_id]['token'] =
|
39
|
+
response = JSON.parse(response)
|
40
|
+
@@users_credentials[user_id]['token'] = response['access_token']
|
41
41
|
end
|
42
42
|
private_class_method :refresh_token
|
43
43
|
|
@@ -144,6 +144,29 @@ module RSpotify
|
|
144
144
|
followed
|
145
145
|
end
|
146
146
|
|
147
|
+
# Get the current user’s followed artists or users. Requires the *user-follow-read* scope.
|
148
|
+
#
|
149
|
+
# @note The current Spotify API implementation only supports getting followed *artists*
|
150
|
+
#
|
151
|
+
# @param type [String] The ID type: currently only "artist" is supported
|
152
|
+
# @param limit [Integer] Maximum number of items to return. Maximum: 50. Minimum: 1. Default: 20.
|
153
|
+
# @param after [String] Optional. The last artist ID retrieved from the previous request.
|
154
|
+
# @return [Array<Artist>]
|
155
|
+
#
|
156
|
+
# @example
|
157
|
+
# followed_artists = user.following(type: 'artist')
|
158
|
+
# followed_artists.first.class #=> RSpotify::Artist
|
159
|
+
#
|
160
|
+
# followed_artists = user.following(type: 'artist', limit: 50)
|
161
|
+
def following(type: nil, limit: 20, after: nil)
|
162
|
+
type_class = RSpotify.const_get(type.capitalize)
|
163
|
+
url = "me/following?type=#{type}&limit=#{limit}"
|
164
|
+
url << "&after=#{after}" if after
|
165
|
+
|
166
|
+
response = User.oauth_get(@id, url)
|
167
|
+
response["#{type}s"]['items'].map { |i| type_class.new i }
|
168
|
+
end
|
169
|
+
|
147
170
|
# Check if the current user is following one or more artists or other Spotify users. This method
|
148
171
|
# is only available when the current user has granted access to the *user-follow-read* scope.
|
149
172
|
#
|
@@ -179,8 +202,8 @@ module RSpotify
|
|
179
202
|
# playlists.first.name #=> "Movie Soundtrack Masterpieces"
|
180
203
|
def playlists(limit: 20, offset: 0)
|
181
204
|
url = "users/#{@id}/playlists?limit=#{limit}&offset=#{offset}"
|
182
|
-
|
183
|
-
|
205
|
+
response = RSpotify.resolve_auth_request(@id, url)
|
206
|
+
response['items'].map { |i| Playlist.new i }
|
184
207
|
end
|
185
208
|
|
186
209
|
# Remove tracks from the user’s “Your Music” library.
|
@@ -232,9 +255,9 @@ module RSpotify
|
|
232
255
|
# tracks.first.name #=> "Do I Wanna Know?"
|
233
256
|
def saved_tracks(limit: 20, offset: 0)
|
234
257
|
url = "me/tracks?limit=#{limit}&offset=#{offset}"
|
235
|
-
|
258
|
+
response = User.oauth_get(@id, url)
|
236
259
|
|
237
|
-
tracks =
|
260
|
+
tracks = response['items'].select { |i| i['track'] }
|
238
261
|
@tracks_added_at = hash_for(tracks, 'added_at') do |added_at|
|
239
262
|
Time.parse added_at
|
240
263
|
end
|
data/lib/rspotify/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rspotify
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.15.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Guilherme Sad
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-07-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: omniauth-oauth2
|