rdio_api 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +11 -0
- data/Gemfile +4 -0
- data/Guardfile +20 -0
- data/README.md +115 -0
- data/Rakefile +10 -0
- data/lib/rdio_api/api.rb +81 -0
- data/lib/rdio_api/client.rb +48 -0
- data/lib/rdio_api/version.rb +3 -0
- data/lib/rdio_api.rb +14 -0
- data/rdio_api.gemspec +30 -0
- data/spec/fixtures/addFriend.json +4 -0
- data/spec/fixtures/addToCollection.json +4 -0
- data/spec/fixtures/addToPlaylist.json +4 -0
- data/spec/fixtures/createPlaylist.json +19 -0
- data/spec/fixtures/currentUser.json +14 -0
- data/spec/fixtures/deletePlaylist.json +4 -0
- data/spec/fixtures/findUser.json +14 -0
- data/spec/fixtures/get.json +16 -0
- data/spec/fixtures/getActivityStream.json +18 -0
- data/spec/fixtures/getAlbumsForArtist.json +917 -0
- data/spec/fixtures/getAlbumsForArtistInCollection.json +82 -0
- data/spec/fixtures/getAlbumsInCollection.json +1184 -0
- data/spec/fixtures/getArtistsInCollection.json +37 -0
- data/spec/fixtures/getHeavyRotation.json +394 -0
- data/spec/fixtures/getNewReleases.json +796 -0
- data/spec/fixtures/getObjectFromShortCode.json +33 -0
- data/spec/fixtures/getObjectFromUrl.json +16 -0
- data/spec/fixtures/getPlaybackToken.json +4 -0
- data/spec/fixtures/getPlaylists.json +25 -0
- data/spec/fixtures/getTopCharts.json +181 -0
- data/spec/fixtures/getTracksForAlbumInCollection.json +440 -0
- data/spec/fixtures/getTracksForArtist.json +295 -0
- data/spec/fixtures/getTracksForArtistInCollection.json +34 -0
- data/spec/fixtures/getTracksInCollection.json +121 -0
- data/spec/fixtures/removeFriend.json +4 -0
- data/spec/fixtures/removeFromCollection.json +4 -0
- data/spec/fixtures/removeFromPlaylist.json +4 -0
- data/spec/fixtures/search.json +523 -0
- data/spec/fixtures/searchSuggestions.json +117 -0
- data/spec/fixtures/setAvailableOffline.json +4 -0
- data/spec/fixtures/setPlaylistCollaborating.json +4 -0
- data/spec/fixtures/setPlaylistCollaborationMode.json +4 -0
- data/spec/fixtures/setPlaylistFields.json +4 -0
- data/spec/fixtures/setPlaylistOrder.json +4 -0
- data/spec/fixtures/userFollowers.json +27 -0
- data/spec/fixtures/userFollowing.json +27 -0
- data/spec/helper.rb +26 -0
- data/spec/rdio_api/activity_spec.rb +59 -0
- data/spec/rdio_api/catalog_spec.rb +77 -0
- data/spec/rdio_api/client_spec.rb +18 -0
- data/spec/rdio_api/collection_spec.rb +127 -0
- data/spec/rdio_api/core_spec.rb +59 -0
- data/spec/rdio_api/playback_spec.rb +22 -0
- data/spec/rdio_api/playlists_spec.rb +122 -0
- data/spec/rdio_api/social_spec.rb +92 -0
- metadata +273 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
guard 'rspec', :version => 2 do
|
5
|
+
watch(%r{^spec/.+_spec\.rb$})
|
6
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
7
|
+
watch('spec/spec_helper.rb') { "spec" }
|
8
|
+
|
9
|
+
# Rails example
|
10
|
+
watch(%r{^spec/.+_spec\.rb$})
|
11
|
+
watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
12
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
13
|
+
watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
|
14
|
+
watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
|
15
|
+
watch('spec/spec_helper.rb') { "spec" }
|
16
|
+
watch('config/routes.rb') { "spec/routing" }
|
17
|
+
watch('app/controllers/application_controller.rb') { "spec/controllers" }
|
18
|
+
# Capybara request specs
|
19
|
+
watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/requests/#{m[1]}_spec.rb" }
|
20
|
+
end
|
data/README.md
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
Rdio
|
2
|
+
====================
|
3
|
+
Ruby wrapper for the [Rdio](http://rdio.com) API. Inspired from [Linkedin gem](https://github.com/pengwynn/linkedin) & [Twitter gem](https://github.com/jnunemaker/twitter).
|
4
|
+
|
5
|
+
|
6
|
+
Installation
|
7
|
+
------------
|
8
|
+
gem install rdio_api
|
9
|
+
|
10
|
+
|
11
|
+
Usage
|
12
|
+
-----
|
13
|
+
|
14
|
+
Register for developer keys at [http://developer.rdio.com/](http://developer.rdio.com/).
|
15
|
+
|
16
|
+
All the methods are exactly as in the [API docs](http://developer.rdio.com/docs/read/rest/Methods), camel cased and all the endpoints are also exactly the same.
|
17
|
+
|
18
|
+
OAuth flow is not part of this gem. Recommend using [OmniAuth](https://github.com/intridea/omniauth). Also check Rdio [OAuth documentation](http://developer.rdio.com/docs/read/rest/oauth).
|
19
|
+
|
20
|
+
|
21
|
+
Usage Examples
|
22
|
+
--------------
|
23
|
+
require "rubygems"
|
24
|
+
require "rdio_api"
|
25
|
+
|
26
|
+
# Initialize a new Rdio client
|
27
|
+
client = RdioApi.new(:consumer_key => CONSUMER_KEY, :consumer_secret => CONSUMER_SECRET)
|
28
|
+
|
29
|
+
# Get songs in heavy rotation
|
30
|
+
client.getHeavyRotation(:type => "albums")
|
31
|
+
|
32
|
+
# Get top playlists
|
33
|
+
client.getTopCharts(:type => "Playlist")
|
34
|
+
|
35
|
+
# Search for a query and and pass in the type
|
36
|
+
client.search(:query => "michael giacchino", :types => "album")
|
37
|
+
|
38
|
+
# Get activity stream of a user
|
39
|
+
client.getActivityStream(:user => "s12345", :scope => "user")
|
40
|
+
|
41
|
+
# Find a user by email address
|
42
|
+
client.findUser(:email => "email@example.com")
|
43
|
+
|
44
|
+
# Methods that act on behalf of a user require an access token, OmniAuth is best for this
|
45
|
+
|
46
|
+
# Access token can be set at initialization
|
47
|
+
client = RdioApi.new(:consumer_key => CONSUMER_KEY,
|
48
|
+
:consumer_secret => CONSUMER_SECRET,
|
49
|
+
:access_token => ACCESS_TOKEN)
|
50
|
+
|
51
|
+
# Access token can also be set at the clien't access_token instance variable
|
52
|
+
client.access_token = ACCESS_TOKEN
|
53
|
+
|
54
|
+
# Get info about the current user
|
55
|
+
client.currentUser
|
56
|
+
|
57
|
+
# Add a friend
|
58
|
+
client.addFriend(:user => "s12345")
|
59
|
+
|
60
|
+
# Create a Playlist
|
61
|
+
client.createPlaylist(:name => "RubyGem",
|
62
|
+
:description => "Testing",
|
63
|
+
:tracks => "t1945474, t3483614")
|
64
|
+
|
65
|
+
Available Methods
|
66
|
+
-----------------
|
67
|
+
|
68
|
+
# Unauthenticated methods, which only require registering for developer keys
|
69
|
+
client.get
|
70
|
+
client.getAlbumsForArtist
|
71
|
+
client.getTracksForArtist
|
72
|
+
client.search
|
73
|
+
client.searchSuggestions
|
74
|
+
client.getAlbumsForArtistInCollection
|
75
|
+
client.getAlbumsInCollection
|
76
|
+
client.getArtistsInCollection
|
77
|
+
client.getTracksForAlbumInCollection
|
78
|
+
client.getTracksForArtistInCollection
|
79
|
+
client.getTracksInCollection
|
80
|
+
client.findUser
|
81
|
+
client.userFollowers
|
82
|
+
client.userFollowing
|
83
|
+
client.getActivityStream
|
84
|
+
client.getHeavyRotation
|
85
|
+
client.getNewReleases
|
86
|
+
client.getTopCharts
|
87
|
+
client.getPlaybackToken
|
88
|
+
|
89
|
+
# Authenticated methods, which require an access token , obtained with user permission
|
90
|
+
client.getObjectFromShortCode
|
91
|
+
client.getObjectFromUrl
|
92
|
+
client.addToCollection
|
93
|
+
client.removeFromCollection
|
94
|
+
client.setAvailableOffline
|
95
|
+
client.addToPlaylist
|
96
|
+
client.createPlaylist
|
97
|
+
client.deletePlaylist
|
98
|
+
client.getPlaylists
|
99
|
+
client.removeFromPlaylist
|
100
|
+
client.setPlaylistCollaborating
|
101
|
+
client.setPlaylistCollaborationMode
|
102
|
+
client.setPlaylistFields
|
103
|
+
client.setPlaylistOrder
|
104
|
+
client.addFriend
|
105
|
+
client.currentUser
|
106
|
+
client.removeFriend
|
107
|
+
|
108
|
+
TODO
|
109
|
+
----
|
110
|
+
* Explore moving methods from camel case to snake case and update tests accordingly
|
111
|
+
* OAuth flow
|
112
|
+
* More tests for methods and for each endpoints
|
113
|
+
* Test and Support multiple Rubies
|
114
|
+
|
115
|
+
|
data/Rakefile
ADDED
data/lib/rdio_api/api.rb
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'multi_json'
|
2
|
+
require 'hashie'
|
3
|
+
|
4
|
+
module RdioApi
|
5
|
+
|
6
|
+
module Api
|
7
|
+
|
8
|
+
def method_missing(method_sym, *arguments)
|
9
|
+
if UNAUTHENTICATED.include?(method_sym)
|
10
|
+
unauthenticated_request(method_sym, *arguments)
|
11
|
+
elsif AUTHENTICATED.include?(method_sym)
|
12
|
+
authenticated_request(method_sym, *arguments)
|
13
|
+
else
|
14
|
+
raise NoMethodError.new("Undefined method '#{method_sym}' for #{self}")
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def respond_to?(method)
|
19
|
+
AUTHENTICATED.include?(method.to_sym) || UNAUTHENTICATED.include?(method.to_sym) ? true : false
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def unauthenticated_request(method_sym, *arguments)
|
25
|
+
response = unauthenticated_connection.post do |request|
|
26
|
+
request.body = {:method => method_sym.to_s}.merge!(Hash[*arguments.flatten])
|
27
|
+
end
|
28
|
+
response.body.result
|
29
|
+
end
|
30
|
+
|
31
|
+
def authenticated_request(method_sym, *arguments)
|
32
|
+
if authenticated_connection
|
33
|
+
response = MultiJson.decode(authenticated_connection.post(api_url,
|
34
|
+
{:method => method_sym.to_s}.merge!(Hash[*arguments.flatten])).body)['result']
|
35
|
+
response.is_a?(Hash) ? Hashie::Mash.new(response) : response
|
36
|
+
else
|
37
|
+
"Set access token at initialization or the client's access_token instance variable"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
UNAUTHENTICATED = [
|
42
|
+
:get,
|
43
|
+
:getAlbumsForArtist,
|
44
|
+
:getTracksForArtist,
|
45
|
+
:search,
|
46
|
+
:searchSuggestions,
|
47
|
+
:getAlbumsForArtistInCollection,
|
48
|
+
:getAlbumsInCollection,
|
49
|
+
:getArtistsInCollection,
|
50
|
+
:getTracksForAlbumInCollection,
|
51
|
+
:getTracksForArtistInCollection,
|
52
|
+
:getTracksInCollection,
|
53
|
+
:findUser,
|
54
|
+
:userFollowers,
|
55
|
+
:userFollowing,
|
56
|
+
:getActivityStream,
|
57
|
+
:getHeavyRotation,
|
58
|
+
:getNewReleases,
|
59
|
+
:getTopCharts,
|
60
|
+
:getPlaybackToken]
|
61
|
+
|
62
|
+
AUTHENTICATED = [
|
63
|
+
:getObjectFromShortCode,
|
64
|
+
:getObjectFromUrl,
|
65
|
+
:addToCollection,
|
66
|
+
:removeFromCollection,
|
67
|
+
:setAvailableOffline,
|
68
|
+
:addToPlaylist,
|
69
|
+
:createPlaylist,
|
70
|
+
:deletePlaylist,
|
71
|
+
:getPlaylists,
|
72
|
+
:removeFromPlaylist,
|
73
|
+
:setPlaylistCollaborating,
|
74
|
+
:setPlaylistCollaborationMode,
|
75
|
+
:setPlaylistFields,
|
76
|
+
:setPlaylistOrder,
|
77
|
+
:addFriend,
|
78
|
+
:currentUser,
|
79
|
+
:removeFriend]
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module RdioApi
|
2
|
+
|
3
|
+
class Client
|
4
|
+
|
5
|
+
include Api
|
6
|
+
|
7
|
+
attr_reader :consumer_key, :consumer_secret
|
8
|
+
attr_accessor :access_token
|
9
|
+
|
10
|
+
# Initialize the client for API request. A consumer key and consumer secret are required.
|
11
|
+
# Requests on behalf of the user require access_token (oauth token)
|
12
|
+
|
13
|
+
def initialize(options={})
|
14
|
+
@consumer_key = options[:consumer_key]
|
15
|
+
@consumer_secret = options[:consumer_secret]
|
16
|
+
@access_token = options[:access_token]
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
# Set up the connection to use for all requests based on the options from intialization.
|
22
|
+
|
23
|
+
def unauthenticated_connection
|
24
|
+
params = {}
|
25
|
+
params[:consumer_key] = @consumer_key
|
26
|
+
params[:consumer_secret] = @consumer_secret
|
27
|
+
@connection ||= Faraday.new(:url => api_url) do |builder|
|
28
|
+
builder.use Faraday::Request::OAuth, params
|
29
|
+
builder.use Faraday::Request::UrlEncoded
|
30
|
+
builder.use Faraday::Response::Mashify
|
31
|
+
builder.use Faraday::Response::ParseJson
|
32
|
+
builder.adapter Faraday.default_adapter
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# Sets the access token to make authenticated calls
|
37
|
+
|
38
|
+
def authenticated_connection
|
39
|
+
@access_token
|
40
|
+
end
|
41
|
+
|
42
|
+
# Base URL for api requests
|
43
|
+
|
44
|
+
def api_url
|
45
|
+
("http://api.rdio.com/1/").freeze
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/lib/rdio_api.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require "rdio_api/version"
|
2
|
+
require 'faraday'
|
3
|
+
require 'faraday_middleware'
|
4
|
+
|
5
|
+
require 'rdio_api/api'
|
6
|
+
require 'rdio_api/client'
|
7
|
+
|
8
|
+
module RdioApi
|
9
|
+
|
10
|
+
# RdioApi::Client.new alias
|
11
|
+
def self.new(options={})
|
12
|
+
RdioApi::Client.new(options)
|
13
|
+
end
|
14
|
+
end
|
data/rdio_api.gemspec
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "rdio_api/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "rdio_api"
|
7
|
+
s.version = RdioApi::VERSION
|
8
|
+
s.authors = ["Anil"]
|
9
|
+
s.homepage = "http://github.com/anilv/rdio_api"
|
10
|
+
s.summary = %q{A Ruby wrapper for the Rdio API}
|
11
|
+
s.description = %q{A Ruby wrapper for the Rdio API}
|
12
|
+
|
13
|
+
s.add_development_dependency 'rake', '~> 0.9'
|
14
|
+
s.add_development_dependency 'rspec', '~> 2.6'
|
15
|
+
s.add_development_dependency 'webmock', '~>1.6'
|
16
|
+
s.add_development_dependency 'oauth', '~>0.4.5'
|
17
|
+
s.add_development_dependency 'rb-fsevent'
|
18
|
+
s.add_development_dependency 'guard-rspec'
|
19
|
+
|
20
|
+
s.add_runtime_dependency 'faraday', '~> 0.6.1'
|
21
|
+
s.add_runtime_dependency 'faraday_middleware', '~> 0.6.5'
|
22
|
+
s.add_runtime_dependency 'hashie', '~> 1.0.0'
|
23
|
+
s.add_runtime_dependency 'multi_json', '~> 1.0.3'
|
24
|
+
s.add_runtime_dependency 'simple_oauth', '~> 0.1.5'
|
25
|
+
|
26
|
+
s.files = `git ls-files`.split("\n")
|
27
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
28
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
29
|
+
s.require_paths = ["lib"]
|
30
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
{
|
2
|
+
"status" :"ok",
|
3
|
+
"result" : {
|
4
|
+
"ownerKey": "s27093",
|
5
|
+
"name": "RubyGem",
|
6
|
+
"baseIcon": "album/f/4/8/000000000002784f/square-200.jpg",
|
7
|
+
"ownerIcon": "user/no-user-image-square.jpg",
|
8
|
+
"owner": "Anil V",
|
9
|
+
"lastUpdated": 1312411563.0,
|
10
|
+
"shortUrl": "http://rd.io/x/QDaXL0BSKw",
|
11
|
+
"length": 2,
|
12
|
+
"url": "/people/anilv/playlists/200057/RubyGem/",
|
13
|
+
"key": "p200057",
|
14
|
+
"ownerUrl": "/people/anilv/",
|
15
|
+
"embedUrl": "http://rd.io/e/QDaXL0BSKw",
|
16
|
+
"type": "p",
|
17
|
+
"icon": "http://m.rdio.com/_is/?aid=284243,161871&w=200&h=200"
|
18
|
+
}
|
19
|
+
}
|
@@ -0,0 +1,14 @@
|
|
1
|
+
{
|
2
|
+
"status" :"ok",
|
3
|
+
"result" : {
|
4
|
+
"firstName": "Anil",
|
5
|
+
"baseIcon": "user/no-user-image-square.jpg",
|
6
|
+
"gender": "m",
|
7
|
+
"url": "/people/anilv/",
|
8
|
+
"key": "s27093",
|
9
|
+
"lastName": "V",
|
10
|
+
"libraryVersion": 110,
|
11
|
+
"type": "s",
|
12
|
+
"icon": "http://media.rd.io/user/no-user-image-square.jpg"
|
13
|
+
}
|
14
|
+
}
|
@@ -0,0 +1,14 @@
|
|
1
|
+
{
|
2
|
+
"status" :"ok",
|
3
|
+
"result" : {
|
4
|
+
"firstName": "Anil",
|
5
|
+
"baseIcon": "user/no-user-image-square.jpg",
|
6
|
+
"gender": "m",
|
7
|
+
"url": "/people/anilv/",
|
8
|
+
"key": "s27093",
|
9
|
+
"lastName": "V",
|
10
|
+
"libraryVersion": 110,
|
11
|
+
"type": "s",
|
12
|
+
"icon": "http://media.rd.io/user/no-user-image-square.jpg"
|
13
|
+
}
|
14
|
+
}
|
@@ -0,0 +1,16 @@
|
|
1
|
+
{
|
2
|
+
"status" :"ok",
|
3
|
+
"result" : {
|
4
|
+
"r13700" : {
|
5
|
+
"name" : "John Williams",
|
6
|
+
"hasRadio" : false,
|
7
|
+
"baseIcon" : "artist/4/8/5/0000000000003584/square-200.jpg",
|
8
|
+
"shortUrl" : "http://rd.io/x/Qi132w",
|
9
|
+
"length" : 2075,
|
10
|
+
"url" : "/artist/John_Williams/",
|
11
|
+
"key" : "r13700",
|
12
|
+
"type" : "r",
|
13
|
+
"icon" : "http://media.rd.io/artist/4/8/5/0000000000003584/square-200.jpg"
|
14
|
+
}
|
15
|
+
}
|
16
|
+
}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
{
|
2
|
+
"status" :"ok",
|
3
|
+
"result" : {
|
4
|
+
"last_id": 0,
|
5
|
+
"user": {
|
6
|
+
"firstName": "Anil",
|
7
|
+
"baseIcon": "user/no-user-image-square.jpg",
|
8
|
+
"gender": "m",
|
9
|
+
"url": "/people/anilv/",
|
10
|
+
"key": "s27093",
|
11
|
+
"lastName": "V",
|
12
|
+
"libraryVersion": 110,
|
13
|
+
"type": "s",
|
14
|
+
"icon": "http://media.rd.io/user/no-user-image-square.jpg"
|
15
|
+
},
|
16
|
+
"updates": []
|
17
|
+
}
|
18
|
+
}
|