rspotify 1.14.0 → 1.15.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1082adbe732bf14bc527e73ba174a6f6ff13af16
4
- data.tar.gz: 2d82ce44c497c38d87f1c37d21164f0d355ed3b4
3
+ metadata.gz: d7a369b00096dcefd7060c3d6d802dbd84c47891
4
+ data.tar.gz: 72766cf26e96b3cb2fe24df568b70a64d5683021
5
5
  SHA512:
6
- metadata.gz: be541f01c62b9c4185a116bcd04c52b9becde49cd5616dcd7ea02f9a9d56be7651f3bfc5bc83c88f10fba09a1e681b68cae9482bcea187f3d0bb289291a20802
7
- data.tar.gz: 479718f76a3c2e38e319ff53087a41f4d0f4a9ff5e5b9303655a80646addaddcdde7ba54bafdf2fe154537364ca5bc1a5a2d7949a9793275ab0c948cc2cafee0
6
+ metadata.gz: b0b1c1b3a0e4651cb1fdf10c158f1ce89276450294dd18799fd72ed7006598c12f39b9220cf0a985a8e92752f37d2815ff2567f0fa7c85f5d5caa709716fe838
7
+ data.tar.gz: 8c15b7aa0844acd020380670247505ae83bff813062c12918cab4a43a1595c85921dc1f3ee711eab3575b9dc744bcb6873138e62cfb7362fbd098a42cc7f2907
@@ -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
- json = RSpotify.get(url)
48
- json['albums']['items'].map { |i| Album.new i }
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
- json = RSpotify.get(url)
109
- tracks = json['items'].map { |i| Track.new i }
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
@@ -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
- json = RSpotify.get(url)
76
- json['items'].map { |i| Album.new i }
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
- json = RSpotify.get("artists/#{@id}/related-artists")
92
- @related_artists = json['artists'].map { |a| Artist.new a }
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
- json = RSpotify.get("artists/#{@id}/top-tracks?country=#{country}")
108
- @top_tracks[country] = json['tracks'].map { |t| Track.new t }
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
- json = RSpotify.get path
44
- json["#{type}s"].map { |t| type_class.new t }
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
- json = RSpotify.get path
52
- type_class.new json
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, json)
56
+ def self.insert_total(result, types, response)
57
57
  result.instance_eval do
58
58
  @total = types.map do |type|
59
- json["#{type}s"]['total']
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
- json = if market.is_a? Hash
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
- json["#{type}s"]['items'].map { |i| type_class.new i }
103
+ response["#{type}s"]['items'].map { |i| type_class.new i }
104
104
  end
105
105
 
106
- insert_total(result, types, json)
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|
@@ -29,8 +29,8 @@ module RSpotify
29
29
  url << '&' unless index == options.size-1
30
30
  end
31
31
 
32
- json = RSpotify.get(url)
33
- Category.new json
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
- json = RSpotify.get(url)
54
- json['categories']['items'].map { |i| Category.new i }
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
- json = RSpotify.get(url)
95
- json['playlists']['items'].map { |i| Playlist.new i }
94
+ response = RSpotify.get(url)
95
+ response['playlists']['items'].map { |i| Playlist.new i }
96
96
  end
97
97
  end
98
98
  end
@@ -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
- response = RestClient.send(verb, url, *params)
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
 
@@ -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. Can be supplied in other requests to target a specific playlist version
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
- json = RSpotify.get(url)
36
- json['playlists']['items'].map { |i| Playlist.new i }
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
- json = RSpotify.resolve_auth_request(user_id, url)
56
- Playlist.new json
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
- json = RSpotify.resolve_auth_request(@owner.id, url)
226
- tracks = json['items'].select { |i| i['track'] }
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
- json = JSON.parse(response)
40
- @@users_credentials[user_id]['token'] = json['access_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
- json = RSpotify.resolve_auth_request(@id, url)
183
- json['items'].map { |i| Playlist.new i }
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
- json = User.oauth_get(@id, url)
258
+ response = User.oauth_get(@id, url)
236
259
 
237
- tracks = json['items'].select { |i| i['track'] }
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
@@ -1,3 +1,3 @@
1
1
  module RSpotify
2
- VERSION = '1.14.0'
2
+ VERSION = '1.15.0'
3
3
  end
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.14.0
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-06-21 00:00:00.000000000 Z
11
+ date: 2015-07-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: omniauth-oauth2