rdio 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
data/lib/rdio/api.rb CHANGED
@@ -82,13 +82,14 @@ module Rdio
82
82
  end
83
83
 
84
84
  # Fetch one or more objects from Rdio.
85
- def get(objs,type=nil)
85
+ def get(objs,type=nil,extras=nil)
86
86
  if not objs.is_a? Array
87
87
  objs = [objs]
88
88
  end
89
89
  method = 'get'
90
90
  cls = type
91
91
  args = {:keys=>keys(objs)}
92
+ args[:extras] = extras if extras
92
93
  json = call method,args
93
94
  if Rdio::log_json
94
95
  Rdio::log "json: #{json}"
@@ -103,7 +104,8 @@ module Rdio
103
104
  type = ActivityStream
104
105
  args = {:user=>user,:scope=>scope}
105
106
  args[:last_id] = last_id if last_id
106
- return_object type,method,args
107
+ auth = user
108
+ return_object type,method,args,auth
107
109
  end
108
110
 
109
111
  # Return the albums by (or featuring) an artist.
@@ -124,7 +126,8 @@ module Rdio
124
126
  type = Album
125
127
  args = {:artist=>artist}
126
128
  args[:user] = user if user
127
- return_object type,method,args
129
+ auth = !!user
130
+ return_object type,method,args,auth
128
131
  end
129
132
 
130
133
  # Get all of the albums in the user's collection.
@@ -137,7 +140,8 @@ module Rdio
137
140
  args[:count] = count if count
138
141
  args[:sort] = sort if sort
139
142
  args[:query] = query if query
140
- return_object type,method,args
143
+ auth = !!user
144
+ return_object type,method,args,auth
141
145
  end
142
146
 
143
147
  # Get all of the artist in a user's collection.
@@ -150,7 +154,8 @@ module Rdio
150
154
  args[:count] = count if count
151
155
  args[:sort] = sort if sort
152
156
  args[:query] = query if query
153
- return_object type,method,args
157
+ auth = !!user
158
+ return_object type,method,args,auth
154
159
  end
155
160
 
156
161
  # Find the most popular artists or albums for a user, their friends
@@ -310,8 +315,54 @@ module Rdio
310
315
 
311
316
  # Search for artists, albums, tracks, users or all kinds of objects.
312
317
  def search(query,types=nil,never_or=nil,extras=nil,start=nil,count=nil)
318
+ result = search_json query,types,never_or,extras,start,count
319
+ return result if not result
320
+ results = result['results'] || []
321
+ api = self
322
+ #
323
+ # This start out nil, because we need to reference classes in
324
+ # types.rb and this gets loaded after this file. There's
325
+ # probably a better way to do this.
326
+ #
327
+ if not @@types2classes
328
+ @@types2classes = {
329
+ 'r' => Artist,
330
+ 'a' => Album,
331
+ 's' => User,
332
+ 't' => Track,
333
+ 'p' => Playlist
334
+ }
335
+ end
336
+ results.map {|o| @@types2classes[o['type']].new(api).fill o}
337
+ end
338
+
339
+ def counts(query,types=nil,never_or=nil,extras=nil,start=nil,count=nil)
340
+ obj = search_json query,types,never_or,extras,start,count
341
+ return JSONObj.new obj
342
+ end
343
+
344
+ # Match the supplied prefix against artists, albums, tracks and
345
+ # people in the Rdio system. Return the first ten matches.
346
+ def searchSuggestions(query,extras)
347
+ method = 'searchSuggestions'
348
+ type = TODO
349
+ args = {:query=>query}
350
+ args[:extras] = extras if extras
351
+ return_object type,method,args
352
+ end
353
+
354
+ private
355
+
356
+ # Initialize this after types.rb has been loaded (this stinks!)
357
+ @@types2classes = nil
358
+
359
+ # Search for artists, albums, tracks, users or all kinds of objects.
360
+ def search_json(query,types=nil,never_or=nil,extras=nil,start=nil,count=nil)
313
361
  method = 'search'
