ruby-echonest 0.0.6 → 0.1.1
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.
- data/README.rdoc +9 -5
- data/Rakefile +1 -0
- data/lib/echonest/analysis.rb +91 -0
- data/lib/echonest/api.rb +94 -148
- data/lib/echonest/element/bar.rb +1 -4
- data/lib/echonest/element/beat.rb +1 -4
- data/lib/echonest/element/section.rb +3 -2
- data/lib/echonest/element/segment.rb +2 -2
- data/lib/echonest/element/tatum.rb +1 -4
- data/lib/echonest/response.rb +10 -23
- data/lib/echonest/traditional_api_methods.rb +14 -0
- data/lib/echonest/version.rb +1 -1
- data/lib/echonest.rb +3 -2
- data/spec/analysis_spec.rb +98 -0
- data/spec/api_spec.rb +63 -177
- data/spec/fixtures/analysis.json +3 -0
- data/spec/fixtures/profile.json +1 -0
- data/spec/fixtures/profile_failure.json +1 -0
- data/spec/fixtures/profile_unknown.json +1 -0
- data/spec/response_spec.rb +6 -43
- data/spec/track_spec.rb +106 -0
- metadata +43 -27
- data/lib/echonest/element/value_with_confidence.rb +0 -10
- data/spec/fixtures/get_bars.xml +0 -2
- data/spec/fixtures/get_beats.xml +0 -2
- data/spec/fixtures/get_duration.xml +0 -2
- data/spec/fixtures/get_end_of_fade_in.xml +0 -2
- data/spec/fixtures/get_key.xml +0 -2
- data/spec/fixtures/get_loudness.xml +0 -2
- data/spec/fixtures/get_metadata.xml +0 -2
- data/spec/fixtures/get_mode.xml +0 -2
- data/spec/fixtures/get_sections.xml +0 -2
- data/spec/fixtures/get_segments.xml +0 -2
- data/spec/fixtures/get_start_of_fade_out.xml +0 -2
- data/spec/fixtures/get_tatums.xml +0 -2
- data/spec/fixtures/get_tempo.xml +0 -2
- data/spec/fixtures/get_time_signature.xml +0 -2
data/spec/api_spec.rb
CHANGED
@@ -7,213 +7,99 @@ include SpecHelper
|
|
7
7
|
|
8
8
|
describe Echonest::Api do
|
9
9
|
before do
|
10
|
-
@api = Echonest::Api.new('
|
11
|
-
end
|
12
|
-
|
13
|
-
it "should have version" do
|
14
|
-
Echonest::Api::VERSION.should eql('3')
|
10
|
+
@api = Echonest::Api.new('8TPE3VC60ODJTNTFE')
|
15
11
|
end
|
16
12
|
|
17
13
|
it "should build parameters" do
|
18
|
-
params = @api.build_params(:id => '
|
14
|
+
params = @api.build_params(:id => 'TRXXHTJ1294CD8F3B3')
|
19
15
|
params.keys.size.should eql(3)
|
20
|
-
params[:
|
21
|
-
params[:
|
22
|
-
params[:
|
23
|
-
end
|
24
|
-
|
25
|
-
it "should call api method" do
|
26
|
-
make_connection_stub(<<EOM)
|
27
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
28
|
-
<response version="3">
|
29
|
-
<status>
|
30
|
-
<code>0</code>
|
31
|
-
<message>Success</message>
|
32
|
-
</status>
|
33
|
-
<query>
|
34
|
-
<parameter name="api_key">5ZAOMB3BUR8QUN4PE</parameter>
|
35
|
-
<parameter name="id">music://id.echonest.com/~/AR/ARH6W4X1187B99274F</parameter>
|
36
|
-
</query>
|
37
|
-
<artist>
|
38
|
-
<name>Radiohead</name>
|
39
|
-
<id>music://id.echonest.com/~/AR/ARH6W4X1187B99274F</id>
|
40
|
-
<foreign_id>music://id.echonest.com/5ZAOMB3BUR8QUN4PE/AR/1</foreign_id>
|
41
|
-
<familiarity>0.96974159665</familiarity>
|
42
|
-
</artist>
|
43
|
-
</response>
|
44
|
-
EOM
|
45
|
-
|
46
|
-
response = @api.request(:get_bars, :id => 'music://id.echonest.com/~/AR/ARH6W4X1187B99274F')
|
47
|
-
response.success?.should be_true
|
48
|
-
end
|
49
|
-
|
50
|
-
it "should raise error when api method call was failed" do
|
51
|
-
make_connection_stub(<<EOM)
|
52
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
53
|
-
<response version="3">
|
54
|
-
<status>
|
55
|
-
<code>1</code>
|
56
|
-
<message>Invalid API key</message>
|
57
|
-
</status>
|
58
|
-
<query>
|
59
|
-
<parameter name="api_key">XXXXXX</parameter>
|
60
|
-
<parameter name="id">music://id.echonest.com/~/AR/ARH6W4X1187B99274F</parameter>
|
61
|
-
</query>
|
62
|
-
</response>
|
63
|
-
EOM
|
64
|
-
lambda {
|
65
|
-
@api.request(:get_bars, :id => 'music://id.echonest.com/~/AR/ARH6W4X1187B99274F')
|
66
|
-
}.should raise_error(Echonest::Api::Error, 'Invalid API key')
|
67
|
-
end
|
68
|
-
|
69
|
-
it "should raise error when unknown api method was called" do
|
70
|
-
lambda {
|
71
|
-
@api.get_xxx(:id => 'music://id.echonest.com/~/AR/ARH6W4X1187B99274F')
|
72
|
-
}.should raise_error(NoMethodError)
|
73
|
-
end
|
74
|
-
|
75
|
-
it "should get bars" do
|
76
|
-
make_connection_stub(open(fixture('get_bars.xml')).read)
|
77
|
-
|
78
|
-
bars = @api.get_bars(fixture('sample.mp3'))
|
79
|
-
|
80
|
-
bars.should be_an_instance_of(Array)
|
81
|
-
bars.size.should eql(80)
|
82
|
-
bars.first.start.should eql(0.45717)
|
83
|
-
bars.first.confidence.should eql(0.537)
|
84
|
-
end
|
85
|
-
|
86
|
-
it "should get beats" do
|
87
|
-
make_connection_stub(open(fixture('get_beats.xml')).read)
|
88
|
-
|
89
|
-
beats = @api.get_beats(fixture('sample.mp3'))
|
90
|
-
|
91
|
-
beats.should be_an_instance_of(Array)
|
92
|
-
beats.size.should eql(375)
|
93
|
-
beats.first.start.should eql(0.45717)
|
94
|
-
beats.first.confidence.should eql(0.823)
|
95
|
-
end
|
96
|
-
|
97
|
-
it "should get tempo" do
|
98
|
-
make_connection_stub(open(fixture('get_tempo.xml')).read)
|
99
|
-
|
100
|
-
tempo = @api.get_tempo(fixture('sample.mp3'))
|
101
|
-
|
102
|
-
tempo.should eql(120.163)
|
103
|
-
end
|
104
|
-
|
105
|
-
it "should get segments" do
|
106
|
-
make_connection_stub(open(fixture('get_segments.xml')).read)
|
107
|
-
|
108
|
-
segments = @api.get_segments(fixture('sample.mp3'))
|
109
|
-
|
110
|
-
segments.size.should eql(4)
|
111
|
-
|
112
|
-
segment = segments.first
|
113
|
-
|
114
|
-
segment.start.should eql(0.0)
|
115
|
-
segment.duration.should eql(0.421)
|
116
|
-
segment.loudness.time.should eql(0.0)
|
117
|
-
segment.loudness.value.should eql(-60.0)
|
118
|
-
segment.max_loudness.time.should eql(0.0)
|
119
|
-
segment.max_loudness.value.should eql(-60.0)
|
120
|
-
segment.pitches.size.should eql(12)
|
121
|
-
segment.pitches.first.should eql(0.542)
|
122
|
-
segment.timbre.size.should eql(12)
|
123
|
-
segment.timbre.first.should eql(0.0)
|
124
|
-
end
|
125
|
-
|
126
|
-
it "should get sections" do
|
127
|
-
make_connection_stub(open(fixture('get_sections.xml')).read)
|
128
|
-
|
129
|
-
sections = @api.get_sections(fixture('sample.mp3'))
|
130
|
-
|
131
|
-
sections.size.should eql(16)
|
132
|
-
|
133
|
-
section = sections.first
|
134
|
-
|
135
|
-
section.start.should eql(0.0)
|
136
|
-
section.duration.should eql(7.82647)
|
16
|
+
params[:api_key].should eql('8TPE3VC60ODJTNTFE')
|
17
|
+
params[:id].should eql('TRXXHTJ1294CD8F3B3')
|
18
|
+
params[:format].should eql('json')
|
137
19
|
end
|
138
20
|
|
139
|
-
it "should
|
140
|
-
|
21
|
+
it "should pass arguments to user agent" do
|
22
|
+
@api.user_agent.should_receive(:get_content).
|
23
|
+
with(
|
24
|
+
URI('http://developer.echonest.com/api/v4/xxx/yyy'),
|
25
|
+
{
|
26
|
+
:foo => 'bar',
|
27
|
+
:api_key => '8TPE3VC60ODJTNTFE',
|
28
|
+
:format => 'json'
|
29
|
+
}).and_return(open(fixture('profile.json')).read)
|
141
30
|
|
142
|
-
@api.
|
31
|
+
@api.request('xxx/yyy', :get, :foo => 'bar')
|
143
32
|
end
|
144
33
|
|
145
|
-
it "should
|
146
|
-
|
147
|
-
|
148
|
-
@api.get_end_of_fade_in(fixture('sample.mp3')).should eql(0.421)
|
149
|
-
end
|
34
|
+
it "should pass arguments including a file to user agent" do
|
35
|
+
file = open(fixture('sample.mp3'))
|
36
|
+
file.should_receive(:read).and_return('content')
|
150
37
|
|
151
|
-
|
152
|
-
|
38
|
+
@api.user_agent.should_receive(:post_content).
|
39
|
+
with(
|
40
|
+
URI('http://developer.echonest.com/api/v4/xxx/zzz?api_key=8TPE3VC60ODJTNTFE&bar=baz&format=json'),
|
41
|
+
'content',
|
42
|
+
{
|
43
|
+
'Content-Type' => 'application/octet-stream'
|
44
|
+
}).and_return(open(fixture('profile.json')).read)
|
153
45
|
|
154
|
-
|
155
|
-
|
156
|
-
key.confidence.should eql(1.0)
|
157
|
-
key.value.should eql(5)
|
46
|
+
@api.request('xxx/zzz', :post, { :bar => 'baz' }, file)
|
158
47
|
end
|
159
48
|
|
160
|
-
it "should
|
161
|
-
|
162
|
-
|
163
|
-
loudness = @api.get_loudness(fixture('sample.mp3'))
|
49
|
+
it "should call api method" do
|
50
|
+
content = open(fixture('profile.json')).read
|
164
51
|
|
165
|
-
|
52
|
+
make_connection_stub(content, :post)
|
53
|
+
response = @api.request('track/profile', :post, :id => 'TRXXHTJ1294CD8F3B3')
|
54
|
+
response.should be_success
|
55
|
+
response.body.status.version.should eql("4.2")
|
166
56
|
end
|
167
57
|
|
168
|
-
it "should
|
169
|
-
make_connection_stub(open(fixture('
|
170
|
-
|
171
|
-
metadata = @api.get_metadata(fixture('sample.mp3'))
|
58
|
+
it "should raise error when api method call was failed" do
|
59
|
+
make_connection_stub(open(fixture('profile_failure.json')).read, :post)
|
172
60
|
|
173
|
-
|
174
|
-
|
61
|
+
lambda {
|
62
|
+
@api.request('track/profile', :post, :id => 'TRXXHTJ1294CD8F3B3')
|
63
|
+
}.should raise_error(Echonest::Api::Error, 'api_key - Invalid key: "XXXXX" is not a valid, active api key')
|
175
64
|
end
|
176
65
|
|
177
|
-
it "should
|
178
|
-
|
179
|
-
|
180
|
-
mode = @api.get_mode(fixture('sample.mp3'))
|
66
|
+
it "should raise error when unknown api method was called" do
|
67
|
+
@api.user_agent.stub!('get_content').and_raise(HTTPClient::BadResponseError.new('error message'))
|
181
68
|
|
182
|
-
|
183
|
-
|
69
|
+
lambda {
|
70
|
+
@api.request('track/xxxx', :get, :id => 'TRXXHTJ1294CD8F3B3')
|
71
|
+
}.should raise_error(Echonest::Api::Error, 'track/xxxx: error message')
|
184
72
|
end
|
185
73
|
|
186
|
-
it "should
|
187
|
-
|
188
|
-
|
189
|
-
@api.get_start_of_fade_out(fixture('sample.mp3')).should eql(182.44499)
|
74
|
+
it "should make http request with agent name" do
|
75
|
+
@api.user_agent.agent_name.should eql('ruby-echonest/' + Echonest::VERSION)
|
190
76
|
end
|
191
77
|
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
tatums.size.should eql(757)
|
199
|
-
tatums.first.start.should eql(0.45717)
|
200
|
-
tatums.first.confidence.should eql(1.0)
|
78
|
+
describe '#track' do
|
79
|
+
it 'should return track methods' do
|
80
|
+
track = @api.track
|
81
|
+
track.class.should eql(Echonest::ApiMethods::Track)
|
82
|
+
track.instance_eval { @api }.should eql(@api)
|
83
|
+
end
|
201
84
|
end
|
202
85
|
|
203
|
-
it
|
204
|
-
|
86
|
+
it 'should have traditional API methods' do
|
87
|
+
filename = fixture('sample.mp3')
|
88
|
+
analysis = Echonest::Analysis.new(open(fixture('analysis.json')).read)
|
89
|
+
track = Echonest::ApiMethods::Track.new(@api)
|
205
90
|
|
206
|
-
time_signature
|
91
|
+
%w/tempo duration end_of_fade_in key loudness mode start_of_fade_out time_signature bars beats sections tatums segments/.
|
92
|
+
each do |method|
|
207
93
|
|
208
|
-
|
209
|
-
|
210
|
-
|
94
|
+
@api.should_receive(:track).and_return(track)
|
95
|
+
track.should_receive(:analysis).with(filename).and_return(analysis)
|
96
|
+
analysis.should_receive(method.to_sym)
|
211
97
|
|
212
|
-
|
213
|
-
|
98
|
+
@api.send('get_' + method, filename)
|
99
|
+
end
|
214
100
|
end
|
215
101
|
|
216
|
-
def make_connection_stub(
|
217
|
-
@api.user_agent.stub!(
|
102
|
+
def make_connection_stub(content, method)
|
103
|
+
@api.user_agent.stub!(method.to_s + '_content').and_return(content)
|
218
104
|
end
|
219
105
|
end
|