lilyplaying 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/bin/lilyplaying +1 -1
- data/lib/lilyplaying.rb +4 -7
- data/lib/lilyplaying/current.rb +2 -10
- data/lib/lilyplaying/user.rb +4 -4
- data/lib/lilyplaying/version.rb +4 -4
- data/lib/om.rb +160 -0
- data/lib/rdio.rb +82 -0
- data/lilyplaying.gemspec +26 -27
- metadata +5 -17
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
ZTU4MTUwNjcxMmNjM2IzNTAwZjFmOGExOTY0YjE3Y2Y2NjY1MTI1OQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
OTQ1ZjM2ZDUwMWFkZWU2MWFlMzhjZTk2N2Y3OTgxMjRkZDFkZDM3Zg==
|
7
7
|
!binary "U0hBNTEy":
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
NDM2NjUzZDVjOTEwNDdmZWVmYjZkNGJmZTQ2ZWJlZTIxODU2NmRiYjg4Yjg2
|
10
|
+
MmMwYzVkZTEyMmI3YzVhY2IxODNjN2NhZWJmMGNhZjRlNzM4MGNhYjc5ZmM1
|
11
|
+
YWY1YjI1OTQyODhkNDE1ZjJkZjcyMjExOTMxYTFjNDMzZTI4ZWM=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
ZGQ4NThhYTYyOWM1MTA0ZmRhMjA0MDI4NWJhYjUxOGRjNTVhMmFiOThlMTI4
|
14
|
+
NTVjZDU0N2ZkMTc0MjQ3MDQwNzAxNGUzODBjOWM4NDMwNGUzZjZiNGVhMGM2
|
15
|
+
MGY0ZDEyOWYzYWZhMGI4OTQ1YmFhMjI5NjlkM2VkZDgyZTA0OWQ=
|
data/bin/lilyplaying
CHANGED
data/lib/lilyplaying.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'lilyplaying/version'
|
2
|
-
require '
|
2
|
+
require 'rubygems'
|
3
|
+
require 'rdio'
|
3
4
|
require 'safe_yaml'
|
4
5
|
|
5
6
|
require 'lilyplaying/user'
|
@@ -11,14 +12,10 @@ module LilyPlaying
|
|
11
12
|
end
|
12
13
|
|
13
14
|
def self.client
|
14
|
-
@@client ||=
|
15
|
-
end
|
16
|
-
|
17
|
-
def self.session
|
18
|
-
@@session = client.auth.get_session(:token => config['api']['token'])['key']
|
15
|
+
@@client ||= Rdio.new([config['consumer']['key'], config['consumer']['secret']], [config['access']['token'], config['access']['secret']])
|
19
16
|
end
|
20
17
|
|
21
18
|
def self.user
|
22
|
-
LilyPlaying::User.new
|
19
|
+
LilyPlaying::User.new
|
23
20
|
end
|
24
21
|
end
|
data/lib/lilyplaying/current.rb
CHANGED
@@ -3,19 +3,11 @@ module LilyPlaying
|
|
3
3
|
attr_reader :data
|
4
4
|
|
5
5
|
def initialize(data)
|
6
|
-
@data = data
|
7
|
-
end
|
8
|
-
|
9
|
-
def playing?
|
10
|
-
@data["nowplaying"]
|
11
|
-
end
|
12
|
-
|
13
|
-
def album
|
14
|
-
(@data['album']['content'] || artist) if @data
|
6
|
+
@data = data
|
15
7
|
end
|
16
8
|
|
17
9
|
def method_missing(meth, *args, &block)
|
18
|
-
|
10
|
+
@data[meth.to_s]
|
19
11
|
end
|
20
12
|
|
21
13
|
def to_s
|
data/lib/lilyplaying/user.rb
CHANGED
@@ -2,14 +2,14 @@ require 'lilyplaying/current'
|
|
2
2
|
|
3
3
|
module LilyPlaying
|
4
4
|
class User
|
5
|
-
attr_reader :
|
5
|
+
attr_reader :data
|
6
6
|
|
7
|
-
def initialize(
|
8
|
-
@
|
7
|
+
def initialize()
|
8
|
+
@data = LilyPlaying.client.call("currentUser", :extras => "lastSongPlayed")['result']
|
9
9
|
end
|
10
10
|
|
11
11
|
def current
|
12
|
-
LilyPlaying::Current.new(
|
12
|
+
LilyPlaying::Current.new(@data["lastSongPlayed"])
|
13
13
|
end
|
14
14
|
end
|
15
15
|
end
|
data/lib/lilyplaying/version.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
module LilyPlaying
|
2
|
-
DESCRIPTION = "Outputs the currently playing
|
3
|
-
VERSION = "0.0.
|
4
|
-
end
|
1
|
+
module LilyPlaying
|
2
|
+
DESCRIPTION = "Outputs the currently playing rdio song to a text file for use while streaming"
|
3
|
+
VERSION = "0.0.2"
|
4
|
+
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
|
data/lib/rdio.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 Rdio
|
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/lilyplaying.gemspec
CHANGED
@@ -1,27 +1,26 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
lib = File.expand_path('../lib', __FILE__)
|
3
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require 'lilyplaying/version'
|
5
|
-
|
6
|
-
Gem::Specification.new do |spec|
|
7
|
-
spec.name = "lilyplaying"
|
8
|
-
spec.version = LilyPlaying::VERSION
|
9
|
-
spec.authors = ["Christopher Giroir"]
|
10
|
-
spec.email = ["kelsin@valefor.com"]
|
11
|
-
spec.description = LilyPlaying::DESCRIPTION
|
12
|
-
spec.summary = LilyPlaying::DESCRIPTION
|
13
|
-
spec.homepage = "https://github.com/Kelsin/lilyplaying"
|
14
|
-
spec.license = "MIT"
|
15
|
-
|
16
|
-
spec.files = `git ls-files`.split($/)
|
17
|
-
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
-
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
-
spec.require_paths = ["lib"]
|
20
|
-
|
21
|
-
spec.add_runtime_dependency('commander', "~> 4.1.3")
|
22
|
-
spec.add_runtime_dependency('
|
23
|
-
|
24
|
-
|
25
|
-
spec.add_development_dependency "
|
26
|
-
|
27
|
-
end
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'lilyplaying/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "lilyplaying"
|
8
|
+
spec.version = LilyPlaying::VERSION
|
9
|
+
spec.authors = ["Christopher Giroir"]
|
10
|
+
spec.email = ["kelsin@valefor.com"]
|
11
|
+
spec.description = LilyPlaying::DESCRIPTION
|
12
|
+
spec.summary = LilyPlaying::DESCRIPTION
|
13
|
+
spec.homepage = "https://github.com/Kelsin/lilyplaying"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_runtime_dependency('commander', "~> 4.1.3")
|
22
|
+
spec.add_runtime_dependency('safe_yaml', "~> 0.7.0")
|
23
|
+
|
24
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
25
|
+
spec.add_development_dependency "rake"
|
26
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lilyplaying
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Christopher Giroir
|
@@ -24,20 +24,6 @@ dependencies:
|
|
24
24
|
- - ~>
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 4.1.3
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: lastfm
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - ~>
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: 1.21.0
|
34
|
-
type: :runtime
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - ~>
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: 1.21.0
|
41
27
|
- !ruby/object:Gem::Dependency
|
42
28
|
name: safe_yaml
|
43
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -80,7 +66,7 @@ dependencies:
|
|
80
66
|
- - ! '>='
|
81
67
|
- !ruby/object:Gem::Version
|
82
68
|
version: '0'
|
83
|
-
description: Outputs the currently playing
|
69
|
+
description: Outputs the currently playing rdio song to a text file for use while
|
84
70
|
streaming
|
85
71
|
email:
|
86
72
|
- kelsin@valefor.com
|
@@ -99,6 +85,8 @@ files:
|
|
99
85
|
- lib/lilyplaying/current.rb
|
100
86
|
- lib/lilyplaying/user.rb
|
101
87
|
- lib/lilyplaying/version.rb
|
88
|
+
- lib/om.rb
|
89
|
+
- lib/rdio.rb
|
102
90
|
- lilyplaying.gemspec
|
103
91
|
homepage: https://github.com/Kelsin/lilyplaying
|
104
92
|
licenses:
|
@@ -123,5 +111,5 @@ rubyforge_project:
|
|
123
111
|
rubygems_version: 2.0.3
|
124
112
|
signing_key:
|
125
113
|
specification_version: 4
|
126
|
-
summary: Outputs the currently playing
|
114
|
+
summary: Outputs the currently playing rdio song to a text file for use while streaming
|
127
115
|
test_files: []
|