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.
@@ -0,0 +1,33 @@
1
+ using StringHelper
2
+
3
+ module Napster
4
+ module Models
5
+ # LibraryDateTime model
6
+ # Only used for /me/library/updated
7
+ class LibraryDateTime
8
+ ATTRIBUTES = [:date,
9
+ :time_zone,
10
+ :time_in_millis].freeze
11
+
12
+ ATTRIBUTES.each do |attribute|
13
+ attr_accessor attribute
14
+ end
15
+
16
+ attr_accessor :client
17
+
18
+ def initialize(arg)
19
+ @client = arg[:client] if arg[:client]
20
+ return unless arg[:data]
21
+ ATTRIBUTES.each do |attribute|
22
+ send("#{attribute}=", arg[:data][attribute.to_s.camel_case_lower])
23
+ end
24
+ end
25
+
26
+ def self.collection(arg)
27
+ arg[:data].map do |library_date_time|
28
+ LibraryDateTime.new(data: library_date_time, client: @client)
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,124 @@
1
+ using StringHelper
2
+
3
+ module Napster
4
+ module Models
5
+ # Member model
6
+ class Member
7
+ ATTRIBUTES = [:type,
8
+ :id,
9
+ :real_name,
10
+ :screen_name,
11
+ :bio,
12
+ :location,
13
+ :genre,
14
+ :visibility,
15
+ :href,
16
+ :favorite_albums_count,
17
+ :favorite_artists_count,
18
+ :favorite_tracks_count,
19
+ :playlists_total_count,
20
+ :playlists_published_count,
21
+ :stations_count,
22
+ :radio_count,
23
+ :follower_count,
24
+ :following_count,
25
+ :avatar,
26
+ :avatar_id,
27
+ :default_avatar,
28
+ :avatar_version].freeze
29
+
30
+ ATTRIBUTES.each do |attribute|
31
+ attr_accessor attribute
32
+ end
33
+
34
+ attr_accessor :client
35
+
36
+ def initialize(arg)
37
+ @client = arg[:client] if arg[:client]
38
+ return unless arg[:data]
39
+
40
+ ATTRIBUTES.each do |attribute|
41
+ send("#{attribute}=", arg[:data][attribute.to_s.camel_case_lower])
42
+ end
43
+ end
44
+
45
+ def self.collection(arg)
46
+ arg[:data].map do |member|
47
+ Member.new(data: member, client: @client)
48
+ end
49
+ end
50
+
51
+ # Top level methods
52
+
53
+ def find(arg)
54
+ response = @client.get("/members/#{arg}")
55
+ Member.new(data: response['members'].first, client: @client)
56
+ end
57
+
58
+ def screenname_available?(screenname)
59
+ response = @client.get("/screenname/#{screenname}")
60
+ response['screenName'].nil?
61
+ end
62
+
63
+ # TODO: .avatar
64
+
65
+ def playlists(params)
66
+ request_playlists(@id, params)
67
+ end
68
+
69
+ def playlists_for(guid, params)
70
+ request_playlists(guid, params)
71
+ end
72
+
73
+ def favorites(params)
74
+ request_favorites(@id, params)
75
+ end
76
+
77
+ def favorites_for(guid, params)
78
+ request_favorites(guid, params)
79
+ end
80
+
81
+ def favorite_playlists(params)
82
+ request_favorite_playlists(@id, params)
83
+ end
84
+
85
+ def favorite_playlists_for(guid, params)
86
+ request_favorite_playlists(guid, params)
87
+ end
88
+
89
+ def chart(params)
90
+ request_chart(@id, params)
91
+ end
92
+
93
+ def chart_for(guid, params)
94
+ request_chart(guid, params)
95
+ end
96
+
97
+ private
98
+
99
+ def request_playlists(guid, params)
100
+ options = { params: params }
101
+ response = @client.get("/members/#{guid}/library/playlists", options)
102
+ Playlist.collection(data: response['playlists'], client: @client)
103
+ end
104
+
105
+ def request_favorites(guid, params)
106
+ options = { params: params }
107
+ response = @client.get("/members/#{guid}/favorites", options)
108
+ Favorite.collection(data: response['favorites'], client: @client)
109
+ end
110
+
111
+ def request_favorite_playlists(guid, params)
112
+ options = { params: params }
113
+ response = @client.get("/members/#{guid}/favorites/playlists", options)
114
+ Playlist.collection(data: response['playlists'], client: @client)
115
+ end
116
+
117
+ def request_chart(guid, params)
118
+ options = { params: params }
119
+ response = @client.get("/members/#{guid}/charts", options)
120
+ Chart.collection(data: response['charts'], client: @client)
121
+ end
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,279 @@
1
+ using StringHelper
2
+
3
+ module Napster
4
+ module Models
5
+ # Playlist model
6
+ class Playlist
7
+ ATTRIBUTES = [:type,
8
+ :id,
9
+ :name,
10
+ :modified,
11
+ :href,
12
+ :privacy,
13
+ :images,
14
+ :description,
15
+ :favorite_count,
16
+ :free_play_compliant].freeze
17
+
18
+ ATTRIBUTES.each do |attribute|
19
+ attr_accessor attribute
20
+ end
21
+
22
+ attr_accessor :client
23
+
24
+ def initialize(arg)
25
+ @client = arg[:client] if arg[:client]
26
+ return unless arg[:data]
27
+
28
+ ATTRIBUTES.each do |attribute|
29
+ send("#{attribute}=", arg[:data][attribute.to_s.camel_case_lower])
30
+ end
31
+ end
32
+
33
+ def self.collection(arg)
34
+ arg[:data].map do |playlist|
35
+ Playlist.new(data: playlist, client: @client)
36
+ end
37
+ end
38
+
39
+ # Top level methods
40
+
41
+ def playlists_of_the_day(params)
42
+ response = @client.get('/playlists', params: params)
43
+ Playlist.collection(data: response['playlists'], client: @client)
44
+ end
45
+
46
+ def featured(params)
47
+ response = @client.get('/playlists/featured', params: params)
48
+ Playlist.collection(data: response['playlists'], client: @client)
49
+ end
50
+
51
+ def find(id)
52
+ e = 'Invalid playlist id'
53
+ raise ArgumentError, e unless Napster::Moniker.check(id, :playlist)
54
+
55
+ return authenticated_find(id) if @client.access_token
56
+
57
+ response = @client.get("/playlists/#{id}")
58
+ Playlist.new(data: response['playlists'].first, client: @client)
59
+ end
60
+
61
+ # Instance methods
62
+
63
+ def tracks(params)
64
+ return authenticated_tracks(params) if @client.access_token
65
+
66
+ hash = { params: params }
67
+ response = @client.get("/playlists/#{@id}/tracks", hash)
68
+ Track.collection(data: response['tracks'], client: @client)
69
+ end
70
+
71
+ def tags
72
+ return authenticated_tags if @client.access_token
73
+
74
+ response = @client.get("/playlists/#{@id}/tags")
75
+ Tag.collection(data: response['tags'], client: @client)
76
+ end
77
+
78
+ # /me
79
+
80
+ def all(params)
81
+ get_options = {
82
+ params: params,
83
+ headers: {
84
+ Authorization: 'Bearer ' + @client.access_token,
85
+ 'Content-Type' => 'application/json',
86
+ 'Accept-Version' => '2.0.0'
87
+ }
88
+ }
89
+ response = @client.get('/me/library/playlists', get_options)
90
+ Playlist.collection(data: response['playlists'])
91
+ end
92
+
93
+ def authenticated_find(playlist_id)
94
+ path = "/me/library/playlists/#{playlist_id}"
95
+ get_options = {
96
+ headers: {
97
+ Authorization: 'Bearer ' + @client.access_token,
98
+ 'Content-Type' => 'application/json',
99
+ 'Accept-Version' => '2.0.0'
100
+ }
101
+ }
102
+ response = @client.get(path, get_options)
103
+ return nil if response['playlists'].empty?
104
+
105
+ Playlist.new(data: response['playlists'].first, client: @client)
106
+ end
107
+
108
+ def authenticated_tracks(params)
109
+ path = "/me/library/playlists/#{@id}/tracks"
110
+ options = {
111
+ params: params,
112
+ headers: {
113
+ Authorization: 'Bearer ' + @client.access_token,
114
+ 'Content-Type' => 'application/json',
115
+ 'Accept-Version' => '2.0.0'
116
+ }
117
+ }
118
+ response = @client.get(path, options)
119
+ return [] if response['tracks'].empty?
120
+
121
+ Track.collection(data: response['tracks'], client: @client)
122
+ end
123
+
124
+ def create(playlist_hash)
125
+ body = Oj.dump('playlists' => playlist_hash)
126
+ path = '/me/library/playlists'
127
+ options = {
128
+ headers: {
129
+ Authorization: 'Bearer ' + @client.access_token,
130
+ 'Content-Type' => 'application/json',
131
+ 'Accept-Version' => '2.0.0'
132
+ }
133
+ }
134
+ response = @client.post(path, body, options)
135
+ Playlist.new(data: response['playlists'].first, client: @client)
136
+ end
137
+
138
+ def update(playlist_id, playlist_hash)
139
+ body = Oj.dump('playlists' => playlist_hash)
140
+ path = "/me/library/playlists/#{playlist_id}"
141
+ options = {
142
+ headers: {
143
+ Authorization: 'Bearer ' + @client.access_token,
144
+ 'Content-Type' => 'application/json',
145
+ 'Accept-Version' => '2.0.0'
146
+ }
147
+ }
148
+ response = @client.put(path, body, options)
149
+ Playlist.new(data: response['playlists'].first, client: @client)
150
+ end
151
+
152
+ def delete(playlist_id)
153
+ path = "/me/library/playlists/#{playlist_id}"
154
+ options = {
155
+ headers: {
156
+ Authorization: 'Bearer ' + @client.access_token,
157
+ 'Content-Type' => 'application/json',
158
+ 'Accept-Version' => '2.0.0'
159
+ }
160
+ }
161
+ @client.delete(path, options)
162
+ end
163
+
164
+ def set_private(playlist_id, boolean)
165
+ e = 'The argument should be a boolean value.'
166
+ raise ArgumentError, e unless [true, false].include?(boolean)
167
+
168
+ privacy_value = boolean ? 'private' : 'public'
169
+ body = Oj.dump('privacy' => privacy_value)
170
+ path = "/me/library/playlists/#{playlist_id}/privacy"
171
+ options = {
172
+ headers: {
173
+ Authorization: 'Bearer ' + @client.access_token,
174
+ 'Content-Type' => 'application/json',
175
+ 'Accept-Version' => '2.0.0'
176
+ }
177
+ }
178
+ @client.put(path, body, options)
179
+ end
180
+
181
+ def add_tracks(playlist_id, tracks)
182
+ tracks = tracks.map { |track| { 'id' => track } }
183
+ body = Oj.dump('tracks' => tracks)
184
+ path = "/me/library/playlists/#{playlist_id}/tracks"
185
+ options = {
186
+ headers: {
187
+ Authorization: 'Bearer ' + @client.access_token,
188
+ 'Content-Type' => 'application/json',
189
+ 'Accept-Version' => '2.0.0'
190
+ }
191
+ }
192
+ @client.post(path, body, options)
193
+ end
194
+
195
+ def authenticated_tags
196
+ return [] if @id
197
+ path = "/me/library/playlists/#{playlist_id}/tags"
198
+ options = {
199
+ headers: {
200
+ Authorization: 'Bearer ' + @client.access_token,
201
+ 'Content-Type' => 'application/json',
202
+ 'Accept-Version' => '2.0.0'
203
+ }
204
+ }
205
+ response = @client.get(path, options)
206
+ return [] if response['tags']
207
+ Tag.collection(data: response['tags'], client: @client)
208
+ end
209
+
210
+ def recommended_tracks(playlist_id)
211
+ options = {
212
+ params: { playlistId: playlist_id },
213
+ headers: {
214
+ Authorization: 'Bearer ' + @client.access_token,
215
+ 'Content-Type' => 'application/json',
216
+ 'Accept-Version' => '2.0.0'
217
+ }
218
+ }
219
+ response = @client.get('/me/recommendations/tracks', options)
220
+ Track.collection(data: response['tracks'], client: @client)
221
+ end
222
+
223
+ def uploaded_images(options)
224
+ return uploaded_images_with_size(options) if options.class == Fixnum
225
+ e = 'Playlist ID is missing.'
226
+ playlist_id = options[:id] ? options[:id] : @id
227
+ raise ArgumentError, e unless playlist_id
228
+
229
+ path = "/me/library/playlists/#{playlist_id}/images"
230
+ options = {
231
+ headers: {
232
+ Authorization: 'Bearer ' + @client.access_token,
233
+ 'Content-Type' => 'application/json',
234
+ 'Accept-Version' => '2.0.0'
235
+ }
236
+ }
237
+ options[:params] = { size: options[:size] } if options[:size]
238
+ response = @client.get(path, options)
239
+ UploadedImage.collection(data: response['images'], client: @client)
240
+ end
241
+
242
+ def sourced_by(sourced, params)
243
+ sourced_error = 'sourced argument should be a string'
244
+ params_error = 'params argument should be a hash'
245
+ raise ArgumentError, sourced_error unless sourced.class == String
246
+ raise ArgumentError, params_error unless params.class == Hash
247
+
248
+ path = '/me/search/playlists'
249
+ options = {
250
+ params: params,
251
+ headers: {
252
+ Authorization: 'Bearer ' + @client.access_token,
253
+ 'Content-Type' => 'application/json',
254
+ 'Accept-Version' => '2.0.0'
255
+ }
256
+ }
257
+ options[:params][:source] = sourced
258
+ response = @client.get(path, options)
259
+ Playlist.collection(data: response['playlists'], client: @client)
260
+ end
261
+
262
+ private
263
+
264
+ def uploaded_images_with_size(size)
265
+ path = "/me/library/playlists/#{@id}/images"
266
+ options = {
267
+ params: { size: size },
268
+ headers: {
269
+ Authorization: 'Bearer ' + @client.access_token,
270
+ 'Content-Type' => 'application/json',
271
+ 'Accept-Version' => '2.0.0'
272
+ }
273
+ }
274
+ response = @client.get(path, options)
275
+ UploadedImage.collection(data: response['images'], client: @client)
276
+ end
277
+ end
278
+ end
279
+ end
@@ -0,0 +1,75 @@
1
+ using StringHelper
2
+
3
+ module Napster
4
+ module Models
5
+ # Profile model
6
+ class Profile
7
+ ATTRIBUTES = [:id,
8
+ :real_name,
9
+ :screen_name,
10
+ :bio,
11
+ :location,
12
+ :gender,
13
+ :visibility,
14
+ :type,
15
+ :href,
16
+ :favorite_albums_count,
17
+ :favorite_artists_count,
18
+ :favorite_tracks_count,
19
+ :playlists_total_count,
20
+ :playlists_published_count,
21
+ :stations_count,
22
+ :radio_count,
23
+ :follower_count,
24
+ :following_count,
25
+ :avatar,
26
+ :avatar_id,
27
+ :default_avatar,
28
+ :avatar_version,
29
+ :links].freeze
30
+
31
+ ATTRIBUTES.each do |attribute|
32
+ attr_accessor attribute
33
+ end
34
+
35
+ attr_accessor :client
36
+
37
+ def initialize(arg)
38
+ @client = arg[:client] if arg[:client]
39
+ return unless arg[:data]
40
+ ATTRIBUTES.each do |attribute|
41
+ send("#{attribute}=", arg[:data][attribute.to_s.camel_case_lower])
42
+ end
43
+ end
44
+
45
+ def self.collection(arg)
46
+ arg[:data].map do |profile|
47
+ Profile.new(data: profile, client: @client)
48
+ end
49
+ end
50
+
51
+ def get
52
+ get_options = {
53
+ headers: {
54
+ Authorization: 'Bearer ' + @client.access_token,
55
+ 'Content-Type' => 'application/json',
56
+ 'Accept-Version' => '2.0.0'
57
+ }
58
+ }
59
+ response = @client.get('/me', get_options)
60
+ Profile.new(data: response['me'], client: @client)
61
+ end
62
+
63
+ def update(body)
64
+ put_options = {
65
+ headers: {
66
+ Authorization: 'Bearer ' + @client.access_token,
67
+ 'Content-Type' => 'application/json',
68
+ 'Accept-Version' => '2.0.0'
69
+ }
70
+ }
71
+ @client.put('/me', Oj.dump(body), put_options)
72
+ end
73
+ end
74
+ end
75
+ end