echonest 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. data/LICENSE +20 -0
  2. data/README.rdoc +7 -0
  3. data/Rakefile +56 -0
  4. data/VERSION.yml +4 -0
  5. data/examples/artist_audio.rb +33 -0
  6. data/generators/echonest_acceptance_test/USAGE +5 -0
  7. data/generators/echonest_acceptance_test/echonest_acceptance_test_generator.rb +50 -0
  8. data/generators/echonest_acceptance_test/templates/feature.erb +8 -0
  9. data/generators/echonest_model/USAGE +5 -0
  10. data/generators/echonest_model/echonest_model_generator.rb +52 -0
  11. data/generators/echonest_model/templates/doc.rb.erb +12 -0
  12. data/generators/echonest_model/templates/result.rb.erb +12 -0
  13. data/generators/echonest_model/templates/results.rb.erb +15 -0
  14. data/generators/echonest_resource/USAGE +5 -0
  15. data/generators/echonest_resource/echonest_resource_generator.rb +50 -0
  16. data/generators/echonest_unit_test/USAGE +5 -0
  17. data/generators/echonest_unit_test/echonest_unit_test_generator.rb +50 -0
  18. data/generators/echonest_unit_test/templates/unit_test.rb.erb +44 -0
  19. data/lib/echonest.rb +56 -0
  20. data/lib/echonest/api_request.rb +26 -0
  21. data/lib/echonest/artist.rb +74 -0
  22. data/lib/echonest/paged_result.rb +33 -0
  23. data/lib/echonest/xml/artist_doc.rb +23 -0
  24. data/lib/echonest/xml/artist_search_results.rb +14 -0
  25. data/lib/echonest/xml/audio_doc.rb +20 -0
  26. data/lib/echonest/xml/audio_result.rb +13 -0
  27. data/lib/echonest/xml/audio_results.rb +16 -0
  28. data/lib/echonest/xml/blogs_doc.rb +15 -0
  29. data/lib/echonest/xml/blogs_result.rb +14 -0
  30. data/lib/echonest/xml/blogs_results.rb +18 -0
  31. data/lib/echonest/xml/familiarity_result.rb +12 -0
  32. data/lib/echonest/xml/hotttnesss_result.rb +12 -0
  33. data/lib/echonest/xml/news_doc.rb +15 -0
  34. data/lib/echonest/xml/news_result.rb +14 -0
  35. data/lib/echonest/xml/news_results.rb +16 -0
  36. data/lib/echonest/xml/profile_result.rb +12 -0
  37. data/lib/echonest/xml/reviews_doc.rb +16 -0
  38. data/lib/echonest/xml/reviews_result.rb +15 -0
  39. data/lib/echonest/xml/reviews_results.rb +17 -0
  40. data/lib/echonest/xml/similar_doc.rb +15 -0
  41. data/lib/echonest/xml/similar_result.rb +14 -0
  42. data/lib/echonest/xml/similar_results.rb +16 -0
  43. data/lib/echonest/xml/urls_result.rb +14 -0
  44. data/lib/echonest/xml/video_doc.rb +16 -0
  45. data/lib/echonest/xml/video_result.rb +14 -0
  46. data/lib/echonest/xml/video_results.rb +17 -0
  47. data/spec/echonest/api_request_spec.rb +38 -0
  48. data/spec/echonest/paged_result_spec.rb +66 -0
  49. data/spec/echonest/xml/artist_search_results_spec.rb +25 -0
  50. data/spec/echonest/xml/audio_result_spec.rb +49 -0
  51. data/spec/echonest/xml/blogs_result_spec.rb +48 -0
  52. data/spec/echonest/xml/familiarity_result_spec.rb +33 -0
  53. data/spec/echonest/xml/hotttness_result_spec.rb +31 -0
  54. data/spec/echonest/xml/news_result_spec.rb +49 -0
  55. data/spec/echonest/xml/profile_result_spec.rb +26 -0
  56. data/spec/echonest/xml/refactor.rb +12 -0
  57. data/spec/echonest/xml/reviews_result_spec.rb +49 -0
  58. data/spec/echonest/xml/similar_result_spec.rb +35 -0
  59. data/spec/echonest/xml/urls_result_spec.rb +38 -0
  60. data/spec/echonest/xml/video_result_spec.rb +48 -0
  61. data/spec/fixtures/audio/wavves.xml +2 -0
  62. data/spec/fixtures/blog/radiohead.xml +32 -0
  63. data/spec/fixtures/familiarity/radiohead.xml +17 -0
  64. data/spec/fixtures/hotttnesss/radiohead.xml +17 -0
  65. data/spec/fixtures/news/radiohead.xml +32 -0
  66. data/spec/fixtures/profile/radiohead.xml +16 -0
  67. data/spec/fixtures/reviews/radiohead.xml +40 -0
  68. data/spec/fixtures/search_artists/wavves.xml +2 -0
  69. data/spec/fixtures/similar/radiohead.xml +31 -0
  70. data/spec/fixtures/urls/radiohead.xml +21 -0
  71. data/spec/fixtures/video/radiohead.xml +32 -0
  72. data/spec/spec_helper.rb +15 -0
  73. data/test/test_echonest_acceptance_test_generator.rb +52 -0
  74. data/test/test_echonest_model_generator.rb +47 -0
  75. data/test/test_echonest_resource_generator.rb +45 -0
  76. data/test/test_echonest_unit_test_generator.rb +35 -0
  77. data/test/test_generator_helper.rb +29 -0
  78. metadata +164 -0
