lastfm 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.rspec +2 -0
- data/README.rdoc +4 -0
- data/Rakefile +7 -12
- data/VERSION +1 -1
- data/lastfm.gemspec +29 -9
- data/lib/lastfm.rb +10 -5
- data/lib/lastfm/method_category/artist.rb +9 -0
- data/lib/lastfm/method_category/auth.rb +8 -6
- data/lib/lastfm/method_category/base.rb +58 -0
- data/lib/lastfm/method_category/track.rb +25 -83
- data/lib/lastfm/response.rb +7 -17
- data/lib/lastfm/util.rb +18 -0
- data/spec/fixtures/artist_get_events.xml +57 -0
- data/spec/fixtures/ng.xml +3 -0
- data/spec/fixtures/ok.xml +128 -0
- data/spec/fixtures/track_get_info.xml +111 -0
- data/spec/fixtures/track_get_info_force_array.xml +89 -0
- data/spec/fixtures/track_get_similar.xml +5095 -0
- data/spec/fixtures/track_get_tags.xml +13 -0
- data/spec/fixtures/track_get_top_fans.xml +28 -0
- data/spec/fixtures/track_get_top_tags.xml +15 -0
- data/spec/fixtures/track_search.xml +35 -0
- data/spec/lastfm_spec.rb +137 -57
- data/spec/method_category_spec.rb +1 -1
- data/spec/response_spec.rb +13 -14
- data/spec/spec_helper.rb +12 -6
- metadata +63 -13
- data/lib/lastfm/method_category.rb +0 -26
data/.rspec
ADDED
data/README.rdoc
CHANGED
data/Rakefile
CHANGED
@@ -10,8 +10,10 @@ begin
|
|
10
10
|
gem.email = "youpy@buycheapviagraonlinenow.com"
|
11
11
|
gem.homepage = "http://github.com/youpy/ruby-lastfm"
|
12
12
|
gem.authors = ["youpy"]
|
13
|
-
gem.add_development_dependency "rspec"
|
13
|
+
gem.add_development_dependency "rspec", ">= 2.0.0"
|
14
14
|
gem.add_dependency "httparty"
|
15
|
+
gem.add_dependency "xml-simple"
|
16
|
+
gem.add_dependency "activesupport"
|
15
17
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
16
18
|
end
|
17
19
|
Jeweler::GemcutterTasks.new
|
@@ -19,21 +21,14 @@ rescue LoadError
|
|
19
21
|
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
20
22
|
end
|
21
23
|
|
22
|
-
require '
|
23
|
-
Spec::Rake::SpecTask.new(:spec) do |spec|
|
24
|
-
spec.libs << 'lib' << 'spec'
|
25
|
-
spec.spec_files = FileList['spec/**/*_spec.rb']
|
26
|
-
end
|
24
|
+
require 'rspec/core/rake_task'
|
27
25
|
|
28
|
-
|
29
|
-
spec.libs << 'lib' << 'spec'
|
26
|
+
RSpec::Core::RakeTask.new(:core) do |spec|
|
30
27
|
spec.pattern = 'spec/**/*_spec.rb'
|
31
|
-
spec.rcov = true
|
32
28
|
end
|
33
29
|
|
34
|
-
task :
|
35
|
-
|
36
|
-
task :default => :spec
|
30
|
+
task :core => :check_dependencies
|
31
|
+
task :default => :core
|
37
32
|
|
38
33
|
require 'rake/rdoctask'
|
39
34
|
Rake::RDocTask.new do |rdoc|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0
|
1
|
+
0.1.0
|
data/lastfm.gemspec
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
# Generated by jeweler
|
2
|
-
# DO NOT EDIT THIS FILE
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{lastfm}
|
8
|
-
s.version = "0.0
|
8
|
+
s.version = "0.1.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["youpy"]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-11-18}
|
13
13
|
s.description = %q{A ruby interface for Last.fm web services version 2.0}
|
14
14
|
s.email = %q{youpy@buycheapviagraonlinenow.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -19,16 +19,29 @@ Gem::Specification.new do |s|
|
|
19
19
|
s.files = [
|
20
20
|
".document",
|
21
21
|
".gitignore",
|
22
|
+
".rspec",
|
22
23
|
"LICENSE",
|
23
24
|
"README.rdoc",
|
24
25
|
"Rakefile",
|
25
26
|
"VERSION",
|
26
27
|
"lastfm.gemspec",
|
27
28
|
"lib/lastfm.rb",
|
28
|
-
"lib/lastfm/method_category.rb",
|
29
|
+
"lib/lastfm/method_category/artist.rb",
|
29
30
|
"lib/lastfm/method_category/auth.rb",
|
31
|
+
"lib/lastfm/method_category/base.rb",
|
30
32
|
"lib/lastfm/method_category/track.rb",
|
31
33
|
"lib/lastfm/response.rb",
|
34
|
+
"lib/lastfm/util.rb",
|
35
|
+
"spec/fixtures/artist_get_events.xml",
|
36
|
+
"spec/fixtures/ng.xml",
|
37
|
+
"spec/fixtures/ok.xml",
|
38
|
+
"spec/fixtures/track_get_info.xml",
|
39
|
+
"spec/fixtures/track_get_info_force_array.xml",
|
40
|
+
"spec/fixtures/track_get_similar.xml",
|
41
|
+
"spec/fixtures/track_get_tags.xml",
|
42
|
+
"spec/fixtures/track_get_top_fans.xml",
|
43
|
+
"spec/fixtures/track_get_top_tags.xml",
|
44
|
+
"spec/fixtures/track_search.xml",
|
32
45
|
"spec/lastfm_spec.rb",
|
33
46
|
"spec/method_category_spec.rb",
|
34
47
|
"spec/response_spec.rb",
|
@@ -37,7 +50,7 @@ Gem::Specification.new do |s|
|
|
37
50
|
s.homepage = %q{http://github.com/youpy/ruby-lastfm}
|
38
51
|
s.rdoc_options = ["--charset=UTF-8"]
|
39
52
|
s.require_paths = ["lib"]
|
40
|
-
s.rubygems_version = %q{1.3.
|
53
|
+
s.rubygems_version = %q{1.3.6}
|
41
54
|
s.summary = %q{A Ruby interface for Last.fm Web Services}
|
42
55
|
s.test_files = [
|
43
56
|
"spec/lastfm_spec.rb",
|
@@ -51,14 +64,21 @@ Gem::Specification.new do |s|
|
|
51
64
|
s.specification_version = 3
|
52
65
|
|
53
66
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
54
|
-
s.add_development_dependency(%q<rspec>, [">= 0"])
|
67
|
+
s.add_development_dependency(%q<rspec>, [">= 2.0.0"])
|
55
68
|
s.add_runtime_dependency(%q<httparty>, [">= 0"])
|
69
|
+
s.add_runtime_dependency(%q<xml-simple>, [">= 0"])
|
70
|
+
s.add_runtime_dependency(%q<activesupport>, [">= 0"])
|
56
71
|
else
|
57
|
-
s.add_dependency(%q<rspec>, [">= 0"])
|
72
|
+
s.add_dependency(%q<rspec>, [">= 2.0.0"])
|
58
73
|
s.add_dependency(%q<httparty>, [">= 0"])
|
74
|
+
s.add_dependency(%q<xml-simple>, [">= 0"])
|
75
|
+
s.add_dependency(%q<activesupport>, [">= 0"])
|
59
76
|
end
|
60
77
|
else
|
61
|
-
s.add_dependency(%q<rspec>, [">= 0"])
|
78
|
+
s.add_dependency(%q<rspec>, [">= 2.0.0"])
|
62
79
|
s.add_dependency(%q<httparty>, [">= 0"])
|
80
|
+
s.add_dependency(%q<xml-simple>, [">= 0"])
|
81
|
+
s.add_dependency(%q<activesupport>, [">= 0"])
|
63
82
|
end
|
64
83
|
end
|
84
|
+
|
data/lib/lastfm.rb
CHANGED
@@ -1,12 +1,14 @@
|
|
1
|
+
require 'lastfm/util'
|
1
2
|
require 'lastfm/response'
|
2
|
-
require 'lastfm/method_category'
|
3
|
-
|
3
|
+
require 'lastfm/method_category/base'
|
4
4
|
require 'lastfm/method_category/auth'
|
5
5
|
require 'lastfm/method_category/track'
|
6
|
+
require 'lastfm/method_category/artist'
|
6
7
|
|
7
8
|
require 'rubygems'
|
8
9
|
require 'digest/md5'
|
9
10
|
require 'httparty'
|
11
|
+
require 'active_support'
|
10
12
|
|
11
13
|
class Lastfm
|
12
14
|
API_ROOT = 'http://ws.audioscrobbler.com/2.0'
|
@@ -25,11 +27,15 @@ class Lastfm
|
|
25
27
|
end
|
26
28
|
|
27
29
|
def auth
|
28
|
-
Auth.new(self)
|
30
|
+
MethodCategory::Auth.new(self)
|
29
31
|
end
|
30
32
|
|
31
33
|
def track
|
32
|
-
Track.new(self)
|
34
|
+
MethodCategory::Track.new(self)
|
35
|
+
end
|
36
|
+
|
37
|
+
def artist
|
38
|
+
MethodCategory::Artist.new(self)
|
33
39
|
end
|
34
40
|
|
35
41
|
def request(method, params = {}, http_method = :get, with_signature = false, with_session = false)
|
@@ -41,7 +47,6 @@ class Lastfm
|
|
41
47
|
|
42
48
|
params.update(:sk => @session) if with_session
|
43
49
|
params.update(:api_sig => Digest::MD5.hexdigest(build_method_signature(params))) if with_signature
|
44
|
-
params.update(:format => 'json')
|
45
50
|
|
46
51
|
response = Response.new(self.class.send(http_method, '/', (http_method == :post ? :body : :query) => params).body)
|
47
52
|
unless response.success?
|
@@ -1,11 +1,13 @@
|
|
1
1
|
class Lastfm
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
2
|
+
module MethodCategory
|
3
|
+
class Auth < Base
|
4
|
+
method_for_authentication :get_token, [], [] do |response|
|
5
|
+
response.xml['token']
|
6
|
+
end
|
6
7
|
|
7
|
-
|
8
|
-
|
8
|
+
method_for_authentication :get_session, [:token], [] do |response|
|
9
|
+
response.xml['session']['key']
|
10
|
+
end
|
9
11
|
end
|
10
12
|
end
|
11
13
|
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
class Lastfm
|
2
|
+
module MethodCategory
|
3
|
+
class Base
|
4
|
+
class << self
|
5
|
+
def write_method(id, mandatory, optional = [])
|
6
|
+
__define_method(:write_request, id, mandatory, optional) do |response|
|
7
|
+
response.success?
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def method_with_authentication(id, mandatory, optional = [], &block)
|
12
|
+
__define_method(:request_with_authentication, id, mandatory, optional, &block)
|
13
|
+
end
|
14
|
+
|
15
|
+
def method_for_authentication(id, mandatory, optional = [], &block)
|
16
|
+
__define_method(:request_for_authentication, id, mandatory, optional, &block)
|
17
|
+
end
|
18
|
+
|
19
|
+
def regular_method(id, mandatory, optional = [], &block)
|
20
|
+
__define_method(:request, id, mandatory, optional, &block)
|
21
|
+
end
|
22
|
+
|
23
|
+
def __define_method(method, id, mandatory, optional, &block)
|
24
|
+
unless block
|
25
|
+
block = Proc.new { |response| response.xml }
|
26
|
+
end
|
27
|
+
|
28
|
+
define_method(id) do |*args|
|
29
|
+
block.call(send(method, id.to_s.camelize(:lower), Lastfm::Util.build_options(args, mandatory, optional)))
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def initialize(lastfm)
|
35
|
+
@lastfm = lastfm
|
36
|
+
end
|
37
|
+
|
38
|
+
def write_request(method, params = {})
|
39
|
+
request(method, params, :post, true, true)
|
40
|
+
end
|
41
|
+
|
42
|
+
def request_with_authentication(method, params = {})
|
43
|
+
request(method, params, :get, true, true)
|
44
|
+
end
|
45
|
+
|
46
|
+
def request_for_authentication(method, params = {})
|
47
|
+
request(method, params, :get, true)
|
48
|
+
end
|
49
|
+
|
50
|
+
def request(*args)
|
51
|
+
method, *rest = args
|
52
|
+
method = [self.class.name.split(/::/).last.downcase, method].join('.')
|
53
|
+
|
54
|
+
@lastfm.request(method, *rest)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -1,87 +1,29 @@
|
|
1
1
|
class Lastfm
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
request('getSimilar', {
|
28
|
-
:artist => artist,
|
29
|
-
:track => track,
|
30
|
-
})
|
31
|
-
end
|
32
|
-
|
33
|
-
def get_tags(artist, track)
|
34
|
-
request_with_authentication('getTags', {
|
35
|
-
:artist => artist,
|
36
|
-
:track => track,
|
37
|
-
})
|
38
|
-
end
|
39
|
-
|
40
|
-
def get_top_fans(artist, track)
|
41
|
-
request('getTopFans', {
|
42
|
-
:artist => artist,
|
43
|
-
:track => track,
|
44
|
-
})
|
45
|
-
end
|
46
|
-
|
47
|
-
def get_top_tags(artist, track)
|
48
|
-
request('getTopTags', {
|
49
|
-
:artist => artist,
|
50
|
-
:track => track,
|
51
|
-
})
|
52
|
-
end
|
53
|
-
|
54
|
-
def love(artist, track)
|
55
|
-
write_request('love', {
|
56
|
-
:artist => artist,
|
57
|
-
:track => track,
|
58
|
-
})
|
59
|
-
end
|
60
|
-
|
61
|
-
def remove_tag(artist, track, tag)
|
62
|
-
write_request('removeTag', {
|
63
|
-
:artist => artist,
|
64
|
-
:track => track,
|
65
|
-
:tag => tag
|
66
|
-
})
|
67
|
-
end
|
68
|
-
|
69
|
-
def search(artist, track, limit = nil, page = nil)
|
70
|
-
request('search', {
|
71
|
-
:artist => artist,
|
72
|
-
:track => track,
|
73
|
-
:limit => limit,
|
74
|
-
:page => page
|
75
|
-
})
|
76
|
-
end
|
77
|
-
|
78
|
-
def share(artist, track, recipient, message = nil)
|
79
|
-
write_request('share', {
|
80
|
-
:artist => artist,
|
81
|
-
:track => track,
|
82
|
-
:recipient => recipient,
|
83
|
-
:message => message
|
84
|
-
})
|
2
|
+
module MethodCategory
|
3
|
+
class Track < Base
|
4
|
+
write_method :add_tags, [:artist, :track, :tags]
|
5
|
+
write_method :remove_tag, [:artist, :track, :tag]
|
6
|
+
write_method :ban, [:artist, :track]
|
7
|
+
write_method :love, [:artist, :track]
|
8
|
+
write_method :share, [:artist, :track, :recipient], [[:message, nil]]
|
9
|
+
|
10
|
+
regular_method :get_info, [:artist, :track], [[:username, nil]] do |response|
|
11
|
+
response.xml['track']
|
12
|
+
end
|
13
|
+
regular_method :get_top_fans, [:artist, :track], [] do |response|
|
14
|
+
response.xml['topfans']['user']
|
15
|
+
end
|
16
|
+
regular_method :get_top_tags, [:artist, :track], [] do |response|
|
17
|
+
response.xml['toptags']['tag']
|
18
|
+
end
|
19
|
+
regular_method :get_similar, [:artist, :track], [] do |response|
|
20
|
+
response.xml['similartracks']['track'][1 .. -1]
|
21
|
+
end
|
22
|
+
regular_method :search, [:track], [[:artist, nil], [:limit, nil], [:page, nil]]
|
23
|
+
|
24
|
+
method_with_authentication :get_tags, [:artist, :track], [] do |response|
|
25
|
+
response.xml['tags']['tag']
|
26
|
+
end
|
85
27
|
end
|
86
28
|
end
|
87
29
|
end
|
data/lib/lastfm/response.rb
CHANGED
@@ -1,34 +1,24 @@
|
|
1
1
|
require 'rubygems'
|
2
|
-
require '
|
2
|
+
require 'xmlsimple'
|
3
3
|
|
4
4
|
class Lastfm
|
5
5
|
class Response
|
6
|
-
|
7
|
-
# API returns XML response when no child node?
|
8
|
-
if body == '<?xml version="1.0" encoding="utf-8"?>
|
9
|
-
<lfm status="ok">
|
10
|
-
</lfm>
|
11
|
-
'
|
12
|
-
@parsed_body = {}
|
13
|
-
else
|
14
|
-
@parsed_body = JSON.parse(body)
|
15
|
-
end
|
16
|
-
end
|
6
|
+
attr_reader :xml
|
17
7
|
|
18
|
-
def
|
19
|
-
@
|
8
|
+
def initialize(body)
|
9
|
+
@xml = XmlSimple.xml_in(body, 'ForceArray' => ['image', 'tag', 'user', 'event'])
|
20
10
|
end
|
21
11
|
|
22
12
|
def success?
|
23
|
-
|
13
|
+
@xml['status'] == 'ok'
|
24
14
|
end
|
25
15
|
|
26
16
|
def message
|
27
|
-
|
17
|
+
@xml['error']['content']
|
28
18
|
end
|
29
19
|
|
30
20
|
def error
|
31
|
-
|
21
|
+
@xml['error']['code'].to_i
|
32
22
|
end
|
33
23
|
end
|
34
24
|
end
|
data/lib/lastfm/util.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
class Lastfm
|
2
|
+
class Util
|
3
|
+
def self.build_options(args, mandatory, optional)
|
4
|
+
options = {}
|
5
|
+
|
6
|
+
mandatory.each_with_index do |name, index|
|
7
|
+
raise ArgumentError.new('%s is required' % name) unless args[index]
|
8
|
+
options[name] = args[index]
|
9
|
+
end
|
10
|
+
|
11
|
+
optional.each_with_index do |name, index|
|
12
|
+
options[name[0]] = args[index + mandatory.size] || name[1]
|
13
|
+
end
|
14
|
+
|
15
|
+
options
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|