314
362
  type = TODO
363
+ if not types
364
+ types = 'Artist,Album,Track,Playlist,User'
365
+ end
315
366
  args = {:query=>query}
316
367
  args[:types] = types if types
317
368
  args[:never_or] = never_or if never_or
@@ -323,18 +374,7 @@ module Rdio
323
374
  if Rdio::log_json
324
375
  Rdio::log json
325
376
  end
326
- obj = unwrap_json json
327
- return JSONObj.new obj
328
- end
329
-
330
- # Match the supplied prefix against artists, albums, tracks and
331
- # people in the Rdio system. Return the first ten matches.
332
- def searchSuggestions(query,extras)
333
- method = 'searchSuggestions'
334
- type = TODO
335
- args = {:query=>query}
336
- args[:extras] = extras if extras
337
- return_object type,method,args
377
+ return unwrap_json json
338
378
  end
339
379
 
340
380
  end
data/lib/rdio/base.rb CHANGED
@@ -1,14 +1,39 @@
1
1
  require 'rubygems'
2
2
  require 'json'
3
3
 
4
+ # Make sure objects return 'self' by default to 'to_k', then we can
5
+ # override this for subsequent types -- like Artist, Track, etc --
6
+ # that need to use their key for this value
4
7
  class Object
5
8
  def to_k
6
9
  return self
7
10
  end
8
11
  end
9
12
 
13
+ # When putting classes into arguments to BaseApi.call we want to use a
14
+ # classes simple name for the argument value
15
+ class Class
16
+ def to_k
17
+ name.gsub /.*\:\:/,''
18
+ end
19
+ end
20
+
10
21
  module Rdio
11
22
 
23
+ # Adds 'str' to the array or string 'arr'
24
+ def add_to_array(arr,str)
25
+ if arr == nil
26
+ return [str.to_s]
27
+ end
28
+ if arr == ''
29
+ return [str.to_s]
30
+ end
31
+ if arr.is_a? Array
32
+ return arr + [str.to_s]
33
+ end
34
+ return arr.to_s + ',' + str.to_s
35
+ end
36
+
12
37
  # string -> string
13
38
  #
14
39
  # Converts camel-case string to underscore-delimited one.
@@ -26,7 +51,15 @@ module Rdio
26
51
  s
27
52
  end
28
53
 
54
+ # hash -> hash
55
+ #
56
+ # Uses the value of 'to_k' for all the iput hash values in the
57
+ # result hash. This is used to make sure that the arguments passed
58
+ # to create urls use keys for the values of objects like Artist,
59
+ # Track, etc. Also, we use the simple name of classes.
60
+ #
29
61
  def convert_args(args)
62
+ return nil if not args
30
63
  res = {}
31
64
  args.each do |k,v|
32
65
  if v.is_a? Array
@@ -39,8 +72,13 @@ module Rdio
39
72
  return res
40
73
  end
41
74
 
75
+ # array -> string
76
+ #
77
+ # Creates a ','-separated string of the value of 'to_k' from all the
78
+ # values in 'objs'. We also remove the nils from the input array.
79
+ #
42
80
  def keys(objs)
43
- objs.map {|x| x.to_k}.join ','
81
+ (not objs) ? '' : objs.compact.map {|x| x.to_k}.join(',')
44
82
  end
45
83
 
46
84
  # object -> value
@@ -49,7 +87,7 @@ module Rdio
49
87
  # can have primitives other than strings as attributes of BaseObjs.
50
88
  #
51
89
  def to_o(v)
52
- if not v
90
+ if v == nil
53
91
  return nil
54
92
  end
55
93
  s = v.to_s
@@ -59,7 +97,7 @@ module Rdio
59
97
  if s == 'nil'
60
98
  return nil
61
99
  end
62
- if s =~ /^\d+/
100
+ if s =~ /^\d+$/
63
101
  return s.to_i
