lastfm-client 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.DS_Store +0 -0
- data/.gitignore +4 -0
- data/.rspec +1 -0
- data/Gemfile +7 -0
- data/LICENSE +20 -0
- data/README.md +60 -0
- data/Rakefile +6 -0
- data/lastfm.gemspec +21 -0
- data/lib/.DS_Store +0 -0
- data/lib/lastfm-client.rb +130 -0
- data/lib/lastfm-client/.DS_Store +0 -0
- data/lib/lastfm-client/api_class.rb +57 -0
- data/lib/lastfm-client/api_classes/album.rb +9 -0
- data/lib/lastfm-client/api_classes/artist.rb +12 -0
- data/lib/lastfm-client/api_classes/auth.rb +6 -0
- data/lib/lastfm-client/api_classes/chart.rb +6 -0
- data/lib/lastfm-client/api_classes/event.rb +9 -0
- data/lib/lastfm-client/api_classes/geo.rb +7 -0
- data/lib/lastfm-client/api_classes/group.rb +6 -0
- data/lib/lastfm-client/api_classes/library.rb +9 -0
- data/lib/lastfm-client/api_classes/playlist.rb +9 -0
- data/lib/lastfm-client/api_classes/radio.rb +10 -0
- data/lib/lastfm-client/api_classes/tag.rb +6 -0
- data/lib/lastfm-client/api_classes/tasteometer.rb +5 -0
- data/lib/lastfm-client/api_classes/track.rb +11 -0
- data/lib/lastfm-client/api_classes/user.rb +15 -0
- data/lib/lastfm-client/api_classes/venue.rb +5 -0
- data/lib/lastfm-client/version.rb +3 -0
- data/spec/api_class_spec.rb +33 -0
- data/spec/api_classes/album_spec.rb +28 -0
- data/spec/api_classes/artist_spec.rb +15 -0
- data/spec/api_classes/auth_spec.rb +11 -0
- data/spec/api_classes/chart_spec.rb +7 -0
- data/spec/api_classes/event_spec.rb +11 -0
- data/spec/api_classes/geo_spec.rb +7 -0
- data/spec/api_classes/group_spec.rb +10 -0
- data/spec/api_classes/library_spec.rb +11 -0
- data/spec/api_classes/playlist_spec.rb +11 -0
- data/spec/api_classes/radio_spec.rb +11 -0
- data/spec/api_classes/tag_spec.rb +7 -0
- data/spec/api_classes/tasteometer_spec.rb +7 -0
- data/spec/api_classes/track_spec.rb +17 -0
- data/spec/api_classes/user_spec.rb +18 -0
- data/spec/api_classes/venue_spec.rb +7 -0
- data/spec/lastfm-client_spec.rb +101 -0
- data/spec/spec_helper.rb +4 -0
- metadata +120 -0
data/.DS_Store
ADDED
Binary file
|
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--colour
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 Piotr Chmolowski
|
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,60 @@
|
|
1
|
+
# Last.fm API Ruby Client
|
2
|
+
|
3
|
+
LastFM is a Ruby wrapper for [Last.fm API](http://www.last.fm/api).
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add the following line to your Gemfile and run `bundle install`:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'lastfm-client', :git => 'http://github.com/pch/lastfm-client.git'
|
11
|
+
```
|
12
|
+
|
13
|
+
You also need to set up your API key and client name, e.g.:
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
LastFM.api_key = "7234655fd87556209fa94ca6f5e7ad0a8b47f394"
|
17
|
+
LastFM.client_name = "My awesome app"
|
18
|
+
```
|
19
|
+
|
20
|
+
If you're using Rails, you can add the above lines to an initalizer file, e.g. `config/initializers/lastfm.rb`
|
21
|
+
|
22
|
+
## Usage examples
|
23
|
+
|
24
|
+
```ruby
|
25
|
+
LastFM::Album.get_info(:artist => "Red Hot Chili Peppers", :album => "Mother's Milk")
|
26
|
+
LastFM::Artist.get_top_fans(:artist => "Gorillaz")
|
27
|
+
LastFM::Geo.get_events(:location => "Warsaw")
|
28
|
+
LastFM::User.get_top_albums(:user => "some_user")
|
29
|
+
```
|
30
|
+
|
31
|
+
### Authentication
|
32
|
+
|
33
|
+
For some methods Last.fm requires authentication, which is somewhat similar to oAuth:
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
class SessionsController < ApplicationController
|
37
|
+
def new
|
38
|
+
redirect_to LastFM.auth_url
|
39
|
+
end
|
40
|
+
|
41
|
+
def create
|
42
|
+
token = params[:token]
|
43
|
+
redirect_to root_path and return if !token || token == ""
|
44
|
+
|
45
|
+
api_session = LastFM::Auth.get_session(:token => token, :api_sig => true)
|
46
|
+
api_session = api_session["session"]
|
47
|
+
|
48
|
+
user = User.find_by_username(api_session["name"])
|
49
|
+
unless user
|
50
|
+
# new user
|
51
|
+
user = User.create(:username => api_session["name"])
|
52
|
+
end
|
53
|
+
|
54
|
+
session[:user_id] = user.id
|
55
|
+
session[:session_key] = api_session["key"]
|
56
|
+
|
57
|
+
redirect_to root_path
|
58
|
+
end
|
59
|
+
end
|
60
|
+
```
|
data/Rakefile
ADDED
data/lastfm.gemspec
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "lastfm-client/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "lastfm-client"
|
7
|
+
s.version = LastFM::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Piotr Chmolowski"]
|
10
|
+
s.email = ["piotr@chmolowski.pl"]
|
11
|
+
s.homepage = "http://github.com/pch/lastfm-client"
|
12
|
+
s.summary = "Last.fm API client"
|
13
|
+
s.description = "Last.fm API client"
|
14
|
+
|
15
|
+
s.add_dependency "json", ">= 1.4.6"
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
end
|
data/lib/.DS_Store
ADDED
Binary file
|
@@ -0,0 +1,130 @@
|
|
1
|
+
require "open-uri"
|
2
|
+
require "uri"
|
3
|
+
require "json"
|
4
|
+
require "digest/md5"
|
5
|
+
require "net/http"
|
6
|
+
require "cgi"
|
7
|
+
|
8
|
+
module LastFM
|
9
|
+
class APIException < StandardError; end
|
10
|
+
class InvalidData < APIException; end
|
11
|
+
|
12
|
+
extend self
|
13
|
+
|
14
|
+
autoload :APIClass, 'lastfm-client/api_class'
|
15
|
+
autoload :Album, 'lastfm-client/api_classes/album'
|
16
|
+
autoload :Artist, 'lastfm-client/api_classes/artist'
|
17
|
+
autoload :Auth, 'lastfm-client/api_classes/auth'
|
18
|
+
autoload :Chart, 'lastfm-client/api_classes/chart'
|
19
|
+
autoload :Event, 'lastfm-client/api_classes/event'
|
20
|
+
autoload :Geo, 'lastfm-client/api_classes/geo'
|
21
|
+
autoload :Group, 'lastfm-client/api_classes/group'
|
22
|
+
autoload :Library, 'lastfm-client/api_classes/library'
|
23
|
+
autoload :Playlist, 'lastfm-client/api_classes/playlist'
|
24
|
+
autoload :Radio, 'lastfm-client/api_classes/radio'
|
25
|
+
autoload :Tag, 'lastfm-client/api_classes/tag'
|
26
|
+
autoload :Tasteometer, 'lastfm-client/api_classes/tasteometer'
|
27
|
+
autoload :Track, 'lastfm-client/api_classes/track'
|
28
|
+
autoload :User, 'lastfm-client/api_classes/user'
|
29
|
+
autoload :Venue, 'lastfm-client/api_classes/venue'
|
30
|
+
|
31
|
+
DEFAULT_API_URL = 'http://ws.audioscrobbler.com/2.0/'
|
32
|
+
DEFAULT_AUTH_URL = 'http://www.last.fm/api/auth/'
|
33
|
+
|
34
|
+
def api_url
|
35
|
+
@api_url || DEFAULT_API_URL
|
36
|
+
end
|
37
|
+
|
38
|
+
def api_url=(url)
|
39
|
+
@api_url = url
|
40
|
+
end
|
41
|
+
|
42
|
+
def api_key
|
43
|
+
@api_key or raise "API Key is not set"
|
44
|
+
end
|
45
|
+
|
46
|
+
def api_key=(key)
|
47
|
+
@api_key = key
|
48
|
+
end
|
49
|
+
|
50
|
+
def secret
|
51
|
+
@secret or raise "Secret is not set"
|
52
|
+
end
|
53
|
+
|
54
|
+
def secret=(secret)
|
55
|
+
@secret = secret
|
56
|
+
end
|
57
|
+
|
58
|
+
def client_name
|
59
|
+
@client_name or raise "Client name is not set"
|
60
|
+
end
|
61
|
+
|
62
|
+
def client_name=(name)
|
63
|
+
@client_name = name
|
64
|
+
end
|
65
|
+
|
66
|
+
def auth_url
|
67
|
+
(@auth_url || DEFAULT_AUTH_URL) + "?api_key=#{self.api_key}"
|
68
|
+
end
|
69
|
+
|
70
|
+
def auth_url=(url)
|
71
|
+
@auth_url = url
|
72
|
+
end
|
73
|
+
|
74
|
+
def send_api_request(method, params, request_method = :get)
|
75
|
+
raise "Invalid params" unless params.is_a?(Hash)
|
76
|
+
|
77
|
+
params[:method] = method
|
78
|
+
params[:api_key] = self.api_key
|
79
|
+
|
80
|
+
if params[:api_sig] == true
|
81
|
+
params.delete(:api_sig)
|
82
|
+
params[:api_sig] = generate_signature(params)
|
83
|
+
end
|
84
|
+
|
85
|
+
params[:format] = "json"
|
86
|
+
|
87
|
+
if request_method == :post
|
88
|
+
post_data(self.api_url, params)
|
89
|
+
else
|
90
|
+
fetch_data(self.api_url + "?" + hash_to_params(params))
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def fetch_data(url)
|
95
|
+
open(url, "User-Agent" => client_name) do |page|
|
96
|
+
::JSON.parse(page.read)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
#
|
101
|
+
# FIXME: returns either 403 or bad signature errors
|
102
|
+
#
|
103
|
+
def post_data(url, params)
|
104
|
+
url = URI.parse(url)
|
105
|
+
req = Net::HTTP::Post.new(url.path)
|
106
|
+
req.set_form_data(params)
|
107
|
+
|
108
|
+
res = Net::HTTP.new(url.host, url.port).start { |http| http.request(req) }
|
109
|
+
|
110
|
+
case res
|
111
|
+
when Net::HTTPSuccess, Net::HTTPRedirection
|
112
|
+
return ::JSON.parse(res.body)
|
113
|
+
when Net::HTTPClientError
|
114
|
+
raise LastFM::InvalidData, res.body if res.code == "422" # unprocessable entity
|
115
|
+
end
|
116
|
+
|
117
|
+
raise LastFM::APIException, res.error!
|
118
|
+
end
|
119
|
+
|
120
|
+
def generate_signature(params)
|
121
|
+
params = params.sort_by { |k,v| k.to_s }
|
122
|
+
signature = params.map { |param| "#{param[0].to_s}#{param[1].to_s}" }.join('')
|
123
|
+
|
124
|
+
Digest::MD5.hexdigest(signature + self.secret)
|
125
|
+
end
|
126
|
+
|
127
|
+
def hash_to_params(hash)
|
128
|
+
hash.map { |key, value| "#{key.to_s}=#{::CGI.escape(value.to_s)}" }.join('&')
|
129
|
+
end
|
130
|
+
end
|
Binary file
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module LastFM
|
2
|
+
class APIClass
|
3
|
+
|
4
|
+
def self.unrestricted_methods(*args)
|
5
|
+
args.each do |method|
|
6
|
+
define_api_method(method) do |params|
|
7
|
+
raise ArgumentError, "Params should be a hash" unless params.is_a?(Hash)
|
8
|
+
send_request(method, params)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.restricted_methods(*args, &block)
|
14
|
+
if block_given?
|
15
|
+
yield
|
16
|
+
else
|
17
|
+
read(*args)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.read(*args)
|
22
|
+
args.each do |method|
|
23
|
+
define_api_method(method) do |params|
|
24
|
+
restricted_method(method, params)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.write(*args)
|
30
|
+
args.each do |method|
|
31
|
+
define_api_method(method) do |params|
|
32
|
+
restricted_method(method, params, :post)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.restricted_method(method, params, request_method = :get)
|
38
|
+
raise ArgumentError, "Params should be a hash" unless params.is_a?(Hash)
|
39
|
+
|
40
|
+
params[:api_sig] = true
|
41
|
+
send_request(method, params, request_method)
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.send_request(method, params, request_method = :get)
|
45
|
+
api_method = self.to_s.split("::").last + "." # LastFM::Album => Album
|
46
|
+
api_method += method.to_s.tr('_', '') # get_info => getinfo
|
47
|
+
|
48
|
+
LastFM.send_api_request(api_method.downcase, params, request_method)
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.define_api_method(method, &block)
|
52
|
+
(class << self; self; end).instance_eval do
|
53
|
+
define_method(method, &block)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module LastFM
|
2
|
+
class Artist < APIClass
|
3
|
+
unrestricted_methods :get_correction, :get_events, :get_images, :get_info, :get_past_events,
|
4
|
+
:get_podcast, :get_shouts, :get_similar, :get_top_albums, :get_top_fans,
|
5
|
+
:get_top_tags, :get_top_tracks, :search
|
6
|
+
|
7
|
+
restricted_methods do
|
8
|
+
read :get_tags
|
9
|
+
write :add_tags, :remove_tag, :share, :shout
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
module LastFM
|
2
|
+
class Geo < APIClass
|
3
|
+
unrestricted_methods :get_events, :get_metro_artist_chart, :get_metro_hype_artist_chart, :get_metro_hype_track_chart,
|
4
|
+
:get_metro_track_chart, :get_metro_unique_artist_chart, :get_metro_unique_track_chart,
|
5
|
+
:get_metro_weekly_chartlist, :get_metros, :get_top_artists, :get_top_tracks
|
6
|
+
end
|
7
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module LastFM
|
2
|
+
class Track < APIClass
|
3
|
+
unrestricted_methods :get_buy_links, :get_correction, :get_fingerprint_metadata, :get_info,
|
4
|
+
:get_similar, :get_top_fans, :get_top_tags, :search
|
5
|
+
|
6
|
+
restricted_methods do
|
7
|
+
read :get_tags
|
8
|
+
write :add_tags, :ban, :love, :remove_tag, :scrobble, :share, :unban, :unlove, :update_now_playing
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module LastFM
|
2
|
+
class User < APIClass
|
3
|
+
unrestricted_methods :get_artist_tracks, :get_banned_tracks, :get_events, :get_friends,
|
4
|
+
:get_info, :get_loved_tracks, :get_neighbours, :get_new_releases,
|
5
|
+
:get_past_events, :get_playlists, :get_recent_tracks, :get_shouts,
|
6
|
+
:get_top_albums, :get_top_artists, :get_top_tags, :get_top_tracks,
|
7
|
+
:get_weekly_album_chart, :get_weekly_artist_chart, :get_weekly_chart_list,
|
8
|
+
:get_weekly_track_chart
|
9
|
+
|
10
|
+
restricted_methods do
|
11
|
+
read :get_recent_stations, :get_recommended_artists, :get_recommended_events
|
12
|
+
write :shout
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe LastFM::APIClass do
|
4
|
+
it "should define unrestricted methods" do
|
5
|
+
LastFM::APIClass.unrestricted_methods(:foo, :bar, :baz)
|
6
|
+
LastFM::APIClass.unrestricted_methods.should be_an(Array)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should not allow to call an undefined method" do
|
10
|
+
lambda { LastFM::APIClass.i_wasnt_defined }.should raise_error(NoMethodError)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should not allow to call a method with invalid params" do
|
14
|
+
lambda { LastFM::APIClass.foo("not a hash") }.should raise_error(ArgumentError, "Params should be a hash")
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should respond to unrestricted methods" do
|
18
|
+
LastFM.should_receive(:send_api_request).with("apiclass.foo", {:bar => :baz}, :get).and_return({})
|
19
|
+
LastFM::APIClass.foo(:bar => :baz).should be_a(Hash)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should define restricted methods" do
|
23
|
+
LastFM::APIClass.restricted_methods(:foo1, :bar1, :baz1)
|
24
|
+
LastFM::APIClass.should respond_to(:foo1)
|
25
|
+
LastFM::APIClass.should respond_to(:bar1)
|
26
|
+
LastFM::APIClass.should respond_to(:baz1)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should respond to restricted methods" do
|
30
|
+
LastFM.should_receive(:send_api_request).with("apiclass.foo1", {:bar => :baz, :api_sig => true}, :get).and_return({})
|
31
|
+
LastFM::APIClass.foo1(:bar => :baz).should be_a(Hash)
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe LastFM::Album do
|
4
|
+
it "should define unrestricted methods" do
|
5
|
+
LastFM::Album.should respond_to(:get_buy_links, :get_info, :get_top_tags, :search)
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should respond to unrestricted methods" do
|
9
|
+
LastFM.should_receive(:send_api_request).with("album.getinfo", {:bar => :baz}, :get).and_return({})
|
10
|
+
LastFM::Album.get_info(:bar => :baz).should be_a(Hash)
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "restricted methods" do
|
14
|
+
it "should define restricted methods" do
|
15
|
+
LastFM::Album.should respond_to(:get_tags, :add_tags, :remove_tag, :share)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should respond to restricted read methods" do
|
19
|
+
LastFM.should_receive(:send_api_request).with("album.gettags", {:bar => :baz}, :get).and_return({})
|
20
|
+
LastFM::Album.get_tags(:bar => :baz).should be_a(Hash)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should respond to restricted write methods" do
|
24
|
+
LastFM.should_receive(:send_api_request).with("album.addtags", {:bar => :baz, :api_sig => true}, :post).and_return({})
|
25
|
+
LastFM::Album.add_tags(:bar => :baz).should be_a(Hash)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe LastFM::Artist do
|
4
|
+
it "should define unrestricted methods" do
|
5
|
+
LastFM::Artist.should respond_to(
|
6
|
+
:get_correction, :get_events, :get_images, :get_info, :get_past_events,
|
7
|
+
:get_podcast, :get_shouts, :get_similar, :get_top_albums, :get_top_fans,
|
8
|
+
:get_top_tags, :get_top_tracks, :search
|
9
|
+
)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should define restricted methods" do
|
13
|
+
LastFM::Artist.should respond_to(:add_tags, :get_tags, :remove_tag, :share, :shout)
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe LastFM::Auth do
|
4
|
+
it "should define unrestricted methods" do
|
5
|
+
LastFM::Auth.should respond_to(:get_token)
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should define restricted methods" do
|
9
|
+
LastFM::Auth.should respond_to(:get_mobile_session, :get_session)
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe LastFM::Event do
|
4
|
+
it "should define unrestricted methods" do
|
5
|
+
LastFM::Event.should respond_to(:get_attendees, :get_info, :get_shouts)
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should define restricted methods" do
|
9
|
+
LastFM::Event.should respond_to(:attend, :share, :shout)
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe LastFM::Geo do
|
4
|
+
it "should define unrestricted methods" do
|
5
|
+
LastFM::Geo.should respond_to(:get_events, :get_metro_artist_chart, :get_metro_hype_artist_chart, :get_metro_hype_track_chart, :get_metro_track_chart, :get_metro_unique_artist_chart, :get_metro_unique_track_chart, :get_metro_weekly_chartlist, :get_metros, :get_top_artists, :get_top_tracks)
|
6
|
+
end
|
7
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe LastFM::Group do
|
4
|
+
it "should define unrestricted methods" do
|
5
|
+
LastFM::Group.should respond_to(
|
6
|
+
:get_hype, :get_members, :get_weekly_album_chart, :get_weekly_artist_chart,
|
7
|
+
:get_weekly_chart_list, :get_weekly_trackchart
|
8
|
+
)
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe LastFM::Library do
|
4
|
+
it "should define unrestricted methods" do
|
5
|
+
LastFM::Library.should respond_to(:get_albums, :get_artists, :get_tracks)
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should define restricted methods" do
|
9
|
+
LastFM::Library.should respond_to(:add_album, :add_artist, :add_track)
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe LastFM::Playlist do
|
4
|
+
it "should define unrestricted methods" do
|
5
|
+
LastFM::Playlist.should respond_to(:fetch)
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should define restricted methods" do
|
9
|
+
LastFM::Playlist.should respond_to(:add_track, :create)
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe LastFM::Radio do
|
4
|
+
it "should define unrestricted methods" do
|
5
|
+
LastFM::Radio.should respond_to(:search)
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should define restricted methods" do
|
9
|
+
LastFM::Radio.should respond_to(:get_playlist, :tune)
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe LastFM::Tag do
|
4
|
+
it "should define unrestricted methods" do
|
5
|
+
LastFM::Tag.should respond_to(:get_similar, :get_top_albums, :get_top_artists, :get_top_tags, :get_top_tracks, :get_weekly_artist_chart, :get_weekly_chart_list, :search)
|
6
|
+
end
|
7
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe LastFM::Track do
|
4
|
+
it "should define unrestricted methods" do
|
5
|
+
LastFM::Track.should respond_to(
|
6
|
+
:get_buy_links, :get_correction, :get_fingerprint_metadata, :get_info,
|
7
|
+
:get_similar, :get_top_fans, :get_top_tags, :search
|
8
|
+
)
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should define restricted methods" do
|
12
|
+
LastFM::Track.should respond_to(
|
13
|
+
:get_tags, :add_tags, :ban, :love, :remove_tag, :scrobble, :share, :unban,
|
14
|
+
:unlove, :update_now_playing
|
15
|
+
)
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe LastFM::User do
|
4
|
+
it "should define unrestricted methods" do
|
5
|
+
LastFM::User.should respond_to(
|
6
|
+
:get_artist_tracks, :get_banned_tracks, :get_events, :get_friends,
|
7
|
+
:get_info, :get_loved_tracks, :get_neighbours, :get_new_releases,
|
8
|
+
:get_past_events, :get_playlists, :get_recent_tracks, :get_shouts,
|
9
|
+
:get_top_albums, :get_top_artists, :get_top_tags, :get_top_tracks,
|
10
|
+
:get_weekly_album_chart, :get_weekly_artist_chart, :get_weekly_chart_list,
|
11
|
+
:get_weekly_track_chart
|
12
|
+
)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should define restricted methods" do
|
16
|
+
LastFM::User.should respond_to(:get_recent_stations, :get_recommended_artists, :get_recommended_events, :shout)
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe LastFM do
|
4
|
+
it "should have a default API URL" do
|
5
|
+
LastFM.api_url.should == LastFM::DEFAULT_API_URL
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should allow to set a custom API URL" do
|
9
|
+
custom_url = "http://foobar.com"
|
10
|
+
|
11
|
+
LastFM.api_url = custom_url
|
12
|
+
LastFM.api_url.should == custom_url
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should set API key" do
|
16
|
+
LastFM.api_key = "1234"
|
17
|
+
LastFM.api_key.should == "1234"
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should raise error when trying to read empty token" do
|
21
|
+
LastFM.api_key = nil
|
22
|
+
lambda { LastFM.api_key }.should raise_error(RuntimeError, "API Key is not set")
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should set secret" do
|
26
|
+
LastFM.secret = "123456"
|
27
|
+
LastFM.secret.should == "123456"
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should raise error when trying to read empty secret" do
|
31
|
+
LastFM.secret = nil
|
32
|
+
lambda { LastFM.secret }.should raise_error(RuntimeError, "Secret is not set")
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should set client name" do
|
36
|
+
LastFM.client_name = "Foobar"
|
37
|
+
LastFM.client_name.should == "Foobar"
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should raise error when trying to read empty client name" do
|
41
|
+
LastFM.client_name = nil
|
42
|
+
lambda { LastFM.client_name }.should raise_error(RuntimeError, "Client name is not set")
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should have a default Auth URL" do
|
46
|
+
LastFM.api_key = "1234"
|
47
|
+
LastFM.auth_url.should == LastFM::DEFAULT_AUTH_URL + "?api_key=1234"
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should allow to set a custom Auth URL" do
|
51
|
+
custom_url = "http://foobarbaz.com"
|
52
|
+
|
53
|
+
LastFM.auth_url = custom_url
|
54
|
+
LastFM.auth_url.should == custom_url + "?api_key=1234"
|
55
|
+
end
|
56
|
+
|
57
|
+
describe "API requests" do
|
58
|
+
it "should raise error when trying to supply invalid params" do
|
59
|
+
lambda { LastFM.send_api_request("test", nil) }.should raise_error(RuntimeError, "Invalid params")
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should generate key signature" do
|
63
|
+
LastFM.secret = "test"
|
64
|
+
signature = LastFM.generate_signature(:foo => "hey", :bar => "hi", :baz => "hello")
|
65
|
+
signature.should == "46bfc3df86f175c869101e1c8c171589"
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should send request" do
|
69
|
+
LastFM.api_url = LastFM::DEFAULT_API_URL
|
70
|
+
LastFM.api_key = "7fbc71d4b818dc1277e273ac1ef92b07"
|
71
|
+
LastFM.client_name = "Last.fm Ruby gem"
|
72
|
+
|
73
|
+
LastFM.should_receive(:fetch_data).with("http://ws.audioscrobbler.com/2.0/?artist=Cher&album=Believe&method=album.getinfo&api_key=7fbc71d4b818dc1277e273ac1ef92b07&format=json").and_return({})
|
74
|
+
|
75
|
+
response = LastFM.send_api_request("album.getinfo", :artist => "Cher", :album => "Believe")
|
76
|
+
response.should be_a(Hash)
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should send GET request by default" do
|
80
|
+
LastFM.should_receive(:fetch_data).with("http://ws.audioscrobbler.com/2.0/?artist=Cher&album=Believe&method=album.getinfo&api_key=7fbc71d4b818dc1277e273ac1ef92b07&format=json").and_return({})
|
81
|
+
|
82
|
+
response = LastFM.send_api_request("album.getinfo", :artist => "Cher", :album => "Believe")
|
83
|
+
response.should be_a(Hash)
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should send request with key signature" do
|
87
|
+
LastFM.secret = "test"
|
88
|
+
LastFM.should_receive(:fetch_data).with("http://ws.audioscrobbler.com/2.0/?artist=Cher&album=Believe&method=album.getinfo&api_key=7fbc71d4b818dc1277e273ac1ef92b07&api_sig=b796a3385c59872367f31fc510a4ee21&format=json").and_return({})
|
89
|
+
|
90
|
+
response = LastFM.send_api_request("album.getinfo", :artist => "Cher", :album => "Believe", :api_sig => true)
|
91
|
+
response.should be_a(Hash)
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should send POST requests" do
|
95
|
+
LastFM.should_receive(:post_data).with("http://ws.audioscrobbler.com/2.0/", {:user => "jeff", :message => "hi Jeff!", :method => "user.shout", :api_key => "7fbc71d4b818dc1277e273ac1ef92b07", :api_sig => "83c66301079de9f515be5e0206ddbb18", :format => "json"}).and_return({})
|
96
|
+
|
97
|
+
response = LastFM.send_api_request("user.shout", {:user => "jeff", :message => "hi Jeff!", :api_sig => true}, :post)
|
98
|
+
response.should be_a(Hash)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: lastfm-client
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.3
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Piotr Chmolowski
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-03-05 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: json
|
16
|
+
requirement: &70293269416280 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 1.4.6
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70293269416280
|
25
|
+
description: Last.fm API client
|
26
|
+
email:
|
27
|
+
- piotr@chmolowski.pl
|
28
|
+
executables: []
|
29
|
+
extensions: []
|
30
|
+
extra_rdoc_files: []
|
31
|
+
files:
|
32
|
+
- .DS_Store
|
33
|
+
- .gitignore
|
34
|
+
- .rspec
|
35
|
+
- Gemfile
|
36
|
+
- LICENSE
|
37
|
+
- README.md
|
38
|
+
- Rakefile
|
39
|
+
- lastfm.gemspec
|
40
|
+
- lib/.DS_Store
|
41
|
+
- lib/lastfm-client.rb
|
42
|
+
- lib/lastfm-client/.DS_Store
|
43
|
+
- lib/lastfm-client/api_class.rb
|
44
|
+
- lib/lastfm-client/api_classes/album.rb
|
45
|
+
- lib/lastfm-client/api_classes/artist.rb
|
46
|
+
- lib/lastfm-client/api_classes/auth.rb
|
47
|
+
- lib/lastfm-client/api_classes/chart.rb
|
48
|
+
- lib/lastfm-client/api_classes/event.rb
|
49
|
+
- lib/lastfm-client/api_classes/geo.rb
|
50
|
+
- lib/lastfm-client/api_classes/group.rb
|
51
|
+
- lib/lastfm-client/api_classes/library.rb
|
52
|
+
- lib/lastfm-client/api_classes/playlist.rb
|
53
|
+
- lib/lastfm-client/api_classes/radio.rb
|
54
|
+
- lib/lastfm-client/api_classes/tag.rb
|
55
|
+
- lib/lastfm-client/api_classes/tasteometer.rb
|
56
|
+
- lib/lastfm-client/api_classes/track.rb
|
57
|
+
- lib/lastfm-client/api_classes/user.rb
|
58
|
+
- lib/lastfm-client/api_classes/venue.rb
|
59
|
+
- lib/lastfm-client/version.rb
|
60
|
+
- spec/api_class_spec.rb
|
61
|
+
- spec/api_classes/album_spec.rb
|
62
|
+
- spec/api_classes/artist_spec.rb
|
63
|
+
- spec/api_classes/auth_spec.rb
|
64
|
+
- spec/api_classes/chart_spec.rb
|
65
|
+
- spec/api_classes/event_spec.rb
|
66
|
+
- spec/api_classes/geo_spec.rb
|
67
|
+
- spec/api_classes/group_spec.rb
|
68
|
+
- spec/api_classes/library_spec.rb
|
69
|
+
- spec/api_classes/playlist_spec.rb
|
70
|
+
- spec/api_classes/radio_spec.rb
|
71
|
+
- spec/api_classes/tag_spec.rb
|
72
|
+
- spec/api_classes/tasteometer_spec.rb
|
73
|
+
- spec/api_classes/track_spec.rb
|
74
|
+
- spec/api_classes/user_spec.rb
|
75
|
+
- spec/api_classes/venue_spec.rb
|
76
|
+
- spec/lastfm-client_spec.rb
|
77
|
+
- spec/spec_helper.rb
|
78
|
+
homepage: http://github.com/pch/lastfm-client
|
79
|
+
licenses: []
|
80
|
+
post_install_message:
|
81
|
+
rdoc_options: []
|
82
|
+
require_paths:
|
83
|
+
- lib
|
84
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
85
|
+
none: false
|
86
|
+
requirements:
|
87
|
+
- - ! '>='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
91
|
+
none: false
|
92
|
+
requirements:
|
93
|
+
- - ! '>='
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
96
|
+
requirements: []
|
97
|
+
rubyforge_project:
|
98
|
+
rubygems_version: 1.8.11
|
99
|
+
signing_key:
|
100
|
+
specification_version: 3
|
101
|
+
summary: Last.fm API client
|
102
|
+
test_files:
|
103
|
+
- spec/api_class_spec.rb
|
104
|
+
- spec/api_classes/album_spec.rb
|
105
|
+
- spec/api_classes/artist_spec.rb
|
106
|
+
- spec/api_classes/auth_spec.rb
|
107
|
+
- spec/api_classes/chart_spec.rb
|
108
|
+
- spec/api_classes/event_spec.rb
|
109
|
+
- spec/api_classes/geo_spec.rb
|
110
|
+
- spec/api_classes/group_spec.rb
|
111
|
+
- spec/api_classes/library_spec.rb
|
112
|
+
- spec/api_classes/playlist_spec.rb
|
113
|
+
- spec/api_classes/radio_spec.rb
|
114
|
+
- spec/api_classes/tag_spec.rb
|
115
|
+
- spec/api_classes/tasteometer_spec.rb
|
116
|
+
- spec/api_classes/track_spec.rb
|
117
|
+
- spec/api_classes/user_spec.rb
|
118
|
+
- spec/api_classes/venue_spec.rb
|
119
|
+
- spec/lastfm-client_spec.rb
|
120
|
+
- spec/spec_helper.rb
|