@@ -0,0 +1,56 @@
1
+
2
+ require 'happymapper'
3
+ require 'open-uri'
4
+ require 'activesupport'
5
+ require 'delegate'
6
+
7
+ module EchoNest
8
+ def self.api_key=(api_key)
9
+ @api_key = api_key
10
+ end
11
+
12
+ def self.api_key
13
+ @api_key
14
+ end
15
+
16
+ end
17
+
18
+ require "echonest/api_request.rb"
19
+ require "echonest/paged_result.rb"
20
+
21
+ require "echonest/artist.rb"
22
+ require "echonest/xml/artist_doc.rb"
23
+
24
+ require "echonest/xml/artist_search_results.rb"
25
+
26
+ require "echonest/xml/audio_doc.rb"
27
+ require "echonest/xml/audio_results.rb"
28
+ require "echonest/xml/audio_result.rb"
29
+
30
+ require "echonest/xml/blogs_doc.rb"
31
+ require "echonest/xml/blogs_results.rb"
32
+ require "echonest/xml/blogs_result.rb"
33
+
34
+ require "echonest/xml/familiarity_result.rb"
35
+
36
+ require "echonest/xml/hotttnesss_result.rb"
37
+
38
+ require "echonest/xml/news_doc.rb"
39
+ require "echonest/xml/news_results.rb"
40
+ require "echonest/xml/news_result.rb"
41
+
42
+ require "echonest/xml/profile_result.rb"
43
+
44
+ require "echonest/xml/reviews_doc.rb"
45
+ require "echonest/xml/reviews_results.rb"
46
+ require "echonest/xml/reviews_result.rb"
47
+
48
+ require "echonest/xml/similar_doc.rb"
49
+ require "echonest/xml/similar_results.rb"
50
+ require "echonest/xml/similar_result.rb"
51
+
52
+ require "echonest/xml/urls_result.rb"
53
+
54
+ require "echonest/xml/video_doc.rb"
55
+ require "echonest/xml/video_results.rb"
56
+ require "echonest/xml/video_result.rb"
@@ -0,0 +1,26 @@
1
+
2
+ module EchoNest
3
+ class ApiRequest
4
+
5
+ def initialize(resource, options)
6
+ @options = {:version =>3, :api_key => EchoNest.api_key}.merge(options)
7
+ @resource = resource
8
+ end
9
+
10
+ def uri
11
+ "http://developer.echonest.com/api/#{@resource}?#{query_string(@options)}"
12
+ end
13
+
14
+ def fetch
15
+ open(uri).read
16
+ end
17
+
18
+ private
19
+
20
+ def query_string(options)
21
+ options.keys.map { |key| "#{key.to_s}=#{URI.encode(options[key].to_s)}" }.join('&')
22
+ end
23
+
24
+ end
25
+
26
+ end
@@ -0,0 +1,74 @@
1
+
2
+ module EchoNest
3
+ class Artist
4
+ attr_accessor :id
5
+
6
+ def initialize(id=nil)
7
+ @id = id if id
8
+ end
9
+
10
+ def self.service(name, options = {})
11
+
12
+ define_method "get_#{name.to_s}" do |*args|
13
+ options = args[0] if args.length == 1
14
+ options = {:id => id}.merge(options)
15
+ request = ApiRequest.new("get_#{name.to_s}", options)
16
+ "Xml::#{name.to_s.titleize}Result".constantize.parse request.fetch
17
+ end
18
+
19
+ if !options[:singular]
20
+ define_method name do
21
+ return instance_variable_get("@#{name.to_s}") if instance_variable_get("@#{name.to_s}")
22
+ result = self.send("get_#{name.to_s}")
23
+ pager = Proc.new { |start, rows|
24
+ self.send("get_#{name.to_s}", :start => start, :rows => rows).results
25
+ }
26
+ page = PagedResult.new result.results, pager
27
+ instance_variable_set("@#{name.to_s}", page)
28
+ end
29
+ else
30
+ if !options[:provides]
31
+ define_method name do
32
+ return instance_variable_get("@#{name.to_s}") if instance_variable_get("@#{name.to_s}")
33
+ result = self.send("get_#{name.to_s}")
34
+ instance_variable_set("@#{name.to_s}", result.artist.send(name))
35
+ end
36
+ else
37
+
38
+ define_method name do
39
+ return instance_variable_get("@#{name.to_s}") if instance_variable_get("@#{name.to_s}")
40
+ result = self.send("get_#{name.to_s}")
41
+ instance_variable_set("@#{name.to_s}", result.artist)
42
+ end
43
+
44
+ options[:provides].each do |prop|
45
+ define_method prop do
46
+ return instance_variable_get("@#{prop.to_s}") if instance_variable_get("@#{prop.to_s}")
47
+ instance_variable_set("@#{prop.to_s}", self.send(name).send(prop))
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+
54
+ def self.find(query, options={})
55
+ options = {:query => query}.merge(options)
56
+ request = ApiRequest.new("search_artists", options)
57
+ results = Xml::ArtistSearchResults.parse(request.fetch)
58
+ results.artists
59
+ end
60
+
61
+ service :audio
62
+ service :blogs
63
+ service :familiarity, :singular => true
64
+ service :hotttnesss, :singular => true
65
+ service :news
66
+ service :profile, :singular => true, :provides => [:id, :name, :foreign_id]
67
+ service :reviews
68
+ service :similar
69
+ service :urls, :singular => true, :provides => [:mb_url, :official_url, :myspace_url, :wikipedia_url, :amazon_url, :itunes_url]
70
+ service :video
71
+
72
+
73
+ end
74
+ end
@@ -0,0 +1,33 @@
1
+
2
+
3
+
4
+ module EchoNest
5
+ class PagedResult < DelegateClass(Array)
6
+
7
+ def initialize(results, block, options={})
8
+ @results = results
9
+ @update = block
10
+ @page_name = options[:page] || :docs
11
+ @available = @results.send(@page_name)
12
+ super(@available)
13
+ end
14
+
15
+ def found
16
+ @results.found
17
+ end
18
+
19
+ def next_page
20
+ results = @update.call @available.length, 15
21
+ @available += results.send(@page_name)
22
+ self.__setobj__(@available)
23
+ end
24
+
25
+ def [](i)
26
+ return @available[i] if @available[i]
27
+ next_page
28
+ @available[i]
29
+ end
30
+
31
+
32
+ end
33
+ end
@@ -0,0 +1,23 @@
1
+
2
+ module EchoNest
3
+ module Xml
4
+ class ArtistDoc
5
+ include HappyMapper
6
+
7
+ tag :artist
8
+
9
+ element :name, String
10
+ element :id, String
11
+ element :familiarity, Float
12
+ element :hotttnesss, Float
13
+ element :foreign_id, String
14
+
15
+ element :mb_url, String
16
+ element :official_url, String
17
+ element :myspace_url, String
18
+ element :wikipedia_url, String
19
+ element :amazon_url, String
20
+ element :itunes_url, String
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,14 @@
1
+
2
+ module EchoNest
3
+ module Xml
4
+ class ArtistSearchResults
5
+ include HappyMapper
6
+
7
+ tag :response
8
+
9
+ # has_one :status, RequestStatus
10
+ # has_one :query, RequestQuery
11
+ has_many :artists, ArtistDoc
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,20 @@
1
+
2
+ module EchoNest
3
+ module Xml
4
+ class AudioDoc
5
+ include HappyMapper
6
+
7
+ tag :doc
8
+
9
+ element :artist_id, String
10
+ element :foreign_artist_id, String
11
+ element :artist, String
12
+ element :release, String
13
+ element :title, String
14
+ element :url, String
15
+ element :link, String
16
+ element :date, String
17
+ element :length, String
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,13 @@
1
+
2
+ module EchoNest
3
+ module Xml
4
+ class AudioResult
5
+ include HappyMapper
6
+
7
+ tag :response
8
+
9
+ has_one :artist, ArtistDoc
10
+ has_one :results, AudioResults
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,16 @@
1
+
2
+ module EchoNest
3
+ module Xml
4
+ class AudioResults
5
+ include HappyMapper
6
+
7
+ tag :results
8
+
9
+ attribute :found, String
10
+ attribute :shown, String
11
+ attribute :start, String
12
+
13
+ has_many :docs, AudioDoc
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,15 @@
1
+
2
+ module EchoNest
3
+ module Xml
4
+ class BlogsDoc
5
+ include HappyMapper
6
+
7
+ tag :doc
8
+
9
+ element :name, String
10
+ element :url, String
11
+ element :summary, String
12
+ element :date_found, String
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,14 @@
1
+
2
+ module EchoNest
3
+ module Xml
4
+ class BlogsResult
5
+ include HappyMapper
6
+
7
+ tag :response
8
+
9
+ has_one :artist, ArtistDoc
10
+ has_one :results, BlogsResults
11
+
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,18 @@
1
+
2
+ module EchoNest
3
+ module Xml
4
+ class BlogsResults
5
+ include HappyMapper
6
+
7
+ tag :results
8
+
9
+ attribute :found, String
10
+ attribute :shown, String
11
+ attribute :start, String
12
+
13
+ has_many :docs, BlogsDoc
14
+
15
+ end
16
+ end
17
+ end
18
+
@@ -0,0 +1,12 @@
1
+
2
+ module EchoNest
3
+ module Xml
4
+ class FamiliarityResult
5
+ include HappyMapper
6
+
7
+ tag :response
8
+
9
+ has_one :artist, ArtistDoc
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+
2
+ module EchoNest
3
+ module Xml
4
+ class HotttnesssResult
5
+ include HappyMapper
6
+
7
+ tag :response
8
+
9
+ has_one :artist, ArtistDoc
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,15 @@
1
+
2
+ module EchoNest
3
+ module Xml
4
+ class NewsDoc
5
+ include HappyMapper
6
+
7
+ tag :doc
8
+
9
+ element :name, String
10
+ element :url, String
11
+ element :summary, String
12
+ element :date_found, String
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,14 @@
1
+
2
+ module EchoNest
3
+ module Xml
4
+ class NewsResult
5
+ include HappyMapper
6
+
7
+ tag :response
8
+
9
+ has_one :artist, ArtistDoc
10
+ has_one :results, NewsResults
11
+
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,16 @@
1
+
2
+ module EchoNest
3
+ module Xml
4
+ class NewsResults
5
+ include HappyMapper
6
+
7
+ tag :results
8
+
9
+ attribute :found, String
10
+ attribute :shown, String
11
+ attribute :start, String
12
+
13
+ has_many :docs, NewsDoc
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,12 @@
1
+
2
+ module EchoNest
3
+ module Xml
4
+ class ProfileResult
5
+ include HappyMapper
6
+
7
+ tag :response
8
+
9
+ has_one :artist, ArtistDoc
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,16 @@
1
+
2
+ module EchoNest
3
+ module Xml
4
+ class ReviewsDoc
5
+ include HappyMapper
6
+
7
+ tag :doc
8
+
9
+ element :name, String
10
+ element :review_text, String
11
+ element :url, String
12
+ element :summary, String
13
+ element :date_found, String
14
+ end
15
+ end
16
+ end