64
102
  end
65
103
  if s =~ /^\d+\.?\d*$/
@@ -79,9 +117,11 @@ module Rdio
79
117
  return s
80
118
  end
81
119
 
82
- # Override this to declare how certain attributes are constructed.
83
- # This is done at the end of types.rb.
84
120
  class << self
121
+ #
122
+ # Override this to declare how certain attributes are constructed.
123
+ # This is done at the end of types.rb.
124
+ #
85
125
  attr_accessor :symbols_to_types
86
126
  end
87
127
  self.symbols_to_types = {}
@@ -116,11 +156,7 @@ module Rdio
116
156
  # Allow simple types that are used for arrays
117
157
  #
118
158
  if v.is_a? Array
119
- o = v.map do |x|
120
- obj = type.new api
121
- obj.fill x
122
- obj
123
- end
159
+ o = v.map {|x| type.new(api).fill x}
124
160
  else
125
161
  o = type.new api
126
162
  o.fill v
@@ -132,10 +168,11 @@ module Rdio
132
168
  sym_eq = (camel2underscores(k)+'=').to_sym
133
169
  self.send sym_eq,o
134
170
  rescue Exception => e
135
- STDERR.puts "Couldn't find symbol: " +
171
+ Rdio::logger.warn "Couldn't find symbol: " +
136
172
  "#{sym} => #{o} for type: #{self.class}"
137
173
  end
138
174
  end
175
+ self
139
176
  end
140
177
 
141
178
  end
@@ -181,8 +218,7 @@ module Rdio
181
218
 
182
219
  # Compares only by key
183
220
  def eql?(that)
184
- self.class.equal?(that.class) and
185
- self.key.equal?(that.key)
221
+ self.class.equal? that.class and self.key.equal? that.key
186
222
  end
187
223
 
188
224
  def to_k
@@ -198,12 +234,29 @@ module Rdio
198
234
  # ----------------------------------------------------------------------
199
235
  class BaseApi
200
236
 
237
+ PATH = '/1/'
238
+
239
+ attr_reader :oauth
240
+
201
241
  def initialize(key,secret)
202
242
  @oauth = RdioOAuth.new key,secret
203
243
  @access_token_auth = nil
204
244
  @access_token_no_auth = nil
205
245
  end
206
246
 
247
+ # (string -> string) -> (string -> string)
248
+ #
249
+ # Sets the function that will return a pin given an authorization
250
+ # url for the contained RdioOAuth instance
251
+ #
252
+ def get_pin=(get_pin)
253
+ @oauth.get_pin = get_pin
254
+ end
255
+
256
+ def get_pin
257
+ @oauth.get_pin
258
+ end
259
+
207
260
  def call(method,args,requires_auth=false)
208
261
  #
209
262
  # Convert object with keys just to use their keys
@@ -217,7 +270,7 @@ module Rdio
217
270
  args.each do |k,v|
218
271
  new_args[k] = v.to_k.to_s
219
272
  end
220
- url = '/1/'
273
+ url = PATH
221
274
  if Rdio::log_posts
222
275
  Rdio::log "Post to url=#{url} method=#{method} args=#{args}"
223
276
  end
data/lib/rdio/oauth.rb CHANGED
@@ -1,6 +1,5 @@
1
1
  require 'rubygems'
2
2
  require 'oauth'
3
- require 'open-uri'
4
3
 
5
4
  module Rdio
6
5
 
@@ -10,10 +9,39 @@ module Rdio
10
9
  class RdioOAuth
11
10
 
12
11
  SITE = 'http://api.rdio.com'
12
+
13
+ # string[url] -> string
14
+ #
15
+ # Set this to allow a different way to enter the pin found for
16
+ # authorization. By default it will open a browser and repeatedly
17
+ # ask the user for input from the console.
18
+ #
19
+ attr_accessor :get_pin
13
20
 
14
21
  def initialize(key,secret)
