rspotify 1.7.0 → 1.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (29) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +5 -0
  3. data/lib/rspotify/album.rb +25 -11
  4. data/lib/rspotify/artist.rb +8 -11
  5. data/lib/rspotify/base.rb +21 -19
  6. data/lib/rspotify/playlist.rb +22 -0
  7. data/lib/rspotify/track.rb +9 -12
  8. data/lib/rspotify/version.rb +1 -1
  9. data/spec/lib/rspotify/album_spec.rb +40 -0
  10. data/spec/lib/rspotify/artist_spec.rb +6 -0
  11. data/spec/lib/rspotify/playlist_spec.rb +31 -1
  12. data/spec/lib/rspotify/track_spec.rb +6 -0
  13. data/spec/lib/rspotify/user_spec.rb +2 -2
  14. data/spec/vcr_cassettes/album_new_releases.yml +148 -0
  15. data/spec/vcr_cassettes/album_new_releases_country_ES.yml +153 -0
  16. data/spec/vcr_cassettes/album_new_releases_limit_10_offset_10.yml +110 -0
  17. data/spec/vcr_cassettes/album_search_AM_market_ES.yml +145 -0
  18. data/spec/vcr_cassettes/artist_search_Arctic_market_ES.yml +126 -0
  19. data/spec/vcr_cassettes/{authenticate_5ac1cda2ad354aeaa1ad2693d33bb98c.yml → authenticate_client.yml} +15 -15
  20. data/spec/vcr_cassettes/playlist_browse_featured.yml +98 -0
  21. data/spec/vcr_cassettes/playlist_browse_featured_country_ES_timestamp_2014-10-23T09_00_00.yml +111 -0
  22. data/spec/vcr_cassettes/playlist_browse_featured_limit_10_offset_10.yml +77 -0
  23. data/spec/vcr_cassettes/playlist_browse_featured_locale_es_MX.yml +98 -0
  24. data/spec/vcr_cassettes/track_search_Wanna_Know.yml +1 -1
  25. data/spec/vcr_cassettes/track_search_Wanna_Know_limit_10.yml +1 -1
  26. data/spec/vcr_cassettes/track_search_Wanna_Know_limit_10_offset_10.yml +1 -1
  27. data/spec/vcr_cassettes/track_search_Wanna_Know_market_ES.yml +230 -0
  28. data/spec/vcr_cassettes/track_search_Wanna_Know_offset_10.yml +1 -1
  29. metadata +24 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f1f17aa294f27089ff560a5646618f5dcfee6690
4
- data.tar.gz: 07b166ed7b15ce4b29e970d35cd939b78c85a0e8
3
+ metadata.gz: d728735ce396f5f11732cd5c37e0d512506ae503
4
+ data.tar.gz: 0ab2d62caa4df367d792f840f5809a3c720619b7
5
5
  SHA512:
6
- metadata.gz: bdea8017b299b4ce48e689355cffc1d0840ca97e28b77e7ea021b4d67798f27d7f10d079efdb43cb473c28189d7fbf739b4b375dd729e2c2d1fd802fc475718d
7
- data.tar.gz: 5a153f38605d25c63cedaa1f0fcad6f2ec957d20f26c57931fd3fc40751de6eefe4b11c8dc3b66ca62ac62c6582ad16fc63ab6506c79f24dcf8eca33407cc847
6
+ metadata.gz: c8f641f12f5b6f3f0ea50a12ed95549f546f40881c957ef70639344ded1f235e571a96e435486b9bd25c13fb0c4faba2f21ee0394e72c984ef1fa663edb2aaa6
7
+ data.tar.gz: 3b315e77dc643e53b1f4b58c85fc59e9faef82056f3f28f3f6685718c19af5bc0e286d74a6520e0f1b649e95f721b2eb0ff7bad8abd8e54c6c41f78e23034419
data/README.md CHANGED
@@ -101,8 +101,13 @@ playlist.description #=> "Iconic soundtracks featured..."
101
101
  playlist.followers['total'] #=> 13
102
102
  playlist.tracks #=> (Track array)
103
103
 
104
+ # Get user's playlist
104
105
  my_user = RSpotify::User.find("my_user")
105
106
  my_playlists = my_user.playlists #=> (Playlist array)
