napster 0.0.0 → 0.1.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: 0532d69a5aadf0f93bdef73a06c70612705f7843
4
- data.tar.gz: 267c689350304c2cadfa9ab92df6e1237ed83c99
3
+ metadata.gz: 0f53597ca1c82bbe5dfdff89de0e2430077ff4c9
4
+ data.tar.gz: ac674709f442f4de9b040bad17ca6021766533c8
5
5
  SHA512:
6
- metadata.gz: 52bcd887818637ee98a66af6976ec7edcca337fce2fdfb0b582706f5a81a01e4f211c13d8d570270fcd067e3172c923061e047b7155cb12848e2797cc119d460
7
- data.tar.gz: 9abfbd14b16241c3e83929d6a4a669647b3fa8ab3e02899ef2484b7f6972334a8aa5d0404c10f709838dcd9558899fc9458ac2ecb7da54f1f51e3ae16c4f2285
6
+ metadata.gz: f7e5b49b0b9990cad7a882d29dfa086a9a9647622c930ae80c92ed6456f40950ec9d1ccfed09ec22c75037328c5b32652c0a89aa94ab1d3ab8e7b030e9086399
7
+ data.tar.gz: 5b7a4b1e5b93c1f727db9262c2a5ed10e7052500e3ccec7740ec9133fa1420229a9df487eaaa92736985acdefe22a788d31d118fc71766d63d7825efbefbb84b
data/.gitignore CHANGED
@@ -1,9 +1,43 @@
1
- /.bundle/
2
- /.yardoc
3
- /Gemfile.lock
4
- /_yardoc/
1
+ *.gem
2
+ *.lock
3
+ *.rbc
4
+ /.config
5
5
  /coverage/
6
- /doc/
6
+ /InstalledFiles
7
7
  /pkg/
8
8
  /spec/reports/
9
+ /spec/examples.txt
10
+ /test/tmp/
11
+ /test/version_tmp/
9
12
  /tmp/