15
22
  @key = key
16
23
  @secret = secret
24
+ @get_pin = lambda do |url|
25
+
26
+ # Try to open using launchy, then if this doesn't work us open
27
+ begin
28
+ require 'rubygems'
29
+ require 'launchy'
30
+ Launchy.open url
31
+ rescue Exception => e
32
+ Rdio::log.error e
33
+ Rdio::log.info 'Install the \'launchy\' gem to avoid this error'
34
+ system 'open',url
35
+ end
36
+
37
+ oauth_verifier = nil
38
+ while not oauth_verifier or oauth_verifier == ''
39
+ print 'Enter the 4-digit PIN> '
40
+ STDOUT.flush
41
+ oauth_verifier = gets.strip
42
+ end
43
+ return oauth_verifier
44
+ end
17
45
  end
18
46
 
19
47
  def access_token(requires_auth=false)
@@ -36,17 +64,11 @@ module Rdio
36
64
  :authorize_path => "/oauth/authorize",
37
65
  :access_token_path => "/oauth/access_token",
38
66
  :http_method => :post})
39
-
67
+ consumer.http.read_timeout = 600
40
68
  request_token = consumer.get_request_token({:oauth_callback => 'oob'})
41
69
  url = 'https://www.rdio.com/oauth/authorize?oauth_token=' +
42
- request_token.token.to_s
43
- system 'open',url
44
-
45
- oauth_verifier = nil
46
- while not oauth_verifier or oauth_verifier == ''
47
- print 'Enter the PIN> '
48
- oauth_verifier = gets.strip
49
- end
70
+ request_token.token.to_s
71
+ oauth_verifier = @get_pin.call url
50
72
  request_token.get_access_token({:oauth_verifier => oauth_verifier})
51
73
  end
52
74
  end
data/lib/rdio/types.rb CHANGED
@@ -27,6 +27,14 @@ module Rdio
27
27
 
28
28
  attr_accessor :tracks
29
29
 
30
+ attr_accessor :album_keys
31
+
32
+ # Returns an array of Album for the query and other params
33
+ def self.search(query,never_or=nil,extras=nil,start=nil,count=nil)
34
+ extras = add_to_array extras,'artists'
35
+ Search.search query,Artist,never_or,extras,start,count
36
+ end
37
+
30
38
  # Get all of the tracks by this artist.
31
39
  def tracks(appears_on=nil,start=nil,count=nil,extras=nil)
32
40
  api.getTracksForArtist self,appears_on,start,count,extras
@@ -43,13 +51,13 @@ module Rdio
43
51
  end
44
52
 
45
53
  # Fetch one or more objects from Rdio of type Artist.
46
- def self.all(keys)
47
- Rdio::api.get keys,Artist
54
+ def self.all(keys,extras=nil)
55
+ Rdio::api.get keys,Artist,extras
48
56
  end
49
57
 
50
58
  # Fetch one object from Rdio of type Artist.
51
- def self.get(key)
52
- arr = all [key]
59
+ def self.get(key,extras=nil)
60
+ arr = all [key],extras
53
61
  (arr and not arr.empty?) ? arr[0] : nil
54
62
  end
55
63
 
@@ -97,14 +105,45 @@ module Rdio
97
105
  # the tracks
98
106
  attr_accessor :tracks
99
107
 
108
+ # is the album explicit?
109
+ def explicit?
110
+ is_explicit
111
+ end
112
+
113
+ # is the album clean
114
+ def clean?
115
+ is_clean
116
+ end
117
+
118
+ # Returns the Artist
119
+ def artist
120
+ Artist.get artist_key
121
+ end
122
+
123
+ # Returns the String artist name
124
+ def artist_name
125
+ @artist
126
+ end
127
+
128
+ # Return an array of Track
129
+ def tracks(extras=nil)
130
+ Track.all @tracks,extras
131
+ end
132
+
133
+ # Returns an array of Album for the query and other params
134
+ def self.search(query,never_or=nil,extras=nil,start=nil,count=nil)
135
+ extras = add_to_array extras,'albums'
136
+ Search.search query,Album,never_or,extras,start,count
137
+ end
138
+
100
139
  # Fetch one or more objects from Rdio of type Album.
