rdio-cli 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,18 @@
1
+ ## Contributing
2
+ In the spirit of [free software][free-sw], **everyone** is encouraged to help
3
+ improve this project.
4
+
5
+ ## Submitting a Pull Request
6
+ 1. [Fork the repository.][fork]
7
+ 2. [Create a topic branch.][branch]
8
+ 3. Add specs for your unimplemented feature or bug fix.
9
+ 4. Run `bundle exec rake spec`. If your specs pass, return to step 3.
10
+ 5. Implement your feature or bug fix.
11
+ 6. Run `bundle exec rake spec`. If your specs fail, return to step 5.
12
+ 7. Add, commit, and push your changes.
13
+ 8. [Submit a pull request.][pr]
14
+
15
+ [free-sw]: http://www.fsf.org/licensing/essays/free-sw.html
16
+ [fork]: http://help.github.com/fork-a-repo/
17
+ [branch]: http://learn.github.com/p/branching.html
18
+ [pr]: http://help.github.com/send-pull-requests/
data/LICENSE.md ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 Wynn Netherland
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,87 @@
1
+ # Rdio CLI
2
+
3
+ A simple command line interface for [Rdio][].
4
+
5
+ ## Installation
6
+
7
+ ```
8
+ gem install rdio-cli
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ Rdio CLI is powered by [GLI][] and has a Git-like (sub)command interface:
14
+
15
+ ```bash
16
+ $ rdio current
17
+ Now playing: All The Roadrunning / Mark Knopfler And Emmylou Harris / Real Live Roadrunning
18
+ ```
19
+
20
+ ```bash
21
+ $ rdio current "♫ %{track} ♫"
22
+ ♫ All The Roadrunning ♫
23
+ ```
24
+
25
+ ### Full usage help
26
+
27
+ ```shell
28
+
29
+ $ rdio help
30
+
31
+ NAME
32
+ rdio - Simple CLI for Rdio
33
+
34
+ SYNOPSIS
35
+ rdio [global options] command [command options] [arguments...]
36
+
37
+ VERSION
38
+ 0.0.1
39
+
40
+ GLOBAL OPTIONS
41
+ --access_secret=arg - (default: none)
42
+ --access_token=arg - (default: none)
43
+ --consumer_key=arg - (default: none)
44
+ --consumer_secret=arg - (default: none)
45
+ --help - Show this message
46
+ --version -
47
+
48
+ COMMANDS
49
+ authorize, auth - Authorize Rdio account
50
+ browse - Open the current track in Rdio player
51
+ current - Display the current track info
52
+ help - Shows a list of commands or help for one command
53
+ initconfig - Initialize the config file using current global options
54
+ link - Get a shareable link for the current track
55
+ mute - Mute the Rdio player
56
+ next - Skip to next track
57
+ pause - Pause the player
58
+ play - Plays the current track
59
+ previous, prev - Play previous track
60
+ quit, q - Quit Rdio
61
+ toggle - Toggle playback
62
+ user - Show the current Rdio user
63
+ version, v - Get CLI and application version info
64
+ volume, vol - Set volume for player
65
+ ```
66
+
67
+ ## TODO
68
+ * `[✓]` <del>Snag current track to collection</del>
69
+ * `[ ]` Snag current album to collection
70
+ * `[ ]` Create a playlist
71
+ * `[ ]` Follow a user
72
+ * `[ ]` Tail a user?
73
+
74
+ ## Credits
75
+
76
+ * Uses Rdio's [rdio-simple][] library for API access.
77
+ * Inspired by [Drew Stokes][]'s [Node version][node-rdio].
78
+
79
+ ## Copyright
80
+ Copyright (c) 2012 Wynn Netherland. See [LICENSE][] for details.
81
+
82
+ [rdio]: http://rdio.com
83
+ [LICENSE]: https://github.com/pengwynn/rdio-cli/blob/master/LICENSE.md
84
+ [rdio-simple]: https://github.com/rdio/rdio-simple
85
+ [Drew Stokes]: https://github.com/dstokes
86
+ [node-rdio]: https://github.com/dstokes/rdio-cli
87
+ [GLI]: https://github.com/davetron5000/gli
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rspec/core/rake_task'
5
+ RSpec::Core::RakeTask.new(:spec)
6
+
7
+ task :test => :spec
8
+ task :default => :spec
data/bin/rdio ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rdio'
3
+
4
+ exit Rdio.run(ARGV)
data/lib/api.rb ADDED
@@ -0,0 +1,82 @@
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
+ require 'om'
21
+ require 'uri'
22
+ require 'net/http'
23
+ require 'cgi'
24
+ require 'json'
25
+
26
+ class Api
27
+ # the consumer and token can be accessed
28
+ attr_accessor :consumer, :token
29
+
30
+ def initialize(consumer, token=nil)
31
+ @consumer = consumer
32
+ @token = token
33
+ end
34
+
35
+ def begin_authentication(callback_url)
36
+ # request a request token from the server
37
+ response = signed_post('http://api.rdio.com/oauth/request_token',
38
+ {'oauth_callback' => callback_url})
39
+ # parse the response
40
+ parsed = CGI.parse(response)
41
+ # save the token
42
+ @token = [parsed['oauth_token'][0], parsed['oauth_token_secret'][0]]
43
+ # return an URL that the user can use to authorize this application
44
+ return parsed['login_url'][0] + '?oauth_token=' + parsed['oauth_token'][0]
45
+ end
46
+
47
+ def complete_authentication(verifier)
48
+ # request an access token
49
+ response = signed_post('http://api.rdio.com/oauth/access_token',
50
+ {'oauth_verifier' => verifier})
51
+ # parse the response
52
+ parsed = CGI.parse(response)
53
+ # save the token
54
+ @token = [parsed['oauth_token'][0], parsed['oauth_token_secret'][0]]
55
+ end
56
+
57
+ def call(method, params={})
58
+ # make a copy of the dict
59
+ params = params.clone
60
+ # put the method in the dict
61
+ params['method'] = method
62
+ # call to the server and parse the response
63
+ return JSON.load(signed_post('http://api.rdio.com/1/', params))
64
+ end
65
+
66
+ private
67
+
68
+ def signed_post(url, params)
69
+ auth = om(@consumer, url, params, @token)
70
+ url = URI.parse(url)
71
+ http = Net::HTTP.new(url.host, url.port)
72
+ req = Net::HTTP::Post.new(url.path, {'Authorization' => auth})
73
+ req.set_form_data(params)
74
+ res = http.request(req)
75
+ return res.body
76
+ end
77
+
78
+ def method_missing(method, *params)
79
+ call(method.to_s, params[0])
80
+ end
81
+
82
+ end
data/lib/om.rb ADDED
@@ -0,0 +1,160 @@
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
+ require 'uri'
38
+ require 'cgi'
39
+ require 'digest'
40
+ require 'digest/sha1'
41
+
42
+ if not "".respond_to?(:encoding)
43
+ # ruby 1.8 doesn't know about unicode :(
44
+ require 'iconv'
45
+ # we will just check that bytes are valid UTF-8
46
+ $__om_utf8_checker = Iconv.new("UTF-8", "UTF-8")
47
+ end
48
+
49
+ def om(consumer, url, post_params, token=nil, method='POST', realm=nil, timestamp=nil, nonce=nil)
50
+ # A one-shot simple OAuth signature generator
51
+
52
+ # the method must be upper-case
53
+ method = method.upcase
54
+
55
+ # we want params as an Array of name / value pairs
56
+ if post_params.is_a?(Array)
57
+ params = post_params
58
+ else
59
+ params = post_params.collect { |x| x }
60
+ end
61
+
62
+ # we want those pairs to be strings
63
+ params = params.collect { |k,v| [k.to_s, v.to_s]}
64
+
65
+ # normalize the URL
66
+ url = URI.parse(url)
67
+ # scheme is lower-case
68
+ url.scheme = url.scheme.downcase
69
+ # remove username & password
70
+ url.user = url.password = nil
71
+ # host is lowercase
72
+ url.host = url.host.downcase
73
+
74
+ # add URL params to the params
75
+ if url.query
76
+ CGI.parse(url.query).each { |k,vs| vs.each { |v| params.push([k,v]) } }
77
+ end
78
+
79
+ # remove the params and fragment
80
+ url.query = nil
81
+ url.fragment = nil
82
+
83
+ # add OAuth params
84
+ params = params + [
85
+ ['oauth_version', '1.0'],
86
+ ['oauth_timestamp', timestamp || Time.now.to_i.to_s],
87
+ ['oauth_nonce', nonce || rand(1000000).to_s],
88
+ ['oauth_signature_method', 'HMAC-SHA1'],
89
+ ['oauth_consumer_key', consumer[0]],
90
+ ]
91
+
92
+ # the consumer secret is the first half of the HMAC-SHA1 key
93
+ hmac_key = consumer[1] + '&'
94
+
95
+ if token != nil
96
+ # include a token in params
97
+ params.push ['oauth_token', token[0]]
98
+ # and the token secret in the HMAC-SHA1 key
99
+ hmac_key += token[1]
100
+ end
101
+
102
+ def percent_encode(s)
103
+ if s.respond_to?(:encoding)
104
+ # Ruby 1.9 knows about encodings, convert the string to UTF-8
105
+ s = s.encode(Encoding::UTF_8)
106
+ else
107
+ # Ruby 1.8 does not, just check that it's valid UTF-8
108
+ begin
109
+ $__om_utf8_checker.iconv(s)
110
+ rescue Iconv::IllegalSequence => exception
111
+ throw ArgumentError.new("Non-UTF-8 string: "+s.inspect)
112
+ end
113
+ end
114
+ chars = s.bytes.map do |b|
115
+ c = b.chr
116
+ if ((c >= '0' and c <= '9') or
117
+ (c >= 'A' and c <= 'Z') or
118
+ (c >= 'a' and c <= 'z') or
119
+ c == '-' or c == '.' or c == '_' or c == '~')
120
+ c
121
+ else
122
+ '%%%02X' % b
123
+ end
124
+ end
125
+ chars.join
126
+ end
127
+
128
+ # Sort lexicographically, first after key, then after value.
129
+ params.sort!
130
+ # escape the key/value pairs and combine them into a string
131
+ normalized_params = (params.collect {|p| percent_encode(p[0])+'='+percent_encode(p[1])}).join '&'
132
+
133
+ # build the signature base string
134
+ signature_base_string = (percent_encode(method) +
135
+ '&' + percent_encode(url.to_s) +
136
+ '&' + percent_encode(normalized_params))
137
+
138
+ # HMAC-SHA1
139
+ hmac = Digest::HMAC.new(hmac_key, Digest::SHA1)
140
+ hmac.update(signature_base_string)
141
+
142
+ # Calculate the digest base 64. Drop the trailing \n
143
+ oauth_signature = [hmac.digest].pack('m0').strip
144
+
145
+ # Build the Authorization header
146
+ if realm
147
+ authorization_params = [['realm', realm]]
148
+ else
149
+ authorization_params = []
150
+ end
151
+ authorization_params.push(['oauth_signature', oauth_signature])
152
+
153
+ # we only want certain params in the auth header
154
+ oauth_params = ['oauth_version', 'oauth_timestamp', 'oauth_nonce',
155
+ 'oauth_signature_method', 'oauth_signature',
156
+ 'oauth_consumer_key', 'oauth_token']
157
+ authorization_params.concat(params.select { |param| nil != oauth_params.index(param[0]) })
158
+
159
+ return 'OAuth ' + (authorization_params.collect {|param| '%s="%s"' % param}).join(', ')
160
+ end
@@ -0,0 +1,3 @@
1
+ module Rdio
2
+ VERSION = '0.0.1'
3
+ end
data/lib/rdio.rb ADDED
@@ -0,0 +1,282 @@
1
+ require 'gli'
2
+ require 'yaml'
3
+ require 'launchy'
4
+
5
+ require 'api'
6
+ require 'rdio/version'
7
+ require 'highline/import'
8
+
9
+ module Rdio
10
+ extend GLI::App
11
+
12
+ program_desc 'Simple CLI for Rdio'
13
+
14
+ version Rdio::VERSION
15
+
16
+ def self.api
17
+ token = @access_token ? [@access_token, @access_secret] : nil
18
+ @api = Api.new \
19
+ [@consumer_key, @consumer_secret],
20
+ token
21
+ end
22
+
23
+ def self.authorize_api
24
+ url = api.begin_authentication('oob')
25
+ ask "Copy the four digit code from your browser. [ENTER] to continue. "
26
+ Launchy.open url
27
+ code = ask 'Code: '
28
+ @access_token, @access_secret = @api.complete_authentication(code)
29
+
30
+ write_config
31
+
32
+ say "You're all set. see `rdio help` for usage"
33
+ end
34
+
35
+ def self.rdio_config
36
+ {
37
+ :consumer_key => @consumer_key,
38
+ :consumer_secret => @consumer_secret,
39
+ :access_token => @access_token,
40
+ :access_secret => @access_secret
41
+ }
42
+ end
43
+
44
+ def self.write_config
45
+ p = File.join(File.expand_path(ENV['HOME']), '.rdio')
46
+ File.open(p, 'w' ) do |out|
47
+ YAML.dump rdio_config, out
48
+ end
49
+ end
50
+
51
+ def self.apple_script(cmd)
52
+ `osascript -e '#{cmd}'`
53
+ end
54
+
55
+ def self.tell_rdio(cmd)
56
+ apple_script "tell app \"Rdio\" to #{cmd}"
57
+ end
58
+
59
+ def self.current_track
60
+ tell_rdio('name of the current track').gsub(/\n/, '')
61
+ end
62
+
63
+ def self.current_artist
64
+ tell_rdio('artist of the current track').gsub(/\n/, '')
65
+ end
66
+
67
+ def self.current_album
68
+ tell_rdio('album of the current track').gsub(/\n/, '')
69
+ end
70
+
71
+ def self.display_track(text)
72
+ text = "Now playing: %{track} / %{artist} / %{album}" if text.nil?
73
+ say (text % {
74
+ :artist => current_artist,
75
+ :track => current_track,
76
+ :album => current_album
77
+ })
78
+ end
79
+
80
+ def self.set_volume(pct = 30)
81
+ tell_rdio "set the sound volume to #{pct}"
82
+ end
83
+
84
+ def self.rdio_url
85
+ path = tell_rdio 'rdio url of the current track'
86
+ "http://www.rdio.com#{path}"
87
+ end
88
+
89
+ def self.current_track_key
90
+ data = api.call 'getObjectFromUrl', { :url => rdio_url }
91
+
92
+ data['result']['key']
93
+ end
94
+
95
+ def self.add_to_collection(tracks)
96
+ tracks = Array(tracks)
97
+
98
+ api.call 'addToCollection', { :keys => tracks.join(',') }
99
+ end
100
+
101
+ config_file '.rdio'
102
+
103
+ flag :consumer_key
104
+ flag :consumer_secret
105
+ flag :access_token
106
+ flag :access_secret
107
+
108
+ desc 'Plays the current track'
109
+ command :play do |c|
110
+ c.action do |global_options,options,args|
111
+ tell_rdio "play"
112
+ end
113
+ end
114
+
115
+ desc 'Pause the player'
116
+ skips_pre
117
+ command :pause do |c|
118
+ c.action do |global_options,options,args|
119
+ tell_rdio "pause"
120
+ end
121
+ end
122
+
123
+ desc 'Toggle playback'
124
+ skips_pre
125
+ command :toggle do |c|
126
+ c.action do |global_options,options,args|
127
+ tell_rdio "playpause"
128
+ end
129
+ end
130
+
131
+ desc 'Display the current track info'
132
+ long_desc %(
133
+ Display current track, artist, and album info. Pass
134
+ format string for custom output using
135
+ %{track}, %{artist}, and %{album} placeholders.
136
+ )
137
+ arg_name 'format'
138
+ skips_pre
139
+ command :current do |c|
140
+ c.action do |global_options,options,args|
141
+ display_track args.first
142
+ end
143
+ end
144
+
145
+ desc 'Skip to next track'
146
+ skips_pre
147
+ command :next do |c|
148
+ c.action do |global_options,options,args|
149
+ tell_rdio "next track"
150
+ end
151
+ end
152
+
153
+ desc 'Play previous track'
154
+ skips_pre
155
+ command :previous, :prev do |c|
156
+ c.action do |global_options,options,args|
157
+ tell_rdio "previous track"
158
+ end
159
+ end
160
+
161
+ desc 'Open the current track in Rdio player'
162
+ skips_pre
163
+ command :browse do |c|
164
+ c.action do |global_options,options,args|
165
+ exec "open '#{rdio_url}'"
166
+ end
167
+ end
168
+
169
+ desc 'Set volume for player'
170
+ skips_pre
171
+ arg_name 'level'
172
+ command :volume, :vol do |c|
173
+ c.action do |global_options,options,args|
174
+ level = args.shift.to_i
175
+ set_volume level
176
+ end
177
+ end
178
+
179
+ desc 'Mute the Rdio player'
180
+ skips_pre
181
+ command :mute do |c|
182
+ c.action do |global_options,options,args|
183
+ set_volume 0
184
+ end
185
+ end
186
+
187
+ desc 'Get a shareable link for the current track'
188
+ skips_pre
189
+ command :link do |c|
190
+ c.action do |global_options,options,args|
191
+ say rdio_url
192
+ end
193
+ end
194
+
195
+ desc "Get CLI and application version info"
196
+ skips_pre
197
+ command :version, :v do |c|
198
+ c.action do |global_options,options,args|
199
+ say "rdio-cli #{Rdio::VERSION} / Rdio #{apple_script('get version of application "Rdio"')}"
200
+ end
201
+ end
202
+
203
+ desc "Quit Rdio"
204
+ skips_pre
205
+ command :quit, :q do |c|
206
+ c.action do |global_options,options,args|
207
+ apple_script "tell application \"Rdio\" to quit"
208
+ end
209
+ end
210
+
211
+ desc "Authorize Rdio account"
212
+ skips_pre
213
+ command :authorize, :auth do |c|
214
+ c.action do |global_options,options,args|
215
+ require 'highline/import'
216
+ say "To access your Rdio account, you'll need to get some API keys. "
217
+ say "See http://developer.rdio.com for details. "
218
+ @consumer_key = ask 'Enter your Rdio API key: '
219
+ @consumer_secret = ask 'Enter your Rdio API secret: '
220
+
221
+ if @consumer_key && @consumer_secret
222
+ authorize_api
223
+ end
224
+ end
225
+ end
226
+
227
+ ### Authenticated methods
228
+
229
+ desc 'Show the current Rdio user'
230
+ command :user do |c|
231
+ c.action do |global_options,options,args|
232
+ user = api.call('currentUser')['result']
233
+ say "#{user['firstName']} #{user['lastName']}"
234
+ end
235
+ end
236
+
237
+ desc 'Add the current track or album to your collection'
238
+ command :snag do |c|
239
+ c.action do |global_options,options,args|
240
+ case args.shift
241
+ when 'album'
242
+ say 'Not implemented'
243
+ when nil
244
+ add_to_collection current_track_key
245
+ end
246
+ end
247
+ end
248
+
249
+ pre do |global,command,options,args|
250
+ # Pre logic here
251
+ # Return true to proceed; false to abourt and not call the
252
+ # chosen command
253
+ # Use skips_pre before a command to skip this block
254
+ # on that command only
255
+ @consumer_key = global[:consumer_key]
256
+ @consumer_secret = global[:consumer_secret]
257
+ @access_token = global[:access_token]
258
+ @access_secret = global[:access_secret]
259
+ if api.token.compact.empty?
260
+ say 'Rdio credentials not found. Please run: rdio authorize'
261
+
262
+ false
263
+ else
264
+ true
265
+ end
266
+ end
267
+
268
+ post do |global,command,options,args|
269
+ # Post logic here
270
+ # Use skips_post before a command to skip this
271
+ # block on that command only
272
+ end
273
+
274
+ on_error do |exception|
275
+ # Error logic here
276
+ # return false to skip default error handling
277
+ true
278
+ end
279
+
280
+ end
281
+
282
+
data/rdio-cli.gemspec ADDED
@@ -0,0 +1,27 @@
1
+ # Ensure we require the local version and not one we might have installed already
2
+ require File.join([File.dirname(__FILE__),'lib','rdio','version.rb'])
3
+ spec = Gem::Specification.new do |s|
4
+ s.name = 'rdio-cli'
5
+ s.version = Rdio::VERSION
6
+ s.author = 'Wynn Netherland'
7
+ s.email = 'wynn.netherland@gmail.com'
8
+ s.homepage = 'http://wynnnetherland.com'
9
+ s.platform = Gem::Platform::RUBY
10
+ s.summary = 'CLI for Rdio for Mac'
11
+ s.files = %w(CONTRIBUTING.md LICENSE.md README.md Rakefile rdio-cli.gemspec)
12
+ s.files += Dir.glob("lib/**/*.rb")
13
+ s.files += Dir.glob("bin/**/*")
14
+ s.files += Dir.glob("etc/**/*")
15
+ s.require_paths << 'lib'
16
+ s.has_rdoc = false
17
+ s.rdoc_options << '--title' << 'rdio' << '--main' << 'README.rdoc' << '-ri'
18
+ s.bindir = 'bin'
19
+ s.executables << 'rdio'
20
+ s.add_dependency('highline', '~> 1.6.15')
21
+ s.add_dependency('launchy', '~> 2.1.2')
22
+ s.add_development_dependency('rake')
23
+ s.add_development_dependency('rdoc')
24
+ s.add_development_dependency('rspec', '~> 2.12.0')
25
+ s.add_development_dependency('rspec-mocks', '~> 2.12.0')
26
+ s.add_runtime_dependency('gli','2.5.2')
27
+ end
metadata ADDED
@@ -0,0 +1,174 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rdio-cli
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Wynn Netherland
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-12-27 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: highline
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 1.6.15
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 1.6.15
30
+ - !ruby/object:Gem::Dependency
31
+ name: launchy
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: 2.1.2
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 2.1.2
46
+ - !ruby/object:Gem::Dependency
47
+ name: rake
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: rdoc
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: rspec
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ~>
84
+ - !ruby/object:Gem::Version
85
+ version: 2.12.0
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ~>
92
+ - !ruby/object:Gem::Version
93
+ version: 2.12.0
94
+ - !ruby/object:Gem::Dependency
95
+ name: rspec-mocks
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ~>
100
+ - !ruby/object:Gem::Version
101
+ version: 2.12.0
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ~>
108
+ - !ruby/object:Gem::Version
109
+ version: 2.12.0
110
+ - !ruby/object:Gem::Dependency
111
+ name: gli
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - '='
116
+ - !ruby/object:Gem::Version
117
+ version: 2.5.2
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - '='
124
+ - !ruby/object:Gem::Version
125
+ version: 2.5.2
126
+ description:
127
+ email: wynn.netherland@gmail.com
128
+ executables:
129
+ - rdio
130
+ extensions: []
131
+ extra_rdoc_files: []
132
+ files:
133
+ - CONTRIBUTING.md
134
+ - LICENSE.md
135
+ - README.md
136
+ - Rakefile
137
+ - rdio-cli.gemspec
138
+ - lib/api.rb
139
+ - lib/om.rb
140
+ - lib/rdio/version.rb
141
+ - lib/rdio.rb
142
+ - bin/rdio
143
+ homepage: http://wynnnetherland.com
144
+ licenses: []
145
+ post_install_message:
146
+ rdoc_options:
147
+ - --title
148
+ - rdio
149
+ - --main
150
+ - README.rdoc
151
+ - -ri
152
+ require_paths:
153
+ - lib
154
+ - lib
155
+ required_ruby_version: !ruby/object:Gem::Requirement
156
+ none: false
157
+ requirements:
158
+ - - ! '>='
159
+ - !ruby/object:Gem::Version
160
+ version: '0'
161
+ required_rubygems_version: !ruby/object:Gem::Requirement
162
+ none: false
163
+ requirements:
164
+ - - ! '>='
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ requirements: []
168
+ rubyforge_project:
169
+ rubygems_version: 1.8.23
170
+ signing_key:
171
+ specification_version: 3
172
+ summary: CLI for Rdio for Mac
173
+ test_files: []
174
+ has_rdoc: false