scrobbler-ng 2.0.4 → 2.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +12 -89
- data/VERSION.yml +2 -2
- data/lib/scrobbler/base.rb +72 -20
- data/lib/scrobbler/user.rb +25 -2
- data/scrobbler-ng.gemspec +2 -2
- metadata +4 -4
data/README.rdoc
CHANGED
@@ -10,95 +10,18 @@ all functions is available at http://rdoc.info/projects/xhochy/scrobbler
|
|
10
10
|
== Initialization
|
11
11
|
|
12
12
|
Scrobbler::Base.api_key = 'foo123'
|
13
|
-
|
14
|
-
== Users
|
15
|
-
|
16
|
-
user = Scrobbler::User.new('jnunemaker')
|
17
|
-
|
18
|
-
puts "#{user.username}'s Recent Tracks"
|
19
|
-
puts "=" * (user.username.length + 16)
|
20
|
-
user.recent_tracks.each { |t| puts t.name }
|
21
|
-
|
22
|
-
puts
|
23
|
-
puts
|
24
|
-
|
25
|
-
puts "#{user.username}'s Top Tracks"
|
26
|
-
puts "=" * (user.username.length + 13)
|
27
|
-
user.top_tracks.each { |t| puts "(#{t.playcount}) #{t.name}" }
|
28
|
-
|
29
|
-
== Albums
|
30
|
-
|
31
|
-
album = Scrobbler::Album.new('Some Hearts', :artist => 'Carrie Underwood', :include_info => true)
|
32
|
-
|
33
|
-
puts "Album: #{album.name}"
|
34
|
-
puts "Artist: #{album.artist}"
|
35
|
-
puts "Playcount: #{album.playcount}"
|
36
|
-
puts "URL: #{album.url}"
|
37
|
-
puts "Release Date: #{album.release_date.strftime('%m/%d/%Y')}"
|
38
|
-
|
39
|
-
==Artists
|
40
|
-
|
41
|
-
artist = Scrobbler::Artist.new('Carrie Underwood')
|
42
13
|
|
43
|
-
|
44
|
-
puts "=" * 10
|
45
|
-
artist.top_tracks.each { |t| puts "(#{t.playcount}) #{t.name}" }
|
46
|
-
|
47
|
-
puts
|
48
|
-
|
49
|
-
puts 'Similar Artists'
|
50
|
-
puts "=" * 15
|
51
|
-
artist.similar.each { |a| puts "(#{a.match}%) #{a.name}" }
|
52
|
-
|
53
|
-
==Geo
|
54
|
-
|
55
|
-
geo = Scrobbler::Geo.new()
|
56
|
-
|
57
|
-
puts 'Events'
|
58
|
-
puts "=" * 10
|
59
|
-
geo.events(:location => 'Manchester').each { |e| puts "(#{e.id}) #{e.title}" }
|
60
|
-
|
61
|
-
puts
|
14
|
+
== Usage
|
62
15
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
==Tags
|
75
|
-
|
76
|
-
tag = Scrobbler::Tag.new('country')
|
77
|
-
|
78
|
-
puts 'Top Albums'
|
79
|
-
tag.top_albums.each { |a| puts "(#{a.count}) #{a.name} by #{a.artist}" }
|
80
|
-
|
81
|
-
puts
|
82
|
-
|
83
|
-
puts 'Top Tracks'
|
84
|
-
tag.top_tracks.each { |t| puts "(#{t.count}) #{t.name} by #{t.artist}" }
|
85
|
-
|
86
|
-
==Tracks
|
87
|
-
|
88
|
-
track = Scrobbler::Track.new('Carrie Underwood', 'Before He Cheats')
|
89
|
-
puts 'Fans'
|
90
|
-
puts "=" * 4
|
91
|
-
track.top_fans.each { |u| puts "(#{u.weight}) #{u.username}" }
|
92
|
-
|
93
|
-
== Simple Authentication (for Scrobbling)
|
94
|
-
|
95
|
-
work in progress...
|
96
|
-
|
97
|
-
== Scrobbling
|
98
|
-
|
99
|
-
work in progress...
|
100
|
-
|
101
|
-
== Now Playing Submission
|
102
|
-
|
103
|
-
work in progress...
|
16
|
+
coming soon ...
|
17
|
+
|
18
|
+
== Note on Patches/Pull Requests
|
19
|
+
|
20
|
+
* Fork the project.
|
21
|
+
* Make your feature addition or bug fix.
|
22
|
+
* Add tests for it. This is important so I don't break it in a
|
23
|
+
future version unintentionally.
|
24
|
+
* Commit, do not mess with rakefile, version, or history.
|
25
|
+
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
26
|
+
* Send me a pull request. Bonus points for topic branches.
|
104
27
|
|
data/VERSION.yml
CHANGED
data/lib/scrobbler/base.rb
CHANGED
@@ -1,19 +1,28 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
require 'digest/md5'
|
4
|
+
require 'net/https'
|
4
5
|
require 'nokogiri'
|
6
|
+
require 'uri'
|
5
7
|
|
6
8
|
# Only set KCODE in Ruby 1.8.X, not in 1.9.X as it is deprecated
|
7
9
|
if RUBY_VERSION =~ /1\.8\.[0-9]/ then
|
8
10
|
$KCODE = 'u'
|
9
11
|
end
|
10
12
|
|
11
|
-
|
12
13
|
module Scrobbler
|
13
14
|
|
14
|
-
API_URL
|
15
|
+
API_URL = 'http://ws.audioscrobbler.com/' unless defined? API_URL
|
15
16
|
|
16
17
|
class Base
|
18
|
+
|
19
|
+
# By default, there is no cache
|
20
|
+
@@cache = []
|
21
|
+
|
22
|
+
def Base.add_cache(cache)
|
23
|
+
@@cache << cache
|
24
|
+
end
|
25
|
+
|
17
26
|
# Set the default API key.
|
18
27
|
#
|
19
28
|
# This key will be used by all Scrobbler classes and objects.
|
@@ -72,6 +81,53 @@ module Scrobbler
|
|
72
81
|
def Base.post_request(api_method, parameters = {})
|
73
82
|
Base.request(api_method, parameters, 'post')
|
74
83
|
end
|
84
|
+
|
85
|
+
# Load a request from cache if possible
|
86
|
+
#
|
87
|
+
# @param [Hash] parameters The parameters passed as URL params.
|
88
|
+
# @return [String,nil]
|
89
|
+
def Base.load_from_cache(parameters)
|
90
|
+
@@cache.each do |cache|
|
91
|
+
if cache.has?(parameters)
|
92
|
+
return cache.get(parameters)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
nil
|
96
|
+
end
|
97
|
+
|
98
|
+
# Save a request answer to all caches that would store it.
|
99
|
+
#
|
100
|
+
# @param [String] xml The answer from the Last.fm API
|
101
|
+
# @param [Hash] parameters The parameters passed as URL params.
|
102
|
+
# @return [nil]
|
103
|
+
def Base.save_to_cache(xml, parameters)
|
104
|
+
@@cache.each do |cache|
|
105
|
+
if cache.writable? then
|
106
|
+
cache.set(xml, parameters)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
# Fetch a http answer for the given request
|
112
|
+
#
|
113
|
+
# @param [String] request_method The HTTP verb for the request type
|
114
|
+
# @param [Array<String>] paramlist The URL(-query) parameters
|
115
|
+
# @return [String] The plain response from the Last.fm API
|
116
|
+
def Base.fetch_http(request_method, paramlist)
|
117
|
+
url = URI.join(API_URL, "/2.0/?#{paramlist.join('&')}")
|
118
|
+
case request_method.downcase
|
119
|
+
when "get"
|
120
|
+
req = Net::HTTP::Get.new(url.request_uri)
|
121
|
+
when "post"
|
122
|
+
req = Net::HTTP::Post.new(url.request_uri)
|
123
|
+
end
|
124
|
+
http = Net::HTTP.new(url.host, url.port)
|
125
|
+
http.use_ssl = (url.port == 443)
|
126
|
+
xml = http.start() do |conn|
|
127
|
+
conn.request(req)
|
128
|
+
end
|
129
|
+
xml.body
|
130
|
+
end
|
75
131
|
|
76
132
|
# Execute a request to the Audioscrobbler webservice
|
77
133
|
#
|
@@ -86,6 +142,7 @@ module Scrobbler
|
|
86
142
|
parameters = {:signed => false}.merge(parameters)
|
87
143
|
parameters['api_key'] = @@api_key
|
88
144
|
parameters['method'] = api_method.to_s
|
145
|
+
check_cache = false
|
89
146
|
paramlist = []
|
90
147
|
# Check if we want a signed call and pop :signed
|
91
148
|
if parameters.delete :signed
|
@@ -102,30 +159,25 @@ module Scrobbler
|
|
102
159
|
paramlist << "#{sanitize(a.at(0))}=#{sanitize(a.at(1))}"
|
103
160
|
end
|
104
161
|
else
|
162
|
+
if request_method == 'get' then
|
163
|
+
check_cache = true
|
164
|
+
end
|
105
165
|
parameters.each do |key, value|
|
106
166
|
paramlist << "#{sanitize(key)}=#{sanitize(value)}"
|
107
167
|
end
|
108
168
|
end
|
109
169
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
case request_method
|
116
|
-
when "get"
|
117
|
-
req = Net::HTTP::Get.new(url.request_uri)
|
118
|
-
when "post"
|
119
|
-
req = Net::HTTP::Post.new(url.request_uri)
|
120
|
-
end
|
121
|
-
http = Net::HTTP.new(url.host, url.port)
|
122
|
-
http.use_ssl = (url.port == 443)
|
123
|
-
|
170
|
+
xml = nil
|
171
|
+
# Check if we could read from cache
|
172
|
+
xml = load_from_cache(parameters) if check_cache
|
173
|
+
# Fetch the http answer if cache was empty
|
174
|
+
xml = fetch_http(request_method, paramlist) if xml.nil?
|
124
175
|
# Process it
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
176
|
+
doc = Nokogiri::XML(xml) { |config| config.noent.noblanks.nonet }
|
177
|
+
# Write to cache
|
178
|
+
save_to_cache(xml, parameters) if check_cache
|
179
|
+
|
180
|
+
# Return the parsed result
|
129
181
|
doc
|
130
182
|
end
|
131
183
|
|
data/lib/scrobbler/user.rb
CHANGED
@@ -68,8 +68,31 @@ module Scrobbler
|
|
68
68
|
end
|
69
69
|
|
70
70
|
# Get a list of the user's friends on Last.fm.
|
71
|
-
def friends(
|
72
|
-
|
71
|
+
def friends(opts={})
|
72
|
+
result = []
|
73
|
+
if opts.delete :all
|
74
|
+
params = {:page => 1, :limit => 50, :user => @name}.merge(opts)
|
75
|
+
doc = Base.request('user.getfriends', params)
|
76
|
+
root = nil
|
77
|
+
doc.root.children.each do |child|
|
78
|
+
next unless child.name == 'friends'
|
79
|
+
root = child
|
80
|
+
end
|
81
|
+
total_pages = root['totalPages'].to_i
|
82
|
+
root.children.each do |child|
|
83
|
+
next unless child.name == 'user'
|
84
|
+
result << Scrobbler::User.new_from_libxml(child)
|
85
|
+
end
|
86
|
+
puts total_pages
|
87
|
+
(2..total_pages).each do |i|
|
88
|
+
params[:page] = i
|
89
|
+
result.concat call('user.getfriends', :friends, User, params)
|
90
|
+
end
|
91
|
+
else
|
92
|
+
params = {:page => 1, :limit => 50, :user => @name}.merge(opts)
|
93
|
+
result = call('user.getfriends', :friends, User, params)
|
94
|
+
end
|
95
|
+
result
|
73
96
|
end
|
74
97
|
|
75
98
|
# Get information about a user profile.
|
data/scrobbler-ng.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{scrobbler-ng}
|
8
|
-
s.version = "2.0.
|
8
|
+
s.version = "2.0.5"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["John Nunemaker", "Jonathan Rudenberg", "Uwe L. Korn"]
|
12
|
-
s.date = %q{2010-07-
|
12
|
+
s.date = %q{2010-07-30}
|
13
13
|
s.description = %q{A ruby library for accessing the Last.fm 2.0 API. It is higly optimized so that it uses less memory and parses XML (through Nokogiri) than other implementations.}
|
14
14
|
s.email = %q{uwelk@xhochy.org}
|
15
15
|
s.extra_rdoc_files = [
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: scrobbler-ng
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 5
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 2
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 2.0.
|
9
|
+
- 5
|
10
|
+
version: 2.0.5
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- John Nunemaker
|
@@ -17,7 +17,7 @@ autorequire:
|
|
17
17
|
bindir: bin
|
18
18
|
cert_chain: []
|
19
19
|
|
20
|
-
date: 2010-07-
|
20
|
+
date: 2010-07-30 00:00:00 +02:00
|
21
21
|
default_executable:
|
22
22
|
dependencies:
|
23
23
|
- !ruby/object:Gem::Dependency
|