ruby-echonest 0.0.6 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|