107
+
108
+ # Access featured content from Spotify's Browse tab
109
+ featured_playlists = RSpotify::Playlist.browse_featured(country: 'US')
110
+ new_releases = RSpotify::Album.new_releases(country: 'ES')
106
111
  ```
107
112
 
108
113
  RSpotify focuses on objects behaviour so you can forget the API and worry about your tracks, artists and so on.
@@ -30,23 +30,37 @@ module RSpotify
30
30
  super(ids, 'album')
31
31
  end
32
32
 
33
+ # Get a list of new album releases featured in Spotify (shown, for example, on a Spotify player’s “Browse” tab).
34
+ #
35
+ # @param limit [Integer] Maximum number of albums to return. Maximum: 50. Default: 20.
36
+ # @param offset [Integer] The index of the first album to return. Use with limit to get the next set of albums. Default: 0.
37
+ # @param country [String] Optional. A country: an {http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 ISO 3166-1 alpha-2 country code}. Provide this parameter if you want the list of returned albums to be relevant to a particular country. If omitted, the returned albums will be relevant to all countries.
38
+ # @return [Array<Album>]
39
+ #
40
+ # @example
41
+ # albums = RSpotify::Album.new_releases
42
+ # albums = RSpotify::Album.new_releases(country: 'US', limit: 10)
43
+ def self.new_releases(limit: 20, offset: 0, country: nil)
44
+ url = "browse/new-releases?limit=#{limit}&offset=#{offset}"
45
+ url << "&country=#{country}" if country
46
+ json = RSpotify.auth_get(url)
47
+ json['albums']['items'].map { |i| Album.new i }
48
+ end
49
+
33
50
  # Returns array of Album objects matching the query, ordered by popularity
34
51
  #
35
- # @param query [String] The search query's keywords. See the q description in {https://developer.spotify.com/web-api/search-item here} for details.
36
- # @param limit [Integer] Maximum number of albums to return. Maximum: 50. Default: 20.
37
- # @param offset [Integer] The index of the first album to return. Use with limit to get the next set of albums. Default: 0.
52
+ # @param query [String] The search query's keywords. For details access {https://developer.spotify.com/web-api/search-item here} and look for the q parameter description.
53
+ # @param limit [Integer] Maximum number of albums to return. Maximum: 50. Default: 20.
54
+ # @param offset [Integer] The index of the first album to return. Use with limit to get the next set of albums. Default: 0.
55
+ # @param market [String, Hash] Optional. An {http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 ISO 3166-1 alpha-2 country code} or the hash { from: user }, where user is a RSpotify user authenticated using OAuth with scope *user-read-private*. This will take the user's country as the market value. For details access {https://developer.spotify.com/web-api/search-item here} and look for the market parameter description.
38
56
  # @return [Array<Album>]
39
57
  #
40
58
  # @example
41
59
  # albums = RSpotify::Album.search('AM')
42
- # albums.size #=> 20
43
- # albums.first.class #=> RSpotify::Album
44
- # albums.first.name #=> "AM"
45
- #
46
- # albums = RSpotify::Base.search('AM', limit: 10)
47
- # albums.size #=> 10
48
- def self.search(query, limit: 20, offset: 0)
49
- super(query, 'album', limit: limit, offset: offset)
60
+ # albums = RSpotify::Album.search('AM', limit: 10, market: 'US')
61
+ # albums = RSpotify::Album.search('AM', market: { from: user })
62
+ def self.search(query, limit: 20, offset: 0, market: nil)
63
+ super(query, 'album', limit: limit, offset: offset, market: market)
50
64
  end
51
65
 
52
66
  def initialize(options = {})
@@ -26,21 +26,18 @@ module RSpotify
26
26
 
27
27
  # Returns array of Artist objects matching the query, ordered by popularity
28
28
  #
29
- # @param query [String] The search query's keywords. See the q description in {https://developer.spotify.com/web-api/search-item here} for details.
30
- # @param limit [Integer] Maximum number of artists to return. Maximum: 50. Default: 20.
31
- # @param offset [Integer] The index of the first artist to return. Use with limit to get the next set of artists. Default: 0.
29
+ # @param query [String] The search query's keywords. For details access {https://developer.spotify.com/web-api/search-item here} and look for the q parameter description.
30
+ # @param limit [Integer] Maximum number of artists to return. Maximum: 50. Default: 20.
31
+ # @param offset [Integer] The index of the first artist to return. Use with limit to get the next set of artists. Default: 0.
32
+ # @param market [String, Hash] Optional. An {http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 ISO 3166-1 alpha-2 country code} or the hash { from: user }, where user is a RSpotify user authenticated using OAuth with scope *user-read-private*. This will take the user's country as the market value. For details access {https://developer.spotify.com/web-api/search-item here} and look for the market parameter description.
32
33
  # @return [Array<Artist>]
33
34
  #
34
35
  # @example
35
36
  # artists = RSpotify::Artist.search('Arctic')
36
- # artists.size #=> 20
37
- # artists.first.class #=> RSpotify::Artist
38
- # artists.first.name #=> "Arctic Monkeys"
39
- #
40
- # artists = RSpotify::Artist.search('Arctic', limit: 10)
41
- # artists.size #=> 10
42
- def self.search(query, limit: 20, offset: 0)
43
- super(query, 'artist', limit: limit, offset: offset)
37
+ # artists = RSpotify::Artist.search('Arctic', limit: 10, market: 'US')
38
+ # artists = RSpotify::Artist.search('Arctic', market: { from: user })
39
+ def self.search(query, limit: 20, offset: 0, market: nil)
40
+ super(query, 'artist', limit: limit, offset: offset, market: market)
44
41
  end
45
42
 
46
43
  def initialize(options = {})
data/lib/rspotify/base.rb CHANGED
@@ -55,30 +55,32 @@ module RSpotify
55
55
 
56
56
  # Returns array of RSpotify objects matching the query, ordered by popularity
57
57
  #
58
- # @param query [String] The search query's keywords. See the q description in {https://developer.spotify.com/web-api/search-item here} for details.
59
- # @param types [String] Valid types are: album, artist, track and playlist. Separate multiple types with commas.
60
- # @param limit [Integer] Maximum number of objects to return. Maximum: 50. Default: 20.
61
- # @param offset [Integer] The index of the first object to return. Use with limit to get the next set of objects. Default: 0.
62
- # @return [Array<Album>, Array<Artist>, Array<Track>, Array<Playlist>]
58
+ # @param query [String] The search query's keywords. For details access {https://developer.spotify.com/web-api/search-item here} and look for the q parameter description.
59
+ # @param types [String] Valid types are: album, artist, track and playlist. Separate multiple types with commas.
60
+ # @param limit [Integer] Maximum number of objects to return. Maximum: 50. Default: 20.
61
+ # @param offset [Integer] The index of the first object to return. Use with limit to get the next set of objects. Default: 0.
62
+ # @param market [String, Hash] Optional. An {http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 ISO 3166-1 alpha-2 country code} or the hash { from: user }, where user is a RSpotify user authenticated using OAuth with scope *user-read-private*. This will take the user's country as the market value. (Playlist results are not affected by the market parameter.) For details access {https://developer.spotify.com/web-api/search-item here} and look for the market parameter description.
63
+ # @return [Array<Album>, Array<Artist>, Array<Track>, Array<Playlist>, Array<Base>]
63
64
  #
64
65
  # @example
65
66
  # artists = RSpotify::Base.search('Arctic', 'artist')
66
- # artists.size #=> 20
67
- # artists.first.class #=> RSpotify::Artist
68
- # artists.first.name #=> "Arctic Monkeys"
69
- #
70
- # albums = RSpotify::Base.search('AM', 'album', limit: 10)
71
- # albums.size #=> 10
72
- def self.search(query, types, limit: 20, offset: 0)
67
+ # albums = RSpotify::Base.search('AM', 'album', limit: 10, market: 'US')
68
+ # mixed = RSpotify::Base.search('Arctic', 'artist, album, track')
69
+ # albums = RSpotify::Base.search('AM', 'album', market: { from: user })
70
+ def self.search(query, types, limit: 20, offset: 0, market: nil)
71
+ query = URI::encode query
73
72
  types.gsub!(/\s+/, '')
74
73
 
75
- json = RSpotify.get 'search',
76
- params: {
77
- q: query,
78
- type: types,
79
- limit: limit,
80
- offset: offset
81
- }
74
+ url = "search?q=#{query}&type=#{types}"\
75
+ "&limit=#{limit}&offset=#{offset}"
76
+
77
+ json = if market.is_a? Hash
78
+ url << '&market=from_token'
79
+ User.oauth_get(market[:from].id, url)
80
+ else
81
+ url << "&market=#{market}" if market
82
+ RSpotify.get(url)
83
+ end
82
84
 
83
85
  types.split(',').flat_map do |type|
84
86
  type_class = RSpotify.const_get(type.capitalize)
@@ -9,6 +9,28 @@ module RSpotify
9
9
  # @attr [Boolean] public true if the playlist is not marked as secret
10
10
  class Playlist < Base
11
11
 
12
+ # Get a list of Spotify featured playlists (shown, for example, on a Spotify player’s “Browse” tab).
13
+ #
14
+ # @param limit [Integer] Maximum number of playlists to return. Maximum: 50. Default: 20.
15
+ # @param offset [Integer] The index of the first playlist to return. Use with limit to get the next set of playlists. Default: 0.
16
+ # @param locale [String] Optional. The desired language, consisting of a lowercase {http://en.wikipedia.org/wiki/ISO_639 ISO 639 language code} and an uppercase {http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 ISO 3166-1 alpha-2 country code}, joined by an underscore. For details access {https://developer.spotify.com/web-api/get-list-featured-playlists/ here} and look for the locale parameter description.
17
+ # @param country [String] Optional. A country: an {http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 ISO 3166-1 alpha-2 country code}. Provide this parameter if you want the list of returned playlists to be relevant to a particular country. If omitted, the returned playlists will be relevant to all countries.
18
+ # @param timestamp [String] Optional. A timestamp in {http://en.wikipedia.org/wiki/ISO_8601 ISO 8601} format: yyyy-MM-ddTHH:mm:ss. Use this parameter to specify the user's local time to get results tailored for that specific date and time in the day. If not provided, the response defaults to the current UTC time. Example: "2014-10-23T09:00:00" for a user whose local time is 9AM.
19
+ # @return [Array<Playlist>]
20
+ #
21
+ # @example
22
+ # playlists = RSpotify::Playlist.browse_featured
23
+ # playlists = RSpotify::Playlist.browse_featured(locale: 'es_MX', limit: 10)
24
+ # playlists = RSpotify::Playlist.browse_featured(country: 'US', timestamp: '2014-10-23T09:00:00')
25
+ def self.browse_featured(limit: 20, offset: 0, **options)
26
+ url = "browse/featured-playlists?limit=#{limit}&offset=#{offset}"
27
+ options.each do |option, value|
28
+ url << "&#{option}=#{value}"
29
+ end
30
+ json = RSpotify.auth_get(url)
31
+ json['playlists']['items'].map { |i| Playlist.new i }
32
+ end
33
+
12
34
  # Returns Playlist object with user_id and id provided. If id is "starred", returns starred playlist from user.
13
35
  #
14
36
  # @param user_id [String]
@@ -33,21 +33,18 @@ module RSpotify
33
33
 
34
34
  # Returns array of Track objects matching the query, ordered by popularity
35
35
  #
36
- # @param query [String] The search query's keywords. See the q description in {https://developer.spotify.com/web-api/search-item here} for details.
37
- # @param limit [Integer] Maximum number of tracks to return. Maximum: 50. Default: 20.
38
- # @param offset [Integer] The index of the first track to return. Use with limit to get the next set of tracks. Default: 0.
36
+ # @param query [String] The search query's keywords. For details access {https://developer.spotify.com/web-api/search-item here} and look for the q parameter description.
37
+ # @param limit [Integer] Maximum number of tracks to return. Maximum: 50. Default: 20.
38
+ # @param offset [Integer] The index of the first track to return. Use with limit to get the next set of tracks. Default: 0.
39
+ # @param market [String, Hash] Optional. An {http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 ISO 3166-1 alpha-2 country code} or the hash { from: user }, where user is a RSpotify user authenticated using OAuth with scope *user-read-private*. This will take the user's country as the market value. For details access {https://developer.spotify.com/web-api/search-item here} and look for the market parameter description.
39
40
  # @return [Array<Track>]
40
41
  #
41
42
  # @example
42
- # tracks = RSpotify::Track.search('Thriller')
43
- # tracks.size #=> 20
44
- # tracks.first.class #=> RSpotify::Track
45
- # tracks.first.name #=> "Thriller"
46
- #
47
- # tracks = RSpotify::Track.search('Thriller', limit: 10)
48
- # tracks.size #=> 10
49
- def self.search(query, limit: 20, offset: 0)
50
- super(query, 'track', limit: limit, offset: offset)
43
+ # tracks = RSpotify::Track.search('Wanna Know')
44
+ # tracks = RSpotify::Track.search('Wanna Know', limit: 10, market: 'US')
45
+ # tracks = RSpotify::Track.search('Wanna Know', market: { from: user })
46
+ def self.search(query, limit: 20, offset: 0, market: nil)
47
+ super(query, 'track', limit: limit, offset: offset, market: market)
51
48
  end
52
49
 
53
50
  def initialize(options = {})
@@ -1,3 +1,3 @@
1
1
  module RSpotify
2
- VERSION = '1.7.0'
2
+ VERSION = '1.8.0'
3
3
  end
@@ -64,6 +64,40 @@ describe RSpotify::Album do
64
64
  end
65
65
  end
66
66
 
67
+ describe 'Album::new_releases' do
68
+ # Keys generated specifically for the tests. Should be removed in the future
69
+ let(:client_id) { '5ac1cda2ad354aeaa1ad2693d33bb98c' }
70
+ let(:client_secret) { '155fc038a85840679b55a1822ef36b9b' }
71
+
72
+ before(:each) do
73
+ VCR.use_cassette('authenticate:client') do
74
+ RSpotify.authenticate(client_id, client_secret)
75
+ end
76
+ end
77
+
78
+ it 'should find the appropriate new releases' do
79
+ albums = VCR.use_cassette('album:new_releases') do
80
+ RSpotify::Album.new_releases
81
+ end
82
+ expect(albums.size) .to eq 20
83
+ expect(albums.map(&:name)) .to include('A13', 'Singles', 'Magic')
84
+ end
85
+
86
+ it 'should accept additional options' do
87
+ albums = VCR.use_cassette('album:new_releases:limit:10:offset:10') do
88
+ RSpotify::Album.new_releases(limit: 10, offset: 10)
89
+ end
90
+ expect(albums.size) .to eq 10
91
+ expect(albums.map(&:name)) .to include('Recess', 'Atlas', 'Magic')
92
+
93
+ albums = VCR.use_cassette('album:new_releases:country:ES') do
94
+ RSpotify::Album.new_releases(country: 'ES')
95
+ end
96
+ expect(albums.size) .to eq 20
97
+ expect(albums.map(&:name)) .to include('Me Olvide de Vivir', 'Amor Futuro')
98
+ end
99
+ end
100
+
67
101
  describe 'Album::search' do
68
102
  it 'should search for the right albums' do
69
103
  albums = VCR.use_cassette('album:search:AM') do
@@ -93,6 +127,12 @@ describe RSpotify::Album do
93
127
  end
94
128
  expect(albums.size) .to eq 10
95
129
  expect(albums.map(&:name)) .to include('Melody AM')
130
+
131
+ albums = VCR.use_cassette('album:search:AM:market:ES') do
132
+ RSpotify::Album.search('AM', market: 'ES')
133
+ end
134
+ ES_albums = albums.select { |a| a.available_markets.include?('ES') }
135
+ expect(ES_albums.length).to eq(albums.length)
96
136
  end
97
137
  end
98
138
  end
@@ -102,6 +102,12 @@ describe RSpotify::Artist do
102
102
  end
103
103
  expect(artists.size) .to eq 10
104
104
  expect(artists.map(&:name)) .to include('Arctic Flame')
105
+
106
+ artists = VCR.use_cassette('artist:search:Arctic:market:ES') do
107
+ RSpotify::Artist.search('Arctic', market: 'ES')
108
+ end
109
+ expect(artists.size) .to eq 20
110
+ expect(artists.map(&:name)) .to include('Arctic Queen', 'Arctic Sleep')
105
111
  end
106
112
  end
107
113
  end
@@ -10,11 +10,41 @@ describe RSpotify::Playlist do
10
10
  end
11
11
 
12
12
  before do
13
- VCR.use_cassette('authenticate:5ac1cda2ad354aeaa1ad2693d33bb98c') do
13
+ VCR.use_cassette('authenticate:client') do
14
14
  RSpotify.authenticate(client_id, client_secret)
15
15
  end
16
16
  end
17
17
 
18
+ describe 'Playlist::browse_featured' do
19
+ it 'should find the appropriate featured playlists' do
20
+ playlists = VCR.use_cassette('playlist:browse_featured') do
21
+ RSpotify::Playlist.browse_featured
22
+ end
23
+ expect(playlists.size) .to eq 13
24
+ expect(playlists.map(&:name)) .to include('Dance Mega Mix', 'Peaceful Piano', 'Sleep')
25
+ end
26
+
27
+ it 'should accept additional options' do
28
+ playlists = VCR.use_cassette('playlist:browse_featured:limit:10:offset:10') do
29
+ RSpotify::Playlist.browse_featured(limit: 10, offset: 10)
30
+ end
31
+ expect(playlists.size) .to eq 3
32
+ expect(playlists.map(&:name)) .to include('Sleep', 'Late Night R&B')
33
+
34
+ playlists = VCR.use_cassette('playlist:browse_featured:locale:es_MX') do
35
+ RSpotify::Playlist.browse_featured(locale: 'es_MX')
36
+ end
37
+ expect(playlists.size) .to eq 13
38
+ expect(playlists.map(&:name)) .to include('Dance Mega Mix', 'Peaceful Piano', 'Sleep')
39
+
40
+ playlists = VCR.use_cassette('playlist:browse_featured:country:ES:timestamp:2014-10-23T09:00:00') do
41
+ RSpotify::Playlist.browse_featured(country: 'ES', timestamp: '2014-10-23T09:00:00')
42
+ end
43
+ expect(playlists.size) .to eq 17
44
+ expect(playlists.map(&:name)) .to include('En el trabajo', 'En las Nubes')
45
+ end
46
+ end
47
+
18
48
  describe 'Playlist::find' do
19
49
 
20
50
  let(:playlist) do
@@ -92,6 +92,12 @@ describe RSpotify::Track do
92
92
  end
93
93
  expect(tracks.size) .to eq 10
94
94
  expect(tracks.map(&:name)) .to include('They Wanna Know')
95
+
96
+ tracks = VCR.use_cassette('track:search:Wanna Know:market:ES') do
97
+ RSpotify::Track.search('Wanna Know', market: 'ES')
98
+ end
99
+ ES_tracks = tracks.select { |t| t.available_markets.include?('ES') }
100
+ expect(ES_tracks.length).to eq(tracks.length)
95
101
  end
96
102
  end
97
103
  end
@@ -6,7 +6,7 @@ describe RSpotify::User do
6
6
  # Get wizzler user as a testing sample
7
7
  @user = VCR.use_cassette('user:find:wizzler') do
8
8
  RSpotify::User.find('wizzler')
9
- end
9
+ end
10
10
  end
11
11
 
12
12
  it 'should find user with correct attributes' do
@@ -21,7 +21,7 @@ describe RSpotify::User do
21
21
  # Keys generated specifically for the tests. Should be removed in the future
22
22
  client_id = '5ac1cda2ad354aeaa1ad2693d33bb98c'
23
23
  client_secret = '155fc038a85840679b55a1822ef36b9b'
24
- VCR.use_cassette('authenticate:5ac1cda2ad354aeaa1ad2693d33bb98c') do
24
+ VCR.use_cassette('authenticate:client') do
25
25
  RSpotify.authenticate(client_id, client_secret)
26
26
  end
27
27
 
@@ -0,0 +1,148 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://api.spotify.com/v1/browse/new-releases?limit=20&offset=0
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ accept:
11
+ - "*/*; q=0.5, application/xml"
12
+ accept-encoding:
13
+ - gzip, deflate
14
+ authorization:
15
+ - Bearer BQCXC1A5_dYyPER__Z_Ow0oqWTLV3cGeipaHUyQEVPgRMIenGpkKsUcmOf6eG_Uth_eDXKvI-9v-NdL7judXOg
16
+ user-agent:
17
+ - Ruby
18
+ response:
19
+ status:
20
+ code: 200
21
+ message: OK
22
+ headers:
23
+ server:
24
+ - nginx
25
+ date:
26
+ - Sat, 22 Nov 2014 00:55:49 GMT
27
+ content-type:
28
+ - application/json; charset=utf-8
29
+ transfer-encoding:
30
+ - chunked
31
+ connection:
32
+ - keep-alive
33
+ keep-alive:
34
+ - timeout=600
35
+ vary:
36
+ - Accept-Encoding
37
+ cache-control:
38
+ - private, max-age=0
39
+ access-control-allow-headers:
40
+ - Accept, Authorization, Origin, Content-Type
41
+ access-control-allow-origin:
42
+ - "*"
43
+ access-control-max-age:
44
+ - '604800'
45
+ access-control-allow-methods:
46
+ - GET, POST, OPTIONS, PUT, DELETE
47
+ access-control-allow-credentials:
48
+ - 'true'
49
+ x-content-type-options:
50
+ - nosniff
51
+ strict-transport-security:
52
+ - max-age=31536000;
53
+ content-encoding:
54
+ - gzip
55
+ body:
56
+ encoding: ASCII-8BIT
57
+ string: !binary |-
58
+ H4sIAAAAAAAAA+1caU8jSbb9Pr8ixYc3PVJPV+xLS6MnoNjXwVAU1Rq1YgUX
59
+ xqawzVKj/u/vZBqoanDiwiSo+lFCChk7HBlO3zi+99xz73//VhQzruOHJ/2Z
60
+ 4tfiv/gXTxydpVz+O3M0GJz2f33zxp22f+mf9gbtfPVL6J28Oadv/Fnvop/e
61
+ dNPFP89SJ7l+6v9vL+d+GvyL/E+nfdIe/IuRmZ9HC7YHaXSB364vcXPV3wdX
62
+ p6m6VL/dPeyk6zeUL5+7dsf5Tvr9xJ0dp0G1v9+Kmdm3Mz9j3KnG3WrcK8e5
63
+ pWrcqsbq1fnZalyuxvVqrF6dH716UD3+UI5vF6pxrRqrOQvz1Vg9v9Aqx8WV
64
+ aqzeuzQaq6svV+9a3qzGaicr1btWqnetVHPWq/eujx6/Kx9vVOtvVM9svK/G
65
+ aj+b1czNag+b1d62q0+xXa25XX2W7eqzbFfv3a7etVPNb1V3oFWt0Kp21aqu
66
+ tVvtdne/HPcOZor/jL4U3ON0OUhnXdf5fXjW+er7r2zg+uv+kxn0TlP3T3ZQ
67
+ Wc4bRU7O99YHB+3N1s7J6bvznuM7C2Km+uqL4o/by32LWY1ssW7J26XasdpY
68
+ zZW/TDtxh+nacka2PbLv1D48GpQrKEFuJuMz4zb86fPC6EPswuLftMuF3hgl
69
+ mCEsUu4kl4ImTrk2NHAhGXUkck6sdS7cWjHWvGjHwdH1pW7vyO0pKA/b7WY4
70
+ ecxmFKcpiSipIpxwl43SkkqjhdSeekKs1IlIasduBpeasBklHnFjovaaCiII
71
+ idbISJkVeIoIER310gufA3FJjd+LEjdb+co0u+5khAv7qZg9S8VWNxU/bXXw
72
+ oOP+Ufy2e4RHObdD23UKRqgoFlcWZ4v93lknFvPD06LV6x7+5wua3MJMZV9f
73
+ nh+etUfoMwK3X6uXf60xq2qbf/xcC2F31n40glVn/EVxbK684pPQrEK89W/B
74
+ tAq1pkS26s58E75VqPssKCdW339uX+1vdi43RG/7govtjY/vPj4J5WqWvIty
75
+ E6c1i3JCB8WEdRzYIrRkOWjDkxKOZaEVpT4kpZzwY4EFgDoBWB6Hco6x6GNk
76
+ 0spMqRDGkuSZst5bHoK2VLDMtNJjN9MwygXqo5CEyqgcZUICeJ0xiXAAv7KW
77
+ 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
146
+ http_version: '1.1'
147
+ recorded_at: Sat, 22 Nov 2014 00:55:49 GMT
148
+ recorded_with: VCR 2.9.3