101
- def self.all(keys)
102
- Rdio::api.get keys,Album
140
+ def self.all(keys,extras=nil)
141
+ Rdio::api.get keys,Album,extras
103
142
  end
104
143
 
105
144
  # Fetch one object from Rdio of type Album.
106
- def self.get(key)
107
- arr = all [key]
145
+ def self.get(key,extras=nil)
146
+ arr = all [key],extras
108
147
  (arr and not arr.empty?) ? arr[0] : nil
109
148
  end
110
149
 
@@ -168,6 +207,42 @@ module Rdio
168
207
  # the secondary id
169
208
  attr_accessor :secondary_id
170
209
 
210
+ # Returns the Album
211
+ def album(extras=nil)
212
+ Album.get @album_key,extras
213
+ end
214
+
215
+ # Returns the Artist
216
+ def artist(extras=nil)
217
+ Artist.get @artist_key,extras
218
+ end
219
+
220
+ # Returns the album Artist
221
+ def album_artist(extras=nil)
222
+ Artist.get @album_artist_key,extras
223
+ end
224
+
225
+ # Returns the String album name
226
+ def album_name
227
+ @album
228
+ end
229
+
230
+ # Returns the string artist name
231
+ def artist_name
232
+ @artist
233
+ end
234
+
235
+ # Returns the string album artist name
236
+ def album_artist_name
237
+ @album_artist
238
+ end
239
+
240
+ # Returns an array of Track for the query and other params
241
+ def self.search(query,never_or=nil,extras=nil,start=nil,count=nil)
242
+ extras = add_to_array extras,'tracks'
243
+ Search.search query,Track,never_or,extras,start,count
244
+ end
245
+
171
246
  # Get all of the tracks in the user's collection.
172
247
  def self.in_collection(user=nil,start=nil,count=nil,sort=nil,query=nil)
173
248
  Rdio::api.getTracksInCollection user,start,count,sort,query
@@ -185,13 +260,13 @@ module Rdio
185
260
  end
186
261
 
187
262
  # Fetch one or more objects from Rdio of type Track.
188
- def self.all(keys)
189
- Rdio::api.get keys,Track
263
+ def self.all(keys,extras=nil)
264
+ Rdio::api.get keys,Track,extras
190
265
  end
191
266
 
192
267
  # Fetch one object from Rdio of type Track.
193
- def self.get(key)
194
- arr = all [key]
268
+ def self.get(key,extras=nil)
269
+ arr = all [key],extras
195
270
  return (arr and not arr.empty?) ? arr[0] : nil
196
271
  end
197
272
 
@@ -233,6 +308,11 @@ module Rdio
233
308
  api.removeFromPlaylist self,index,count,tracks
234
309
  end
235
310
 
311
+ # Returns an array of Playlist for the query and other params
312
+ def self.search(query,never_or=nil,extras=nil,start=nil,count=nil)
313
+ extras = add_to_array extras,'playlists'
314
+ Search.search query,Playlist,never_or,extras,start,count
315
+ end
236
316
 
237
317
  # Add a track to a playlist.
238
318
  def add_to_playlist(tracks)
@@ -252,13 +332,13 @@ module Rdio
252
332
  end
253
333
 
254
334
  # Fetch one or more objects from Rdio of type Playlist.
255
- def self.all(keys)
256
- Rdio::api.get keys,Playlist
335
+ def self.all(keys,extras=nil)
336
+ Rdio::api.get keys,Playlist,extras
257
337
  end
258
338
 
259
339
  # Fetch one object from Rdio of type Playlist.
