echonest 0.3.0

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.
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