scrobbler 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. data/History.txt +1 -0
  2. data/Manifest.txt +58 -0
  3. data/README.txt +71 -0
  4. data/Rakefile +89 -0
  5. data/examples/album.rb +18 -0
  6. data/examples/artist.rb +14 -0
  7. data/examples/tag.rb +12 -0
  8. data/examples/track.rb +7 -0
  9. data/examples/user.rb +15 -0
  10. data/lib/scrobbler.rb +13 -0
  11. data/lib/scrobbler/album.rb +143 -0
  12. data/lib/scrobbler/artist.rb +127 -0
  13. data/lib/scrobbler/base.rb +29 -0
  14. data/lib/scrobbler/chart.rb +31 -0
  15. data/lib/scrobbler/rest.rb +47 -0
  16. data/lib/scrobbler/tag.rb +104 -0
  17. data/lib/scrobbler/track.rb +96 -0
  18. data/lib/scrobbler/user.rb +192 -0
  19. data/lib/scrobbler/version.rb +9 -0
  20. data/setup.rb +1585 -0
  21. data/test/fixtures/xml/album/info.xml +70 -0
  22. data/test/fixtures/xml/artist/fans.xml +18 -0
  23. data/test/fixtures/xml/artist/similar.xml +39 -0
  24. data/test/fixtures/xml/artist/topalbums.xml +36 -0
  25. data/test/fixtures/xml/artist/toptags.xml +18 -0
  26. data/test/fixtures/xml/artist/toptracks.xml +27 -0
  27. data/test/fixtures/xml/tag/topalbums.xml +39 -0
  28. data/test/fixtures/xml/tag/topartists.xml +39 -0
  29. data/test/fixtures/xml/tag/toptags.xml +252 -0
  30. data/test/fixtures/xml/tag/toptracks.xml +30 -0
  31. data/test/fixtures/xml/track/fans.xml +28 -0
  32. data/test/fixtures/xml/track/toptags.xml +33 -0
  33. data/test/fixtures/xml/user/friends.xml +21 -0
  34. data/test/fixtures/xml/user/neighbours.xml +18 -0
  35. data/test/fixtures/xml/user/profile.xml +12 -0
  36. data/test/fixtures/xml/user/recentbannedtracks.xml +24 -0
  37. data/test/fixtures/xml/user/recentlovedtracks.xml +24 -0
  38. data/test/fixtures/xml/user/recenttracks.xml +27 -0
  39. data/test/fixtures/xml/user/systemrecs.xml +18 -0
  40. data/test/fixtures/xml/user/topalbums.xml +42 -0
  41. data/test/fixtures/xml/user/topartists.xml +30 -0
  42. data/test/fixtures/xml/user/toptags.xml +18 -0
  43. data/test/fixtures/xml/user/toptracks.xml +27 -0
  44. data/test/fixtures/xml/user/weeklyalbumchart.xml +35 -0
  45. data/test/fixtures/xml/user/weeklyalbumchart_from_1138536002_to_1139140802.xml +35 -0
  46. data/test/fixtures/xml/user/weeklyartistchart.xml +38 -0
  47. data/test/fixtures/xml/user/weeklyartistchart_from_1138536002_to_1139140802.xml +59 -0
  48. data/test/fixtures/xml/user/weeklychartlist.xml +74 -0
  49. data/test/fixtures/xml/user/weeklytrackchart.xml +35 -0
  50. data/test/fixtures/xml/user/weeklytrackchart_from_1138536002_to_1139140802.xml +35 -0
  51. data/test/mocks/rest.rb +26 -0
  52. data/test/test_helper.rb +17 -0
  53. data/test/unit/album_test.rb +86 -0
  54. data/test/unit/artist_test.rb +82 -0
  55. data/test/unit/chart_test.rb +34 -0
  56. data/test/unit/tag_test.rb +65 -0
  57. data/test/unit/track_test.rb +42 -0
  58. data/test/unit/user_test.rb +291 -0
  59. metadata +120 -0
@@ -0,0 +1 @@
1
+ * v 0.1.0: initial release
@@ -0,0 +1,58 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.txt
4
+ Rakefile
5
+ setup.rb
6
+ examples/album.rb
7
+ examples/artist.rb
8
+ examples/tag.rb
9
+ examples/track.rb
10
+ examples/user.rb
11
+ lib/scrobbler.rb
12
+ lib/scrobbler/album.rb
13
+ lib/scrobbler/artist.rb
14
+ lib/scrobbler/base.rb
15
+ lib/scrobbler/chart.rb
16
+ lib/scrobbler/rest.rb
17
+ lib/scrobbler/tag.rb
18
+ lib/scrobbler/track.rb
19
+ lib/scrobbler/user.rb
20
+ lib/scrobbler/version.rb
21
+ test/test_helper.rb
22
+ test/fixtures/xml/album/info.xml
23
+ test/fixtures/xml/artist/fans.xml
24
+ test/fixtures/xml/artist/similar.xml
25
+ test/fixtures/xml/artist/topalbums.xml
26
+ test/fixtures/xml/artist/toptags.xml
27
+ test/fixtures/xml/artist/toptracks.xml
28
+ test/fixtures/xml/tag/topalbums.xml
29
+ test/fixtures/xml/tag/topartists.xml
30
+ test/fixtures/xml/tag/toptags.xml
31
+ test/fixtures/xml/tag/toptracks.xml
32
+ test/fixtures/xml/track/fans.xml
33
+ test/fixtures/xml/track/toptags.xml
34
+ test/fixtures/xml/user/friends.xml
35
+ test/fixtures/xml/user/neighbours.xml
36
+ test/fixtures/xml/user/profile.xml
37
+ test/fixtures/xml/user/recentbannedtracks.xml
38
+ test/fixtures/xml/user/recentlovedtracks.xml
39
+ test/fixtures/xml/user/recenttracks.xml
40
+ test/fixtures/xml/user/systemrecs.xml
41
+ test/fixtures/xml/user/topalbums.xml
42
+ test/fixtures/xml/user/topartists.xml
43
+ test/fixtures/xml/user/toptags.xml
44
+ test/fixtures/xml/user/toptracks.xml
45
+ test/fixtures/xml/user/weeklyalbumchart.xml
46
+ test/fixtures/xml/user/weeklyalbumchart_from_1138536002_to_1139140802.xml
47
+ test/fixtures/xml/user/weeklyartistchart.xml
48
+ test/fixtures/xml/user/weeklyartistchart_from_1138536002_to_1139140802.xml
49
+ test/fixtures/xml/user/weeklychartlist.xml
50
+ test/fixtures/xml/user/weeklytrackchart.xml
51
+ test/fixtures/xml/user/weeklytrackchart_from_1138536002_to_1139140802.xml
52
+ test/mocks/rest.rb
53
+ test/unit/album_test.rb
54
+ test/unit/artist_test.rb
55
+ test/unit/chart_test.rb
56
+ test/unit/tag_test.rb
57
+ test/unit/track_test.rb
58
+ test/unit/user_test.rb
@@ -0,0 +1,71 @@
1
+ =Scrobbler
2
+
3
+ Scrobbler is a wrapper for the audioscrobbler web services (http://www.audioscrobbler.net/data/webservices/).
4
+
5
+ Below is just a sampling of how easy this lib is to use.
6
+
7
+ == Users
8
+
9
+ user = Scrobbler::User.new('jnunemaker')
10
+
11
+ puts "#{user.username}'s Recent Tracks"
12
+ puts "=" * (user.username.length + 16)
13
+ user.recent_tracks.each { |t| puts t.name }
14
+
15
+ puts
16
+ puts
17
+
18
+ puts "#{user.username}'s Top Tracks"
19
+ puts "=" * (user.username.length + 13)
20
+ user.top_tracks.each { |t| puts "(#{t.playcount}) #{t.name}" }
21
+
22
+ == Albums
23
+
24
+ album = Scrobbler::Album.new('Carrie Underwood', 'Some Hearts', :include_info => true)
25
+
26
+ puts "Album: #{album.name}"
27
+ puts "Artist: #{album.artist}"
28
+ puts "Reach: #{album.reach}"
29
+ puts "URL: #{album.url}"
30
+ puts "Release Date: #{album.release_date.strftime('%m/%d/%Y')}"
31
+
32
+ puts
33
+ puts
34
+
35
+ puts "Tracks"
36
+ longest_track_name = album.tracks.collect(&:name).sort { |x, y| y.length <=> x.length }.first.length
37
+ puts "=" * longest_track_name
38
+ album.tracks.each { |t| puts t.name }
39
+
40
+ ==Artists
41
+
42
+ artist = Scrobbler::Artist.new('Carrie Underwood')
43
+
44
+ puts 'Top Tracks'
45
+ puts "=" * 10
46
+ artist.top_tracks.each { |t| puts "(#{t.reach}) #{t.name}" }
47
+
48
+ puts
49
+
50
+ puts 'Similar Artists'
51
+ puts "=" * 15
52
+ artist.similar.each { |a| puts "(#{a.match}%) #{a.name}" }
53
+
54
+ ==Tags
55
+
56
+ tag = Scrobbler::Tag.new('country')
57
+
58
+ puts 'Top Albums'
59
+ tag.top_albums.each { |a| puts "(#{a.count}) #{a.name} by #{a.artist}" }
60
+
61
+ puts
62
+
63
+ puts 'Top Tracks'
64
+ tag.top_tracks.each { |t| puts "(#{t.count}) #{t.name} by #{t.artist}" }
65
+
66
+ ==Tracks
67
+
68
+ track = Scrobbler::Track.new('Carrie Underwood', 'Before He Cheats')
69
+ puts 'Fans'
70
+ puts "=" * 4
71
+ track.fans.each { |u| puts "(#{u.weight}) #{u.username}" }
@@ -0,0 +1,89 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/clean'
4
+ require 'rake/testtask'
5
+ require 'rake/packagetask'
6
+ require 'rake/gempackagetask'
7
+ require 'rake/rdoctask'
8
+ require 'rake/contrib/rubyforgepublisher'
9
+ require 'fileutils'
10
+ require 'hoe'
11
+ include FileUtils
12
+ require File.join(File.dirname(__FILE__), 'lib', 'scrobbler', 'version')
13
+
14
+ AUTHOR = 'nunemaker' # can also be an array of Authors
15
+ EMAIL = "nunemaker@gmail.com"
16
+ DESCRIPTION = "wrapper for audioscrobbler (last.fm) web services"
17
+ GEM_NAME = 'scrobbler' # what ppl will type to install your gem
18
+ RUBYFORGE_PROJECT = 'scrobbler' # The unix name for your project
19
+ HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
20
+ DOWNLOAD_PATH = "http://rubyforge.org/projects/#{RUBYFORGE_PROJECT}"
21
+
22
+ NAME = "scrobbler"
23
+ REV = nil # UNCOMMENT IF REQUIRED: File.read(".svn/entries")[/committed-rev="(d+)"/, 1] rescue nil
24
+ VERS = Scrobbler::VERSION::STRING + (REV ? ".#{REV}" : "")
25
+ CLEAN.include ['**/.*.sw?', '*.gem', '.config', '**/.DS_Store']
26
+ RDOC_OPTS = ['--quiet', '--title', 'scrobbler documentation',
27
+ "--opname", "index.html",
28
+ "--line-numbers",
29
+ "--main", "README",
30
+ "--inline-source"]
31
+
32
+ class Hoe
33
+ def extra_deps
34
+ @extra_deps.reject { |x| Array(x).first == 'hoe' }
35
+ end
36
+ end
37
+
38
+ # Generate all the Rake tasks
39
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
40
+ hoe = Hoe.new(GEM_NAME, VERS) do |p|
41
+ p.author = AUTHOR
42
+ p.description = DESCRIPTION
43
+ p.email = EMAIL
44
+ p.summary = DESCRIPTION
45
+ p.url = HOMEPATH
46
+ p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
47
+ p.test_globs = ["test/**/test_*.rb"]
48
+ p.clean_globs = CLEAN #An array of file patterns to delete on clean.
49
+
50
+ # == Optional
51
+ p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
52
+ p.extra_deps = [['hpricot', '>=0.4.86'], ['activesupport', '>=1.4.2']] # An array of rubygem dependencies [name, version], e.g. [ ['active_support', '>= 1.3.1'] ]
53
+ #p.spec_extras = {} # A hash of extra values to set in the gemspec.
54
+ end
55
+
56
+
57
+ desc 'Generate website files'
58
+ task :website_generate do
59
+ Dir['website/**/*.txt'].each do |txt|
60
+ sh %{ ruby scripts/txt2html #{txt} > #{txt.gsub(/txt$/,'html')} }
61
+ end
62
+ end
63
+
64
+ desc 'Upload website files to rubyforge'
65
+ task :website_upload do
66
+ config = YAML.load(File.read(File.expand_path("~/.rubyforge/user-config.yml")))
67
+ host = "#{config["username"]}@rubyforge.org"
68
+ remote_dir = "/var/www/gforge-projects/#{RUBYFORGE_PROJECT}/"
69
+ # remote_dir = "/var/www/gforge-projects/#{RUBYFORGE_PROJECT}/#{GEM_NAME}"
70
+ local_dir = 'website'
71
+ sh %{rsync -av #{local_dir}/ #{host}:#{remote_dir}}
72
+ end
73
+
74
+ desc 'Generate and upload website files'
75
+ task :website => [:website_generate, :website_upload]
76
+
77
+ desc 'Release the website and new gem version'
78
+ task :deploy => [:check_version, :website, :release]
79
+
80
+ task :check_version do
81
+ unless ENV['VERSION']
82
+ puts 'Must pass a VERSION=x.y.z release version'
83
+ exit
84
+ end
85
+ unless ENV['VERSION'] == VERS
86
+ puts "Please update your version.rb to match the release version, currently #{VERS}"
87
+ exit
88
+ end
89
+ end
@@ -0,0 +1,18 @@
1
+ require 'rubygems'
2
+ require 'scrobbler'
3
+
4
+ album = Scrobbler::Album.new('Carrie Underwood', 'Some Hearts', :include_info => true)
5
+
6
+ puts "Album: #{album.name}"
7
+ puts "Artist: #{album.artist}"
8
+ puts "Reach: #{album.reach}"
9
+ puts "URL: #{album.url}"
10
+ puts "Release Date: #{album.release_date.strftime('%m/%d/%Y')}"
11
+
12
+ puts
13
+ puts
14
+
15
+ puts "Tracks"
16
+ longest_track_name = album.tracks.collect(&:name).sort { |x, y| y.length <=> x.length }.first.length
17
+ puts "=" * longest_track_name
18
+ album.tracks.each { |t| puts t.name }
@@ -0,0 +1,14 @@
1
+ require 'rubygems'
2
+ require 'scrobbler'
3
+
4
+ artist = Scrobbler::Artist.new('Carrie Underwood')
5
+
6
+ puts 'Top Tracks'
7
+ puts "=" * 10
8
+ artist.top_tracks.each { |t| puts "(#{t.reach}) #{t.name}" }
9
+
10
+ puts
11
+
12
+ puts 'Similar Artists'
13
+ puts "=" * 15
14
+ artist.similar.each { |a| puts "(#{a.match}%) #{a.name}" }
@@ -0,0 +1,12 @@
1
+ require 'rubygems'
2
+ require 'scrobbler'
3
+
4
+ tag = Scrobbler::Tag.new('country')
5
+
6
+ puts 'Top Albums'
7
+ tag.top_albums.each { |a| puts "(#{a.count}) #{a.name} by #{a.artist}" }
8
+
9
+ puts
10
+
11
+ puts 'Top Tracks'
12
+ tag.top_tracks.each { |t| puts "(#{t.count}) #{t.name} by #{t.artist}" }
@@ -0,0 +1,7 @@
1
+ require 'rubygems'
2
+ require 'scrobbler'
3
+
4
+ track = Scrobbler::Track.new('Carrie Underwood', 'Before He Cheats')
5
+ puts 'Fans'
6
+ puts "=" * 4
7
+ track.fans.each { |u| puts "(#{u.weight}) #{u.username}" }
@@ -0,0 +1,15 @@
1
+ require 'rubygems'
2
+ require 'scrobbler'
3
+
4
+ user = Scrobbler::User.new('jnunemaker')
5
+
6
+ puts "#{user.username}'s Recent Tracks"
7
+ puts "=" * (user.username.length + 16)
8
+ user.recent_tracks.each { |t| puts t.name }
9
+
10
+ puts
11
+ puts
12
+
13
+ puts "#{user.username}'s Top Tracks"
14
+ puts "=" * (user.username.length + 13)
15
+ user.top_tracks.each { |t| puts "(#{t.playcount}) #{t.name}" }
@@ -0,0 +1,13 @@
1
+ %w{cgi rubygems hpricot active_support}.each { |x| require x }
2
+
3
+ require 'scrobbler/base'
4
+
5
+ require 'scrobbler/album'
6
+ require 'scrobbler/artist'
7
+ require 'scrobbler/chart'
8
+ require 'scrobbler/user'
9
+ require 'scrobbler/tag'
10
+ require 'scrobbler/track'
11
+
12
+ require 'scrobbler/rest'
13
+ require 'scrobbler/version'
@@ -0,0 +1,143 @@
1
+ # Getting information about an album such as release date and the tracks on it is very easy.
2
+ #
3
+ # album = Scrobbler::Album.new('Carrie Underwood', 'Some Hearts', :include_info => true)
4
+ #
5
+ # puts "Album: #{album.name}"
6
+ # puts "Artist: #{album.artist}"
7
+ # puts "Reach: #{album.reach}"
8
+ # puts "URL: #{album.url}"
9
+ # puts "Release Date: #{album.release_date.strftime('%m/%d/%Y')}"
10
+ #
11
+ # puts
12
+ # puts
13
+ #
14
+ # puts "Tracks"
15
+ # longest_track_name = album.tracks.collect(&:name).sort { |x, y| y.length <=> x.length }.first.length
16
+ # puts "=" * longest_track_name
17
+ # album.tracks.each { |t| puts t.name }
18
+ #
19
+ # Would output:
20
+ #
21
+ # Album: Some Hearts
22
+ # Artist: Carrie Underwood
23
+ # Reach: 18729
24
+ # URL: http://www.last.fm/music/Carrie+Underwood/Some+Hearts
25
+ # Release Date: 11/15/2005
26
+ #
27
+ #
28
+ # Tracks
29
+ # ===============================
30
+ # Wasted
31
+ # Don't Forget to Remember Me
32
+ # Some Hearts
33
+ # Jesus, Take the Wheel
34
+ # The Night Before (Life Goes On)
35
+ # Lessons Learned
36
+ # Before He Cheats
37
+ # Starts With Goodbye
38
+ # I Just Can't Live a Lie
39
+ # We're Young and Beautiful
40
+ # That's Where It Is
41
+ # Whenever You Remember
42
+ # I Ain't in Checotah Anymore
43
+ # Inside Your Heaven
44
+ module Scrobbler
45
+ class Album < Base
46
+ attr_accessor :artist, :artist_mbid, :name, :mbid, :playcount, :rank, :url, :reach, :release_date
47
+ attr_accessor :image_large, :image_medium, :image_small
48
+ attr_writer :tracks
49
+
50
+ # needed on top albums for tag
51
+ attr_accessor :count, :streamable
52
+
53
+ # needed for weekly album charts
54
+ attr_accessor :chartposition
55
+
56
+ class << self
57
+ def find(artist, name, o={})
58
+ new(artist, name, o)
59
+ end
60
+
61
+ def new_from_xml(xml, doc=nil)
62
+ name = (xml).at(:name).inner_html if (xml).at(:name)
63
+ name = xml['name'] if name.nil? && xml['name']
64
+ artist = (xml).at(:artist)['name'] if (xml).at(:artist) && (xml).at(:artist)['name']
65
+ artist = (xml).at(:artist).inner_html if artist.nil? && (xml).at(:artist)
66
+ artist = doc.root['artist'] if artist.nil? && doc.root['artist']
67
+ a = Album.new(artist, name)
68
+ a.artist_mbid = (xml).at(:artist)['mbid'] if (xml).at(:artist) && (xml).at(:artist)['mbid']
69
+ a.artist_mbid = (xml).at(:artist).at(:mbid).inner_html if a.artist_mbid.nil? && (xml).at(:artist) && (xml).at(:artist).at(:mbid)
70
+ a.mbid = (xml).at(:mbid).inner_html if (xml).at(:mbid)
71
+ a.playcount = (xml).at(:playcount).inner_html if (xml).at(:playcount)
72
+ a.chartposition = (xml).at(:chartposition).inner_html if (xml).at(:chartposition)
73
+ a.rank = (xml).at(:rank).inner_html if (xml).at(:rank)
74
+ a.url = (xml/:url).last.inner_html if (xml/:url).size > 1
75
+ a.url = (xml).at(:url).inner_html if a.url.nil? && (xml).at(:url)
76
+ a.reach = (xml).at(:reach).inner_html if (xml).at(:reach)
77
+ a.image_large = (xml).at(:image).at(:large).inner_html if (xml).at(:image) && (xml).at(:image).at(:large)
78
+ a.image_medium = (xml).at(:image).at(:medium).inner_html if (xml).at(:image) && (xml).at(:image).at(:medium)
79
+ a.image_small = (xml).at(:image).at(:small).inner_html if (xml).at(:image) && (xml).at(:image).at(:small)
80
+
81
+ # coverart element used on top albums for tag
82
+ a.image_large = (xml).at(:coverart).at(:large).inner_html if a.image_large.nil? && (xml).at(:coverart) && (xml).at(:coverart).at(:large)
83
+ a.image_medium = (xml).at(:coverart).at(:medium).inner_html if a.image_medium.nil? && (xml).at(:coverart) && (xml).at(:coverart).at(:medium)
84
+ a.image_small = (xml).at(:coverart).at(:small).inner_html if a.image_small.nil? && (xml).at(:coverart) && (xml).at(:coverart).at(:small)
85
+
86
+ # needed on top albums for tag
87
+ a.count = xml['count'] if xml['count']
88
+ a.streamable = xml['streamable'] if xml['streamable']
89
+ a
90
+ end
91
+ end
92
+
93
+ def initialize(artist, name, o={})
94
+ raise ArgumentError, "Artist is required" if artist.blank?
95
+ raise ArgumentError, "Name is required" if name.blank?
96
+ @artist = artist
97
+ @name = name
98
+ options = {:include_info => false}.merge(o)
99
+ load_info() if options[:include_info]
100
+ end
101
+
102
+ def api_path
103
+ "/#{API_VERSION}/album/#{CGI::escape(artist)}/#{CGI::escape(name)}"
104
+ end
105
+
106
+ def load_info
107
+ doc = self.class.fetch_and_parse("#{api_path}/info.xml")
108
+ @reach = (doc).at(:reach).inner_html
109
+ @url = (doc).at(:url).inner_html
110
+ @release_date = Time.parse((doc).at(:releasedate).inner_html.strip)
111
+ @image_large = (doc).at(:coverart).at(:large).inner_html
112
+ @image_medium = (doc).at(:coverart).at(:medium).inner_html
113
+ @image_small = (doc).at(:coverart).at(:small).inner_html
114
+ @mbid = (doc).at(:mbid).inner_html
115
+ @tracks = (doc/:track).inject([]) do |tracks, track|
116
+ t = Track.new(artist, track['title'])
117
+ t.artist_mbid = artist_mbid
118
+ t.album = name
119
+ t.album_mbid = mbid
120
+ t.url = (track).at(:url).inner_html
121
+ t.reach = (track).at(:reach).inner_html
122
+ tracks << t
123
+ tracks
124
+ end
125
+ end
126
+
127
+ def tracks
128
+ load_info if @tracks.nil?
129
+ @tracks
130
+ end
131
+
132
+ def image(which=:small)
133
+ which = which.to_s
134
+ raise ArgumentError unless ['small', 'medium', 'large'].include?(which)
135
+ img_url = instance_variable_get("@image_#{which}")
136
+ if img_url.nil?
137
+ load_info
138
+ img_url = instance_variable_get("@image_#{which}")
139
+ end
140
+ img_url
141
+ end
142
+ end
143
+ end