rdio 0.0.96 → 0.0.98b

Sign up to get free protection for your applications and to get access to all the features.
data/README CHANGED
@@ -1,4 +1,4 @@
1
- -*- outline -*-
1
+ -*- org -*-
2
2
 
3
3
  * ABOUT
4
4
 
@@ -35,7 +35,7 @@ variables to the appropriate values:
35
35
  RDIO_KEY
36
36
  RDIO_SECRET
37
37
 
38
- You must also serialize an authrozied access token to the file
38
+ There is a sample .rc file in dot-rdio. You must also serialize an authorized access token to the file
39
39
  .rdio_access_token. This can be done with:
40
40
 
41
41
  make .rdio_access_token
@@ -44,3 +44,11 @@ You must also serialize an authrozied access token to the file
44
44
 
45
45
  ./create_access_token
46
46
 
47
+ There is a sample in dot-rdio_access_token.
48
+
49
+ * CONTRIBUTORS
50
+
51
+ Thanks for the pull requests that have been merged to the following:
52
+
53
+ - Scott Hyndman ( https://github.com/shyndman )
54
+ - Rick Fletcher ( https://github.com/rfletcher )
@@ -20,6 +20,17 @@ module Rdio
20
20
  attr_accessor :log_methods
21
21
  attr_accessor :log_symbols
22
22
  attr_accessor :log_posts
23
+ attr_accessor :log_fill
24
+ #
25
+ # Specific setting to turn off warnings like the following:
26
+ #
27
+ # Couldn't find symbol: radio_key => rr31531 for type: Rdio::Artist
28
+ #
29
+ # during tests, because we see it constantly and isn't really a
30
+ # problem. By default it is true, but it is turned off for all
31
+ # tests.
32
+ attr_accessor :log_couldnt_find_symbols
33
+
23
34
  def log(str)
24
35
  logger.debug { str }
25
36
  end
@@ -29,6 +40,8 @@ module Rdio
29
40
  self.log_methods = false
30
41
  self.log_symbols = false
31
42
  self.log_posts = false
43
+ self.log_couldnt_find_symbols = false
44
+ self.log_fill = false
32
45
 
33
46
  @logger ||= ::Logger.new(STDERR)
34
47
  @api = nil
@@ -89,7 +102,11 @@ require 'rdio/datatypes'
89
102
  require 'rdio/types'
90
103
  require 'rdio/call'
91
104
 
92
- # Silly syntax so you can say Rd::io...blah...blah...blah
105
+ # simple additions
106
+ require 'rdio/simple_om'
107
+ require 'rdio/simple_rdio'
108
+
109
+ # Silly syntax so you can say Rd::io.<method>
93
110
  module Rd
94
111
 
95
112
  # Returns the shared Rdio::Api instance from Rdio::api
@@ -148,7 +148,17 @@ module Rdio
148
148
 
149
149
  def fill(x)
150
150
  return self if not x
151
+ if Rdio::log_fill
152
+ Rdio::log "#{self.class}.fill #{x.class} : #{x}"
153
+ end
151
154
  syms_to_types = Rdio::symbols_to_types || {}
155
+ #
156
+ # https://github.com/spudtrooper/rdiorb/issues/9: Certain rubys
157
+ # don't declare 'each' on String. In this case and others where
158
+ # the key is a mapped type and the resulting body isn't a Hash,
159
+ # make x a Hash
160
+ #
161
+ x = {x => nil} if not x.is_a? Hash
152
162
  x.each do |k,v|
153
163
  sym = Rdio::camel2underscores(k).to_sym
154
164
  #
@@ -158,9 +168,9 @@ module Rdio
158
168
  #
159
169
  type = syms_to_types[sym]
160
170
  if Rdio::log_symbols
161
- Rdio::log "#{self.class}.#{sym} => #{type}"
171
+ Rdio::log "#{self.class}.#{sym} => #{type} v=#{v.class}"
162
172
  end
163
- if type
173
+ if type and v.is_a? Enumerable
164
174
  #
165
175
  # Allow simple types that are used for arrays
166
176
  #
@@ -177,8 +187,10 @@ module Rdio
177
187
  sym_eq = (Rdio::camel2underscores(k)+'=').to_sym
178
188
  self.send sym_eq,o
179
189
  rescue Exception => e
180
- Rdio::logger.warn "Couldn't find symbol: " +
181
- "#{sym} => #{o} for type: #{self.class}"
190
+ if Rdio::log_couldnt_find_symbols
191
+ Rdio::logger.warn "Couldn't find symbol: " +
192
+ "#{sym} => #{o} for type: #{self.class}"
193
+ end
182
194
  end
183
195
  end
184
196
  self
@@ -297,7 +309,15 @@ module Rdio
297
309
  if Rdio::log_posts
298
310
  Rdio::log "Post to url=#{url} method=#{method} args=#{args}"
299
311
  end
312
+ #
313
+ # For backwards compatibility the response may have a 'body'
314
+ # attribute or a tuple could be returned. Handle both cases.
315
+ #
300
316
  resp,data = access_token(requires_auth).post url,new_args
317
+ begin
318
+ return resp.body
319
+ rescue
320
+ end
301
321
  return data
302
322
  end
303
323
 
@@ -32,9 +32,9 @@ module Rdio
32
32
  require 'launchy'
33
33
  Launchy.open url
34
34
  rescue Exception => e
35
- Rdio::log.error e
36
- Rdio::log.info 'Install the \'launchy\' gem to avoid this error'
37
- Rdio::log.info 'Trying system \'open\''
35
+ Rdio::logger.error e
36
+ Rdio::logger.info 'Install the \'launchy\' gem to avoid this error'
37
+ Rdio::logger.info 'Trying system \'open\''
38
38
  system 'open',url
39
39
  end
40
40
 
@@ -0,0 +1,151 @@
1
+ # om is oauth-mini - a simple implementation of a useful subset of OAuth.
2
+ # It's designed to be useful and reusable but not general purpose.
3
+ #
4
+ # (c) 2011 Rdio Inc
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+
23
+ # A simple OAuth client implementation. Do less better.
24
+ # Here are the restrictions:
25
+ # - only HMAC-SHA1 is supported
26
+ # - only WWW-Authentiate form signatures are generated
27
+ #
28
+ # To sign a request:
29
+ # auth = om([consumer_key,consumer_secret], url, params)
30
+ # send Authorization: <auth>
31
+ # when POSTing <params> to <url>
32
+ # Optional additional arguments are:
33
+ # token = [oauth_token, oauth_token_secret]
34
+ # method = "POST"
35
+ # realm = "Realm-for-authorization-header"
36
+ #
37
+ # Changes by jeff@jeffpalm.com:
38
+ #
39
+ # - added module Rdio
40
+ #
41
+
42
+ require 'uri'
43
+ require 'cgi'
44
+ require 'digest'
45
+ require 'digest/sha1'
46
+
47
+ module Rdio
48
+
49
+ class OM
50
+
51
+ def self.om(consumer, url, post_params, token=nil, method='POST', realm=nil)
52
+ # A one-shot simple OAuth signature generator
53
+
54
+ # the method must be upper-case
55
+ method.upcase!
56
+
57
+ # we want params as an Array of name / value pairs
58
+ if post_params.is_a?(Array)
59
+ params = post_params
60
+ else
61
+ params = post_params.collect
62
+ end
63
+
64
+ # normalize the URL
65
+ url = URI.parse(url)
66
+ # scheme is lower-case
67
+ url.scheme = url.scheme.downcase
68
+ # remove username & password
69
+ url.user = url.password = nil
70
+ # host is lowercase
71
+ url.host.downcase!
72
+
73
+ # add URL params to the params
74
+ if url.query
75
+ CGI.parse(url.query).each { |k,vs| vs.each { |v| params.push([k,v]) } }
76
+ end
77
+
78
+ # remove the params and fragment
79
+ url.query = nil
80
+ url.fragment = nil
81
+
82
+ # add OAuth params
83
+ params = params + [
84
+ ['oauth_version', '1.0'],
85
+ ['oauth_timestamp', Time.now.to_i.to_s],
86
+ ['oauth_nonce', rand(1000000).to_s],
87
+ ['oauth_signature_method', 'HMAC-SHA1'],
88
+ ['oauth_consumer_key', consumer[0]],
89
+ ]
90
+
91
+ # the consumer secret is the first half of the HMAC-SHA1 key
92
+ hmac_key = consumer[1] + '&'
93
+
94
+ if token != nil
95
+ # include a token in params
96
+ params.push ['oauth_token', token[0]]
97
+ # and the token secret in the HMAC-SHA1 key
98
+ hmac_key += token[1]
99
+ end
100
+
101
+ # Sort lexicographically, first after key, then after value.
102
+ params.sort!
103
+ # escape the key/value pairs and combine them into a string
104
+ normalized_params = (params.collect {|p| percent_encode(p[0])+'='+percent_encode(p[1])}).join '&'
105
+
106
+ # build the signature base string
107
+ signature_base_string = (percent_encode(method) +
108
+ '&' + percent_encode(url.to_s) +
109
+ '&' + percent_encode(normalized_params))
110
+
111
+ # HMAC-SHA1
112
+ hmac = Digest::HMAC.new(hmac_key, Digest::SHA1)
113
+ hmac.update(signature_base_string)
114
+
115
+ # Calculate the digest base 64. Drop the trailing \n
116
+ oauth_signature = [hmac.digest].pack('m0').strip
117
+
118
+ # Build the Authorization header
119
+ if realm
120
+ authorization_params = [['realm', realm]]
121
+ else
122
+ authorization_params = []
123
+ end
124
+ authorization_params.push(['oauth_signature', oauth_signature])
125
+
126
+ # we only want certain params in the auth header
127
+ oauth_params = ['oauth_version', 'oauth_timestamp', 'oauth_nonce',
128
+ 'oauth_signature_method', 'oauth_signature',
129
+ 'oauth_consumer_key', 'oauth_token']
130
+ authorization_params.concat(params.select { |param| nil != oauth_params.index(param[0]) })
131
+
132
+ return 'OAuth ' + (authorization_params.collect {|param| '%s="%s"' % param}).join(', ')
133
+ end
134
+
135
+ def self.percent_encode(s)
136
+ chars = s.chars.map do |c|
137
+ if ((c >= '0' and c <= '9') or
138
+ (c >= 'A' and c <= 'Z') or
139
+ (c >= 'a' and c <= 'z') or
140
+ c == '-' or c == '.' or c == '_' or c == '~')
141
+ c
142
+ else
143
+ '%%%02X' % c[0]
144
+ end
145
+ end
146
+ chars.join
147
+ end
148
+
149
+ end
150
+
151
+ end
@@ -0,0 +1,87 @@
1
+ # (c) 2011 Rdio Inc
2
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
3
+ # of this software and associated documentation files (the "Software"), to deal
4
+ # in the Software without restriction, including without limitation the rights
5
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
6
+ # copies of the Software, and to permit persons to whom the Software is
7
+ # furnished to do so, subject to the following conditions:
8
+ #
9
+ # The above copyright notice and this permission notice shall be included in
10
+ # all copies or substantial portions of the Software.
11
+ #
12
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
17
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
18
+ # THE SOFTWARE.
19
+ #
20
+ # Changes by jeff@jeffpalm.com:
21
+ #
22
+ # - added module Rdio
23
+ # - changed class named from Rdio to SimpleRdio
24
+ #
25
+
26
+ require 'uri'
27
+ require 'net/http'
28
+ require 'cgi'
29
+ require 'json'
30
+
31
+ module Rdio
32
+
33
+ class SimpleRdio
34
+ # the consumer and token can be accessed
35
+ attr_accessor :consumer, :token
36
+
37
+ def initialize(consumer, token=nil)
38
+ @consumer = consumer
39
+ @token = token
40
+ end
41
+
42
+ def begin_authentication(callback_url)
43
+ # request a request token from the server
44
+ response = signed_post('http://api.rdio.com/oauth/request_token',
45
+ {'oauth_callback' => callback_url})
46
+ # parse the response
47
+ parsed = CGI.parse(response)
48
+ # save the token
49
+ @token = [parsed['oauth_token'][0], parsed['oauth_token_secret'][0]]
50
+ # return an URL that the user can use to authorize this application
51
+ return parsed['login_url'][0] + '?oauth_token=' + parsed['oauth_token'][0]
52
+ end
53
+
54
+ def complete_authentication(verifier)
55
+ # request an access token
56
+ response = signed_post('http://api.rdio.com/oauth/access_token',
57
+ {'oauth_verifier' => verifier})
58
+ # parse the response
59
+ parsed = CGI.parse(response)
60
+ # save the token
61
+ @token = [parsed['oauth_token'][0], parsed['oauth_token_secret'][0]]
62
+ end
63
+
64
+ def call(method, params={})
65
+ # make a copy of the dict
66
+ params = params.clone
67
+ # put the method in the dict
68
+ params['method'] = method
69
+ # call to the server and parse the response
70
+ return JSON.load(signed_post('http://api.rdio.com/1/', params))
71
+ end
72
+
73
+ private
74
+
75
+ def signed_post(url, params)
76
+ auth = OM::om(@consumer, url, params, @token)
77
+ url = URI.parse(url)
78
+ http = Net::HTTP.new(url.host, url.port)
79
+ req = Net::HTTP::Post.new(url.path, {'Authorization' => auth})
80
+ req.set_form_data(params)
81
+ res = http.request(req)
82
+ return res.body
83
+ end
84
+
85
+ end
86
+
87
+ end
@@ -30,7 +30,7 @@ module Rdio
30
30
 
31
31
  attr_accessor :album_keys
32
32
 
33
- # Returns an array of Album for the query and other params
33
+ # Returns an array of Artist for the query and other params
34
34
  def self.search(query,never_or=nil,extras=nil,start=nil,count=nil)
35
35
  extras = Rdio::add_to_array extras,'artists'
36
36
  Search.search query,Artist,never_or,extras,start,count
metadata CHANGED
@@ -1,13 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rdio
3
3
  version: !ruby/object:Gem::Version
4
- hash: 223
5
- prerelease:
4
+ hash: 419
5
+ prerelease: 6
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 96
10
- version: 0.0.96
9
+ - 98
10
+ - b
11
+ version: 0.0.98b
11
12
  platform: ruby
12
13
  authors:
13
14
  - Jeffrey Palm
@@ -15,7 +16,7 @@ autorequire:
15
16
  bindir: bin
16
17
  cert_chain: []
17
18
 
18
- date: 2011-08-15 00:00:00 Z
19
+ date: 2012-03-03 00:00:00 Z
19
20
  dependencies:
20
21
  - !ruby/object:Gem::Dependency
21
22
  name: oauth
@@ -52,6 +53,8 @@ files:
52
53
  - lib/rdio/datatypes.rb
53
54
  - lib/rdio/types.rb
54
55
  - lib/rdio/call.rb
56
+ - lib/rdio/simple_om.rb
57
+ - lib/rdio/simple_rdio.rb
55
58
  homepage: http://github.com/spudtrooper/rdiorb
56
59
  licenses: []
57
60
 
@@ -72,15 +75,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
72
75
  required_rubygems_version: !ruby/object:Gem::Requirement
73
76
  none: false
74
77
  requirements:
75
- - - ">="
78
+ - - ">"
76
79
  - !ruby/object:Gem::Version
77
- hash: 3
80
+ hash: 25
78
81
  segments:
79
- - 0
80
- version: "0"
82
+ - 1
83
+ - 3
84
+ - 1
85
+ version: 1.3.1
81
86
  requirements:
82
87
  - launchy gem to use authorized calls
83
- rubyforge_project: "%NAME"
88
+ rubyforge_project: rdio
84
89
  rubygems_version: 1.8.6
85
90
  signing_key:
86
91
  specification_version: 2