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 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
- puts 'Top Tracks'
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
- puts 'Top Artists'
64
- puts "=" * 10
65
- geo.top_artists(:location => 'Manchester').each { |a| puts "(#{a.name}) #{a.playcount}" }
66
-
67
- puts
68
-
69
- puts 'Top Tracks'
70
- puts "=" * 10
71
- geo.top_tracks(:location => 'Manchester').each { |t| puts "(#{a.name}) #{a.playcount}" }
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
@@ -1,5 +1,5 @@
1
1
  ---
2
+ :patch: 5
2
3
  :major: 2
3
- :minor: 0
4
- :patch: 4
5
4
  :build:
5
+ :minor: 0
@@ -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 = 'http://ws.audioscrobbler.com/'
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
- # TODO Caching!
111
-
112
- url = URI.join(API_URL, "/2.0/?#{paramlist.join('&')}")
113
-
114
- # Fetch the http answer
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
- res = http.start() { |conn| conn.request(req) }
126
- doc = Nokogiri::XML(res.body) do |config|
127
- config.noent.noblanks.nonet
128
- end
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
 
@@ -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(page=1, limit=50)
72
- call('user.getfriends', :friends, User, {:user => @name, :page => page, :limit => limit})
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.4"
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-28}
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: 7
4
+ hash: 5
5
5
  prerelease: false
6
6
  segments:
7
7
  - 2
8
8
  - 0
9
- - 4
10
- version: 2.0.4
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-28 00:00:00 +02:00
20
+ date: 2010-07-30 00:00:00 +02:00
21
21
  default_executable:
22
22
  dependencies:
23
23
  - !ruby/object:Gem::Dependency