260
- def self.get(key)
261
- arr = all [key]
340
+ def self.get(key,extras=nil)
341
+ arr = all [key],extras
262
342
  return (arr and not arr.empty?) ? arr[0] : nil
263
343
  end
264
344
 
@@ -296,6 +376,12 @@ module Rdio
296
376
  api.getActivityStream self,scope,last_id
297
377
  end
298
378
 
379
+ # Returns an array of User for the query and other params
380
+ def self.search(query,never_or=nil,extras=nil,start=nil,count=nil)
381
+ extras = add_to_array extras,'users'
382
+ Search.search query,User,never_or,extras,start,count
383
+ end
384
+
299
385
  # Get information about the currently logged in user.
300
386
  def self.current(extras=nil)
301
387
  Rdio::api.currentUser extras
@@ -317,19 +403,18 @@ module Rdio
317
403
  end
318
404
 
319
405
  # Fetch one or more objects from Rdio of type User.
320
- def self.all(keys)
321
- Rdio::api.get keys,User
406
+ def self.all(keys,extras=nil)
407
+ Rdio::api.get keys,User,extras
322
408
  end
323
409
 
324
410
  # Fetch one object from Rdio of type User.
325
- def self.get(key)
326
- arr = all [key]
411
+ def self.get(key,extras=nil)
412
+ arr = all [key],extras
327
413
  return (arr and not arr.empty?) ? arr[0] : nil
328
414
  end
329
415
 
330
416
  # Get all of the albums in the user's collection.
331
- def albums_in_collection(start=nil,count=nil,
332
- sort=nil,query=nil)
417
+ def albums_in_collection(start=nil,count=nil,sort=nil,query=nil)
333
418
  api.getAlbumsInCollection self,start,count,sort,query
334
419
  end
335
420
 
@@ -498,6 +583,13 @@ module Rdio
498
583
  # Wrapper for search
499
584
  class Search
500
585
 
586
+ # Search for 'query' and other parameters
587
+ def self.counts(query,types=nil,never_or=nil,extras=nil,start=nil,count=nil)
588
+ Rdio::api.counts query,types,never_or,extras,start,count
589
+ end
590
+
591
+ # Searches for objects with type 'type' and 'query' and other
592
+ # parameters
501
593
  def self.search(query,types=nil,never_or=nil,extras=nil,start=nil,count=nil)
502
594
  Rdio::api.search query,types,never_or,extras,start,count
503
595
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rdio
3
3
  version: !ruby/object:Gem::Version
4
- hash: 21
4
+ hash: 19
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 5
10
- version: 0.0.5
9
+ - 6
10
+ version: 0.0.6
11
11
  platform: ruby
12
12
  authors:
13
13
  - Jeffrey Palm
@@ -15,10 +15,25 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-03-19 00:00:00 -04:00
18
+ date: 2011-03-23 00:00:00 -04:00
19
19
  default_executable:
20
- dependencies: []
21
-
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: oauth
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 19
30
+ segments:
31
+ - 0
32
+ - 3
33
+ - 0
34
+ version: 0.3.0
35
+ type: :runtime
36
+ version_requirements: *id001
22
37
  description: Ruby implementation of rd.io REST api
23
38
  email: jeff@jeffpalm.com
24
39
  executables: []
@@ -38,7 +53,7 @@ files:
38
53
  - lib/rdio/datatypes.rb
39
54
  - lib/rdio/types.rb
40
55
  has_rdoc: true
41
- homepage: http://github.com/spudtrooper/rdio
56
+ homepage: http://github.com/spudtrooper/rdiorb
42
57
  licenses: []
43
58
 
44
59
  post_install_message:
@@ -64,8 +79,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
64
79
  segments:
65
80
  - 0
66
81
  version: "0"
67
- requirements: []
68
-
82
+ requirements:
83
+ - launchy gem to use authorized calls
69
84
  rubyforge_project: "%NAME"
70
85
  rubygems_version: 1.6.1
71
86
  signing_key: