sundawg_music_rec 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/Manifest ADDED
@@ -0,0 +1,16 @@
1
+ Manifest
2
+ README
3
+ Rakefile
4
+ lib/artist.rb
5
+ lib/base_entity.rb
6
+ lib/last_fm_client.rb
7
+ lib/track.rb
8
+ lib/util.rb
9
+ lib/yahoo_music_client.rb
10
+ test/files/last_fm/get_similar_artists.xml
11
+ test/files/last_fm/get_similar_tracks.xml
12
+ test/files/yahoo_music/artist_search.xml
13
+ test/files/yahoo_music/artist_similar.xml
14
+ test/last_fm_client_test.rb
15
+ test/test_helper.rb
16
+ test/yahoo_music_client_test.rb
data/README ADDED
@@ -0,0 +1,60 @@
1
+ ABOUT
2
+ -----
3
+ This Ruby gem wraps small RESTful clients to hit popular music APIs to find recommended music. Current clients include last.fm and Yahoo! Music.
4
+
5
+ http://www.last.fm/api
6
+ http://developer.yahoo.com/music/
7
+
8
+ TEST
9
+ ----
10
+ Tests can be run by running:
11
+
12
+ rake test
13
+
14
+ To run actual integration tests against RESTful services, you will need to provide an API key for last.fm and Yahoo! Music.
15
+
16
+ SAMPLE USAGE
17
+ ------------
18
+ To find similar songs via last.fm:
19
+
20
+ last_fm_client = SunDawg::LastFmClient.new
21
+ last_fm_client.api_key = "abcdefg" # YOUR KEY
22
+ tracks = last_fm_client.get_similar_tracks("Creep", "Radiohead")
23
+ tracks.each { |t|
24
+ puts "TRACK [#{t}]"
25
+ }
26
+
27
+ To find similar artists via last.fm:
28
+
29
+ artists = last_fm_client.get_similar_artists("Bob Dylan")
30
+
31
+ To find similar artists via Yahoo Music!:
32
+ yahoo_music_client = SunDawg::YahooMusicClient.new
33
+ yahoo_music_client.app_id = "abcdefg" # YOUR KEY
34
+ artists = yahoo_music_client.get_similar_artists("The Killers")
35
+
36
+ Note: The Yahoo! Music API requires that two RESTful calls, one to search for the artist by name to receive the artist ID, then a second call to find similar artists. The get_similar_artists call will implicitly take the first result from the artist search service when finding similar artists. For more granularity, the following methods are supported:
37
+
38
+ get_artists(name)
39
+ get_similar_artists_by_id(id, options)
40
+
41
+ GEM INSTALL
42
+ -----------
43
+ This gem is hosted gemcutter.org. To install the gem, you should install gemcutter as so:
44
+
45
+ sudo gem install gemcutter
46
+ gem tumble
47
+
48
+ This will add gemcutter to your gem repository for downloading the country_codes gem.
49
+
50
+ RAILS INSTALL
51
+ -------------
52
+ config.gem 'sundawg_music_rec', :lib => 'last_fm_client'
53
+ config.gem 'sundawg_music_rec', :lib => 'yahoo_music_client'
54
+
55
+ TO DO
56
+ -----
57
+ - Integrate more recommendation engines.
58
+ - Build a meta-client that calls all API clients.
59
+ - Code improvement.
60
+
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'echoe'
4
+
5
+ Echoe.new('sundawg_music_rec', '0.0.1') do |p|
6
+ p.description = "Generic API Client for Music Recommendations."
7
+ p.url = "http://github.com/SunDawg/music_rec"
8
+ p.author = "Christopher Sun"
9
+ p.email = "christopher.sun@gmail.com"
10
+ p.ignore_pattern = ["tmp/*", "script/*"]
11
+ p.development_dependencies = ['mocha']
12
+ end
data/lib/artist.rb ADDED
@@ -0,0 +1,5 @@
1
+ require 'base_entity'
2
+ module SunDawg
3
+ class Artist < SunDawg::BaseEntity
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ module SunDawg
2
+ class BaseEntity
3
+ attr_accessor :name, :match, :mbid, :yahoo_id
4
+ end
5
+ end
@@ -0,0 +1,45 @@
1
+ require 'rexml/document'
2
+ require 'artist'
3
+ require 'track'
4
+ require 'util'
5
+
6
+ module SunDawg
7
+ class LastFmClient
8
+ attr_accessor :service_host, :api_key
9
+
10
+ def initialize
11
+ @service_host = "http://ws.audioscrobbler.com"
12
+ end
13
+
14
+ def get_similar_tracks(name, artist)
15
+ endpoint = "/2.0/" + SunDawg::Util::build_query_string({"method" => "track.getsimilar", "artist" => artist, "track" => name, "api_key" => @api_key})
16
+ xml = SunDawg::Util.do_http_get(service_host, endpoint)
17
+ doc = REXML::Document.new(xml)
18
+ tracks = []
19
+ doc.elements.each("/lfm/similartracks/track") { |e|
20
+ tracks << parse_element(SunDawg::Track.new, e)
21
+ tracks.last.artist = parse_element(SunDawg::Artist.new, e.elements["artist"])
22
+ }
23
+ tracks
24
+ end
25
+
26
+ def get_similar_artists(name, limit = 20)
27
+ xml = SunDawg::Util.do_http_get(service_host, "/2.0/" + SunDawg::Util::build_query_string({"method" => "artist.getsimilar", "artist" => name, "api_key" => @api_key}))
28
+ doc = REXML::Document.new(xml)
29
+ artists = []
30
+ doc.elements.each("/lfm/similarartists/artist") { |e|
31
+ artists << parse_element(SunDawg::Artist.new, e)
32
+ }
33
+ artists
34
+ end
35
+
36
+ protected
37
+
38
+ def parse_element(model, e)
39
+ model.name = e.elements["name"].text
40
+ model.match = e.elements["match"].text.to_f unless e.elements["match"].nil?
41
+ model.mbid = e.elements["mbid"].text
42
+ model
43
+ end
44
+ end
45
+ end
data/lib/track.rb ADDED
@@ -0,0 +1,7 @@
1
+ require 'base_entity'
2
+
3
+ module SunDawg
4
+ class Track < BaseEntity
5
+ attr_accessor :artist
6
+ end
7
+ end
data/lib/util.rb ADDED
@@ -0,0 +1,24 @@
1
+ require 'net/http'
2
+ require 'uri'
3
+ require 'cgi'
4
+
5
+ module SunDawg
6
+ module Util
7
+ def self.build_query_string(params)
8
+ s = "?"
9
+ params.each { |k, v|
10
+ s += "#{k}=#{CGI.escape(v)}&" unless v.nil?
11
+ }
12
+ s
13
+ end
14
+
15
+ def self.do_http_get(url, endpoint)
16
+ url = URI.parse("#{url}#{endpoint}")
17
+ req = Net::HTTP::Get.new(endpoint)
18
+ res = Net::HTTP.start(url.host, url.port) { |http|
19
+ http.request(req)
20
+ }
21
+ res.body
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,48 @@
1
+ require 'util'
2
+ require 'cgi'
3
+ require 'rexml/document'
4
+
5
+ module SunDawg
6
+ class YahooMusicClient
7
+ attr_accessor :app_id, :service_host
8
+
9
+ def initialize
10
+ @service_host = "http://us.music.yahooapis.com"
11
+ end
12
+
13
+ def get_artists(name)
14
+ endpoint = "/artist/v1/list/search/artist/#{CGI.escape(name)}"
15
+ endpoint += SunDawg::Util.build_query_string("appid" => app_id)
16
+ xml = SunDawg::Util.do_http_get(service_host, endpoint)
17
+ doc = REXML::Document.new(xml)
18
+ parse_artists(doc)
19
+ end
20
+
21
+ def get_similar_artists(name)
22
+ artists = get_artists(name)
23
+ get_similar_artists_by_id(artists.first.yahoo_id)
24
+ end
25
+
26
+ def get_similar_artists_by_id(yahoo_id, options = {})
27
+ endpoint = "/artist/v1/list/similar/#{yahoo_id}"
28
+ endpoint += SunDawg::Util.build_query_string(options.merge("appid" => app_id))
29
+ xml = SunDawg::Util.do_http_get(service_host, endpoint)
30
+ doc = REXML::Document.new(xml)
31
+ parse_artists(doc)
32
+ end
33
+
34
+ protected
35
+
36
+ def parse_artists(doc)
37
+ artists = []
38
+ doc.elements.each("/Artists/Artist") { |e|
39
+ artist = SunDawg::Artist.new
40
+ artist.yahoo_id = e.attributes["id"]
41
+ artist.name = e.attributes["name"]
42
+ artist.match = e.elements["ItemInfo/Relevancy"].attributes["index"].to_i unless e.elements["ItemInfo/Relevancy"].nil?
43
+ artists << artist
44
+ }
45
+ artists
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,34 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{sundawg_music_rec}
5
+ s.version = "0.0.1"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Christopher Sun"]
9
+ s.date = %q{2009-12-08}
10
+ s.description = %q{Generic API Client for Music Recommendations.}
11
+ s.email = %q{christopher.sun@gmail.com}
12
+ s.extra_rdoc_files = ["README", "lib/artist.rb", "lib/base_entity.rb", "lib/last_fm_client.rb", "lib/track.rb", "lib/util.rb", "lib/yahoo_music_client.rb"]
13
+ s.files = ["Manifest", "README", "Rakefile", "lib/artist.rb", "lib/base_entity.rb", "lib/last_fm_client.rb", "lib/track.rb", "lib/util.rb", "lib/yahoo_music_client.rb", "test/files/last_fm/get_similar_artists.xml", "test/files/last_fm/get_similar_tracks.xml", "test/files/yahoo_music/artist_search.xml", "test/files/yahoo_music/artist_similar.xml", "test/last_fm_client_test.rb", "test/test_helper.rb", "test/yahoo_music_client_test.rb", "sundawg_music_rec.gemspec"]
14
+ s.homepage = %q{http://github.com/SunDawg/music_rec}
15
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Sundawg_music_rec", "--main", "README"]
16
+ s.require_paths = ["lib"]
17
+ s.rubyforge_project = %q{sundawg_music_rec}
18
+ s.rubygems_version = %q{1.3.5}
19
+ s.summary = %q{Generic API Client for Music Recommendations.}
20
+ s.test_files = ["test/last_fm_client_test.rb", "test/test_helper.rb", "test/yahoo_music_client_test.rb"]
21
+
22
+ if s.respond_to? :specification_version then
23
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
24
+ s.specification_version = 3
25
+
26
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
27
+ s.add_development_dependency(%q<mocha>, [">= 0"])
28
+ else
29
+ s.add_dependency(%q<mocha>, [">= 0"])
30
+ end
31
+ else
32
+ s.add_dependency(%q<mocha>, [">= 0"])
33
+ end
34
+ end
@@ -0,0 +1,16 @@
1
+ <lfm>
2
+ <similarartists>
3
+ <artist>
4
+ <name>LOLZ SunDawg</name>
5
+ <mbid>3dc00dcb-6106-43d1-b48d-21d236f53983</mbid>
6
+ <match>48.39</match>
7
+ <url>www.last.fm/music/People+Under+the+Stairs</url>
8
+ <image size="small">http://userserve-ak.last.fm/serve/34/50908.jpg</image>
9
+ <image size="medium">http://userserve-ak.last.fm/serve/64/50908.jpg</image>
10
+ <image size="large">http://userserve-ak.last.fm/serve/126/50908.jpg</image>
11
+ <image size="extralarge">http://userserve-ak.last.fm/serve/252/50908.jpg</image>
12
+ <image size="mega">http://userserve-ak.last.fm/serve/500/50908/People+Under+the+Stairs.jpg</image>
13
+ <streamable>1</streamable>
14
+ </artist>
15
+ </similarartists>
16
+ </lfm>
@@ -0,0 +1,22 @@
1
+ <lfm>
2
+ <similartracks>
3
+ <track>
4
+ <name>House of SunDawg</name>
5
+ <playcount></playcount>
6
+ <mbid>abcdefg</mbid>
7
+ <match>0.22</match>
8
+ <url>http://www.last.fm/music/Mother+Tongue/_/That+Man</url>
9
+ <streamable fulltrack="1">1</streamable>
10
+ <duration>237000</duration>
11
+ <artist>
12
+ <name>SunDawg</name>
13
+ <mbid>6fefd5f2-477e-4225-bb8f-77c6befecd83</mbid>
14
+ <url>http://www.last.fm/music/Mother+Tongue</url>
15
+ </artist>
16
+ <image size="small">http://userserve-ak.last.fm/serve/34s/8711423.jpg</image>
17
+ <image size="medium">http://userserve-ak.last.fm/serve/64s/8711423.jpg</image>
18
+ <image size="large">http://userserve-ak.last.fm/serve/126/8711423.jpg</image>
19
+ <image size="extralarge">http://userserve-ak.last.fm/serve/300x300/8711423.jpg</image>
20
+ </track>
21
+ </similartracks>
22
+ </lfm>
@@ -0,0 +1,7 @@
1
+ <Artists start="1" count="23" total="23" errorCount="0">
2
+ <Artist id="123" rating="-1" name="The SunDawgs" catzillaID="0" hotzillaID="1800038606" trackCount="2887" website="http://www.madonna.com/" url="http://new.music.yahoo.com/madonna/" flags="124611">
3
+ <ItemInfo>
4
+ <Relevancy index="722"/>
5
+ </ItemInfo>
6
+ </Artist>
7
+ </Artists>
@@ -0,0 +1,7 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <Artists start="1" count="25" total="100" errorCount="0" >
3
+ <Artist id="294026" rating="-1" name="Anastacia" catzillaID="1927421443" hotzillaID="1804649855" trackCount="714" website="http://www.anastacia.com" url="http://new.music.yahoo.com/anastacia/" flags="124547">
4
+ </Artist>
5
+ <Artist id="254729" rating="-1" name="La Fred" catzillaID="1927036213" hotzillaID="1802474071" trackCount="366" website="" url="http://new.music.yahoo.com/union/" flags="57475">
6
+ </Artist>
7
+ </Artists>
@@ -0,0 +1,65 @@
1
+ require 'test_helper'
2
+ require 'last_fm_client'
3
+
4
+ class LastFmClientTest < Test::Unit::TestCase
5
+
6
+ INTEGRATION = false
7
+
8
+ include TestHelper
9
+
10
+ def setup
11
+ # TODO: Add Your Last.fm API-KEY
12
+ client.api_key = 'abcdef'
13
+ end
14
+
15
+ def test_get_similar_tracks
16
+ setup_http_get_mock(read_file('test/files/last_fm//get_similar_tracks.xml'))
17
+ tracks = client.get_similar_tracks("Creep", "Radiohead")
18
+ assert_equal tracks.size, 1
19
+ assert_equal tracks.first.name, "House of SunDawg"
20
+ assert_equal tracks.first.mbid, "abcdefg"
21
+ assert_equal tracks.first.match, 0.22
22
+ assert_equal tracks.first.artist.name, "SunDawg"
23
+ assert_equal tracks.first.artist.mbid, "6fefd5f2-477e-4225-bb8f-77c6befecd83"
24
+ end
25
+
26
+ def test_get_similar_artists
27
+ setup_http_get_mock(read_file('test/files/last_fm/get_similar_artists.xml'))
28
+ artists = client.get_similar_artists("Creep")
29
+ assert_equal artists.size, 1
30
+ assert_equal artists.first.name, "LOLZ SunDawg"
31
+ assert_equal artists.first.mbid, "3dc00dcb-6106-43d1-b48d-21d236f53983"
32
+ assert_equal artists.first.match, 48.39
33
+ end
34
+
35
+ def test_get_similar_tracks_integration
36
+ return if !INTEGRATION
37
+ tracks = client.get_similar_tracks("Creep", "Radiohead")
38
+ assert_not_nil tracks
39
+ tracks.each { |t|
40
+ assert_not_nil t.name
41
+ assert_not_nil t.match
42
+ assert_not_nil t.artist
43
+ assert_not_nil t.artist.name
44
+ }
45
+ end
46
+
47
+ def test_get_similar_artists_integration
48
+ return if !INTEGRATION
49
+ artists = client.get_similar_artists("A Tribe Called Quest")
50
+ assert_not_nil artists
51
+ artists.each { |a|
52
+ assert_not_nil a.name
53
+ assert_not_nil a.match
54
+ }
55
+ end
56
+
57
+ protected
58
+
59
+ def client
60
+ if @client.nil?
61
+ @client = SunDawg::LastFmClient.new
62
+ end
63
+ @client
64
+ end
65
+ end
@@ -0,0 +1,22 @@
1
+ require 'test/unit'
2
+ require 'rubygems'
3
+ require 'mocha'
4
+
5
+ module TestHelper
6
+ def setup_http_get_mock(xml)
7
+ SunDawg::Util.stubs(:do_http_get).returns(xml)
8
+ end
9
+
10
+ def read_file(name)
11
+ begin
12
+ file = File.new(name, "r")
13
+ content = ""
14
+ while (line = file.gets)
15
+ content += line
16
+ end
17
+ return content
18
+ ensure
19
+ file.close unless file.nil?
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,62 @@
1
+ require 'test_helper'
2
+ require 'yahoo_music_client'
3
+
4
+ class YahooMusicClientTest < Test::Unit::TestCase
5
+
6
+ include TestHelper
7
+
8
+ INTEGRATION = false
9
+
10
+ def setup
11
+ # TODO: Add Your Yahoo! Music APP-ID
12
+ client.app_id = 'ABCDEF'
13
+ end
14
+
15
+ def test_get_artists
16
+ setup_http_get_mock(read_file('test/files/yahoo_music/artist_search.xml'))
17
+ artists = client.get_similar_artists("The Killers")
18
+ assert_equal artists.size, 1
19
+ assert_equal artists.first.name, "The SunDawgs"
20
+ assert_equal artists.first.match, 722
21
+ assert_equal artists.first.yahoo_id, "123"
22
+ end
23
+
24
+ def test_get_similar_artists
25
+ setup_http_get_mock(read_file('test/files/yahoo_music/artist_similar.xml'))
26
+ artists = client.get_similar_artists("The Killers")
27
+ assert_equal artists.size, 2
28
+ assert_equal artists.first.name, "Anastacia"
29
+ assert_equal artists.first.yahoo_id, "294026"
30
+ assert_equal artists.last.name, "La Fred"
31
+ assert_equal artists.last.yahoo_id, "254729"
32
+ end
33
+
34
+ def test_get_similar_artists_integration
35
+ return if !INTEGRATION
36
+ artists = client.get_similar_artists("Bob Marley")
37
+ assert_not_nil artists
38
+ artists.each { |a|
39
+ assert_not_nil a.name
40
+ }
41
+ end
42
+
43
+ def test_get_artists_integration
44
+ return if !INTEGRATION
45
+ artists = client.get_artists("The Rolling Stones")
46
+ assert_not_nil artists
47
+ artists.each { |a|
48
+ assert_not_nil a.name
49
+ assert_not_nil a.yahoo_id
50
+ assert_not_nil a.match
51
+ }
52
+ end
53
+
54
+ protected
55
+
56
+ def client
57
+ if @client.nil?
58
+ @client = SunDawg::YahooMusicClient.new
59
+ end
60
+ @client
61
+ end
62
+ end
metadata ADDED
@@ -0,0 +1,93 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sundawg_music_rec
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Christopher Sun
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-12-08 00:00:00 -05:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: mocha
17
+ type: :development
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ description: Generic API Client for Music Recommendations.
26
+ email: christopher.sun@gmail.com
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - README
33
+ - lib/artist.rb
34
+ - lib/base_entity.rb
35
+ - lib/last_fm_client.rb
36
+ - lib/track.rb
37
+ - lib/util.rb
38
+ - lib/yahoo_music_client.rb
39
+ files:
40
+ - Manifest
41
+ - README
42
+ - Rakefile
43
+ - lib/artist.rb
44
+ - lib/base_entity.rb
45
+ - lib/last_fm_client.rb
46
+ - lib/track.rb
47
+ - lib/util.rb
48
+ - lib/yahoo_music_client.rb
49
+ - test/files/last_fm/get_similar_artists.xml
50
+ - test/files/last_fm/get_similar_tracks.xml
51
+ - test/files/yahoo_music/artist_search.xml
52
+ - test/files/yahoo_music/artist_similar.xml
53
+ - test/last_fm_client_test.rb
54
+ - test/test_helper.rb
55
+ - test/yahoo_music_client_test.rb
56
+ - sundawg_music_rec.gemspec
57
+ has_rdoc: true
58
+ homepage: http://github.com/SunDawg/music_rec
59
+ licenses: []
60
+
61
+ post_install_message:
62
+ rdoc_options:
63
+ - --line-numbers
64
+ - --inline-source
65
+ - --title
66
+ - Sundawg_music_rec
67
+ - --main
68
+ - README
69
+ require_paths:
70
+ - lib
71
+ required_ruby_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: "0"
76
+ version:
77
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: "1.2"
82
+ version:
83
+ requirements: []
84
+
85
+ rubyforge_project: sundawg_music_rec
86
+ rubygems_version: 1.3.5
87
+ signing_key:
88
+ specification_version: 3
89
+ summary: Generic API Client for Music Recommendations.
90
+ test_files:
91
+ - test/last_fm_client_test.rb
92
+ - test/test_helper.rb
93
+ - test/yahoo_music_client_test.rb