scrobbler-ng 2.0.4 → 2.0.5
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/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
|