13
+
14
+ ## Specific to RubyMotion:
15
+ .dat*
16
+ .repl_history
17
+ build/
18
+
19
+ ## Documentation cache and generated files:
20
+ /.yardoc/
21
+ /_yardoc/
22
+ /doc/
23
+ /rdoc/
24
+
25
+ ## Environment normalization:
26
+ /.bundle/
27
+ /vendor/bundle
28
+ /lib/bundler/man/
29
+
30
+ # for a library or gem, you might want to ignore these files since the code is
31
+ # intended to run in multiple environments; otherwise, check them in:
32
+ # Gemfile.lock
33
+ # .ruby-version
34
+ # .ruby-gemset
35
+
36
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
37
+ .rvmrc
38
+
39
+ ## Configs
40
+ spec/config.yml
41
+
42
+ ## RBENV related
43
+ .ruby-version
data/.rubocop.yml ADDED
@@ -0,0 +1,4 @@
1
+ ClassLength:
2
+ Max: 300
3
+ MethodLength:
4
+ Max: 20
data/README.md CHANGED
@@ -1,8 +1,19 @@
1
- # Napster
1
+ <!-- TODO: Move this SVG to Dev Portal assets when we have more assets. Right now it's in Dropbox :) -->
2
+ <a href="http://developer.napster.com/">
3
+ <img src="https://dl.dropboxusercontent.com/s/bfydqpzisetm7y3/napster.svg?dl=0" alt="Napster Logo" title="Napster API" align="right" width=150 height=150/>
4
+ </a>
2
5
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/napster`. To experiment with that code, run `bin/console` for an interactive prompt.
6
+ <!--
7
+ Put Badges here when we have them:
8
+ [![Build Status](https://travis-ci.org/)
9
+ -->
10
+ <!--
11
+ TODO: Add this link to the top when we change name of Google Forum
12
+ **Got a question?** Let us know via the Napster API [google forum](https://groups.google.com/forum/#!forum/rhapsody-api).
13
+ -->
14
+ # Napster Gem
4
15
 
5
- TODO: Delete this and the text above, and describe your gem
16
+ A Ruby interface to the [Napster API](https://developer.napster.com/).
6
17
 
7
18
  ## Installation
8
19
 
@@ -20,22 +31,339 @@ Or install it yourself as:
20
31
 
21
32
  $ gem install napster
22
33
 
34
+ ### Ruby version
35
+
36
+ Ruby version should be 2.0 or greater.
37
+
23
38
  ## Usage
24
39
 
25
- TODO: Write usage instructions here
40
+ ### Setting up a client
41
+
42
+ A **client** prepares you to make calls to Napster API.
43
+ Here is an example code for setting up a client using
44
+ [implicit method](https://developer.napster.com/api#authentication).
45
+
46
+ ``` ruby
47
+ require 'napster'
48
+
49
+ options = {
50
+ api_key: 'API_KEY',
51
+ api_secret: 'API_SECRET',
52
+ }
53
+
54
+ client = Napster::Client.new(options)
55
+ ```
56
+
57
+ You can still set up a client with just an access token. However, you will
58
+ not be able to refresh the access token and you won't be able to make any
59
+ metadata calls. Only authenticated member calls will be allowed with this
60
+ client.
61
+
62
+ ``` ruby
63
+ options = { access_token: 'ACCESS_TOKEN' }
64
+ client = Napster::Client.new(options)
65
+ ```
66
+
67
+ ### Getting an access token
68
+
69
+ #### Password grant
70
+
71
+ ##### Method 1
72
+
73
+ ```ruby
74
+ client_hash = {
75
+ api_key: 'API_KEY',
76
+ api_secret: 'API_SECRET',
77
+ username: 'USERNAME',
78
+ password: 'PASSWORD'
79
+ }
80
+
81
+ # Just by instantiating with api_key, api_secret, username, and password
82
+ # you can authenticate by password_grant.
83
+ client = Napster::Client.new(client_hash)
84
+
85
+ client.authentication.access_token # => returns access_token
86
+ client.authentication.refresh_token
87
+ client.authentication.expires_in
88
+ ```
89
+
90
+ ##### Method 2
91
+
92
+ ```ruby
93
+ client_hash = {
94
+ api_key: 'API_KEY',
95
+ api_secret: 'API_SECRET'
96
+ }
97
+
98
+ client = Napster::Client.new(client_hash)
99
+ client.username = 'USERNAME'
100
+ client.password = 'PASSWORD'
101
+ client.connect
102
+
103
+ client.authentication.access_token # => returns access_token
104
+ client.authentication.refresh_token
105
+ client.authentication.expires_in
106
+ ```
107
+
108
+ #### OAuth 2
109
+
110
+ ```ruby
111
+ client_hash = {
112
+ api_key: 'API_KEY',
113
+ api_secret: 'API_SECRET',
114
+ redirect_uri: 'REDIRECT_URI',
115
+ auth_code: 'AUTH_CODE'
116
+ }
117
+
118
+ client = Napster::Client.new(client_hash)
119
+ client.connect
120
+
121
+ client.authentication.access_token # => returns access_token
122
+ client.authentication.refresh_token
123
+ client.authentication.expires_in
124
+ ```
125
+
126
+ ### Refresh an access token
127
+
128
+ Napster API's `access_token` expires in 24 hours after it is issued.
129
+ You need to use the `refresh_token` to generate a new `access_token` when
130
+ it is expired.
131
+
132
+ *It is not recommended to get a new access_token - refresh_token
133
+ through authentication after the old access_token expires.*
134
+
135
+ ```ruby
136
+ client.refresh # => returns new access_token by refreshing it
137
+ ```
138
+
139
+ ### Making Requests
140
+
141
+ #### Metadata API
142
+
143
+ Metadata endpoints do not need the client to be authenticated.
144
+ First, set up a client with `api_key` and `api_secret`.
145
+ Then you can call metadata endpoints following this pattern.
146
+
147
+ ```ruby
148
+ # takes a form of client.[resources].[method]
149
+
150
+ # albums
151
+ client.albums.new_releases(limit: 10)
152
+ client.albums.staff_picks(limit: 10)
153
+ client.albums.top(limit: 10)
154
+ client.albums.find(artist_id) # => returns an album
155
+ client.albums.find(artist_name) # => returns an album
156
+ client.albums.find(artist_id).tracks(limit: 10) # => returns an album
157
+ client.albums.find(artist_name).tracks(limit: 10) # => returns an album
158
+
159
+ # artists
160
+ client.artists.top(limit: 5)
161
+ client.artists.find(artist_id) # => returns an artist
162
+ client.artists.find(artist_name) # => returns an artist
163
+ client.artists.find(artist_id).albums(offset: 5)
164
+ client.artists.find(artist_id).new_albums(offset: 5)
165
+ client.artists.find(artist_id).tracks(limit: 5)
166
+ client.artists.find(artist_id).top_tracks(limit: 5)
167
+
168
+ # favorites
169
+ client.favorites.members_who_favorited_albums('Alb.5153820')
170
+ client.favorites.members_who_favorited_artists('Art.954')
171
+ client.favorites.member_favorites_for('Tra.5156528')
172
+
173
+ # members
174
+ client.members.playlists_for('D877082A5CBC5AC7E040960A390313EF', limit: 2)
175
+ client.members.favorites_for('D877082A5CBC5AC7E040960A390313EF', limit: 2)
176
+ client.members.favorite_playlists_for('D877082A5CBC5AC7E040960A390313EF', limit: 2)
177
+ client.members.chart_for('D877082A5CBC5AC7E040960A390313EF', limit: 2)
178
+ client.members.find('D877082A5CBC5AC7E040960A390313EF')
179
+ client.members.find('dduda')
180
+ client.members.screenname_available?('dduda')
181
+ client.members.find('dduda').playlists(limit: 5)
182
+ client.members.find('dduda').favorites(limit: 5)
183
+ client.members.find('dduda').favorite_playlists(limit: 5)
184
+ client.members.find('dduda').chart(limit: 5)
185
+
186
+ # playlists
187
+ client.playlists.playlists_of_the_day(limit: 3)
188
+ client.playlists.featured(limit: 3)
189
+ client.playlists.find('pp.125821370')
190
+ client.playlists.find('pp.125821370').tracks(limit: 10)
191
+ client.playlists.find('pp.125821370').tags
192
+
193
+ # tags
194
+ client.tags.all
195
+ client.tags.find('tag.156763217')
196
+
197
+ # tracks
198
+ client.tracks.find('Tra.5156528')
199
+ client.tracks.find_by_name('Marvins Room')
200
+ ```
201
+
202
+ #### Authenticated Member API
203
+
204
+ Authenticated member endpoints require the client to be authenticated.
205
+ First, set up a client with `api_key` and `api_secret`.
206
+ Authenticate the client by going through password grant method or
207
+ OAuth2 method.
208
+ Ensure that the client has access_token and refresh_token.
209
+ Then you can call metadata endpoints following this pattern.
210
+
211
+ ```ruby
212
+ # takes a form of client.me.[resources].[method]
213
+
214
+ # favorites
215
+ client.me.favorites.get(limit: 5)
216
+ client.me.favorites.status(['Art.954', 'Alb.5153820', 'Tra.5156528'])
217
+ client.me.favorites.add(['Art.954', 'Alb.5153820', 'Tra.5156528'])
218
+ client.me.favorites.remove('Art.954')
219
+
220
+ # followers
221
+ client.me.followers.members(limit: 5)
222
+ client.me.followers.by?(guids)
223
+
224
+ # following
225
+ client.me.following.members(limit: 5)
226
+ client.me.following.by?(guids)
227
+ client.me.following.follow(guids)
228
+ client.me.following.unfollow(guids)
229
+
230
+ # library
231
+ client.me.library.artists(limit: 10)
232
+ client.me.library.artist_albums('Art.954', limit: 10)
233
+ client.me.library.artist_tracks('Art.954', limit: 10)
234
+ client.me.library.albums(limit: 10)
235
+ client.me.library.album_tracks('Alb.5153820', limit: 10)
236
+ client.me.library.tracks(limit: 10)
237
+ client.me.library.add_track(['Tra.5156528'])
238
+ client.me.library.remove_track('Tra.5156528')
239
+ client.me.library.last_updated_date
240
+
241
+ # listening history
242
+ client.me.listening_history(limit: 10)
243
+
244
+ # playlists
245
+ client.me.playlists.all(limit: 10)
246
+ client.me.playlists.create({ 'name' => 'hiphop playlist' })
247
+ client.me.playlists.find('mp.123123')
248
+ client.me.playlists.update('mp.123123', { 'name' => 'hiphop playlist 2' })
249
+ client.me.playlists.delete('mp.123123')
250
+ client.me.playlists.set_private('mp.123123', 'public')
251
+ client.me.playlists.set_private('mp.123123', 'private')
252
+ client.me.playlists.add_tracks('mp.123123', ['Tra.5156528'])
253
+ client.me.playlists.recommended_tracks('mp.123123')
254
+ client.me.playlists.uploaded_images(id: 'mp.123123', size: 500) # id and size in px
255
+ client.me.playlists.sourced_by('my_own_playlists',
256
+ { artists: ['art.123', 'art.234'], tags: ['tag.123', 'tag.234'], guid: 'xyz', sort: 'alpha_asc', include_private: true, limit: 10, offset: 5})
257
+ client.me.playlists.find('mp.123123').tracks(limit: 10)
258
+ client.me.playlists.find('mp.123123').tags
259
+ client.me.playlists.find('mp.123123').uploaded_images(500) # size in px
260
+
261
+ # profile
262
+ client.me.profile.get
263
+ client.me.profile.update({ 'me' => { 'bio' => Faker::Lorem.word } })
264
+
265
+ # tags
266
+ client.me.tags.contents('favorite', '', {})
267
+ ```
268
+
269
+ #### Query Parameters
270
+
271
+ ```ruby
272
+ client.artists.top(limit: 5, offset: 5)
273
+ ```
274
+
275
+ #### Request body for PUT / POST
276
+
277
+ ```ruby
278
+ request_hash = {
279
+ body: {
280
+ name: 'name of the playlist',
281
+ tags: ['tag.1', 'tag.2'],
282
+ privacy: 'public',
283
+ tracks: ['tra.1', 'tra.2']
284
+ }
285
+ }
286
+ client.me.create_playlist(request_hash)
287
+ ```
288
+
289
+ #### Error Handling
290
+
291
+ Napster gem provides `ResponseError` which wraps response errors from Napster
292
+ API. You can inspect error attributes as shown below.
293
+
294
+ ```ruby
295
+ begin
296
+ client.playlists.find('pp.125821370').tracks({}) # problematic request
297
+ rescue Exception => error
298
+ puts error.http_status # => 400
299
+ puts error.response_body
300
+ # => {"code":"BadRequestError","message":"limit query parameter is required"}
301
+ puts error.faraday_response.inspect
302
+ # => #<Faraday::Response:0x007fe9bc957150 @on_complete_callbacks=[], ...
303
+ end
304
+ ```
305
+
306
+ <!--
307
+ ### Versioning
308
+
309
+ The Napster gem supports Napster API version 2.x and above only.
310
+ When the client does not specify the version, it'll use the latest
311
+ Napster API version.
312
+
313
+ #### Versioned client
314
+
315
+ You can set client to always use a specific version of Napster API.
316
+
317
+ ```ruby
318
+ client.version = 'v2.1'
319
+ client.artists.top # returns top artists using v2.1
320
+ ```
321
+
322
+ #### Making one-off versioned request
323
+
324
+ Even though the client already has a version set, you can still make
325
+ one-off calls to a different version of Napster API.
326
+
327
+ ```ruby
328
+ client.version = 'v2.1'
329
+ client.v2_2.artists.top # returns top artists using v2.2
330
+ client.artists.top # returns top artists using v2.1
331
+ ```
332
+ -->
26
333
 
27
334
  ## Development
28
335
 
29
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
336
+ ### Running tests
30
337
 
31
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
338
+ Napster gem uses RSpec and FactoryGirl.
32
339
 
33
- ## Contributing
340
+ 1. Get the API key and API secret from
341
+ [Napster Developers site](https://developer.napster.com/).
342
+
343
+ 2. Create a file called `config.yml` in `spec` directory.
344
+
345
+ 3. Add the following with the correct API key and API secret
34
346
 
35
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/napster.
347
+ ``` yml
348
+ config_variables:
349
+ API_KEY: 'API_KEY'
350
+ API_SECRET: 'API_SECRET'
351
+ USERNAME: 'USERNAME'
352
+ PASSWORD: 'PASSWORD'
353
+ REDIRECT_URI: 'REDIRECT_URI'
354
+ ```
355
+
356
+ 4. `$ bundle install`
357
+
358
+ 5. `$ rspec`
359
+
360
+
361
+ ## Contributing
36
362
 
363
+ Bug reports and pull requests are welcome on GitHub at https://github.com/napster/napster-ruby.
37
364
 
38
365
  ## License
39
366
 
40
367
  The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
41
368
 
369
+ Napster and Napster logo are registered and unregistered trademarks of Rhapsody International in the United States and/or other countries. All company, product and service names used in this website are for identification purposes only. All product names, logos, and brands are property of their respective owners.
data/Rakefile CHANGED
@@ -1,6 +1,6 @@
1
- require "bundler/gem_tasks"
2
- require "rspec/core/rake_task"
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
3
 
4
4
  RSpec::Core::RakeTask.new(:spec)
5
5
 
6
- task :default => :spec
6
+ task default: :spec
data/bin/console CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require "bundler/setup"
4
- require "napster"
3
+ require 'bundler/setup'
4
+ require 'napster'
5
5
 
6
6
  # You can add fixtures and/or initialization code here to make experimenting
7
7
  # with your gem easier. You can also use a different console, if you like.
@@ -10,5 +10,5 @@ require "napster"
10
10
  # require "pry"
11
11
  # Pry.start
12
12
 
13
- require "irb"
13
+ require 'irb'
14
14
  IRB.start