Skip to content

@koyachi /echonest.rb
Created

Embed URL

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
#!/usr/bin/env ruby
# -*- coding: utf-8 -*-
require 'rubygems'
require 'uri'
require 'net/http'
require 'digest/md5'
require 'rexml/document'
require 'extlib'
require 'yaml'
class WebService; end
class WebService::EchoNest
def initialize(apikey)
@api_key = apikey
@base_url = 'http://developer.echonest.com'
@host = 'developer.echonest.com'
end
def upload(file)
file_data = File.read(file)
boundary = '----BOUNDARYBOUNDARY----'
data = <<EOF
--#{boundary}\r
Content-Disposition: form-data; name="api_key"\r
\r
#{@api_key}\r
--#{boundary}\r
Content-Disposition: form-data; name="version"\r
\r
3\r
--#{boundary}\r
Content-Disposition: form-data; name="wait"\r
\r
Y\r
--#{boundary}\r
Content-Disposition: form-data; name="file"; filename="#{file}"\r
Content-Type: application/octet-stream\r
\r
#{file_data}\r
--#{boundary}--\r
EOF
header ={
'Content-Length' => data.length.to_s,
'Content-Type' => "multipart/form-data; boundary=#{boundary}"
}
url = @base_url + '/api/upload'
uri = URI.parse(url)
response = Net::HTTP.start(uri.host, 80) {|http|
http.post(uri.path, data, header)
}
doc = REXML::Document.new response.body
result = {
'status' => {},
'query' => {},
'track' => {},
}
%w[code message].each do |m|
result['status'][m] = doc.elements['response'].elements['status'].elements[m].text
end
%w[api_key url file wait].each do |m|
elm = REXML::XPath.first(doc, "//parameter[@name=\"#{m}\"]")
result['query'][m] = elm.text if elm
end
%w[id md5].each do |m|
result['track'][m] = doc.elements['response'].elements['track'].attributes[m]
end
result
end
def get_beats(args)
p args
url = @base_url + '/api/get_beats?' +
['api_key=' + @api_key,
'version=3'].join('&')
if args[:id]
url += "&id=#{args[:id]}"
else
if args[:file]
md5 = Digest::MD5.hexdigest(File.open(args[:file], 'rb').read)
else
md5 = args[:md5]
end
url += "&md5=#{md5}"
end
response = Net::HTTP::get_response(URI.parse(url));
doc = REXML::Document.new response.body
result = Mash.new({
:status => Mash.new({}),
:query => Mash.new({}),
:beats => [],
})
%w[code message].each do |m|
result[:status][m] = doc.elements['response'].elements['status'].elements[m].text
end
# unknown md5
if result[:status][:code] == '5'
puts "unknown md5. uploading..."
upload args[:file]
get_beats :md5 => md5
else
%w[api_key id md5].each do |m|
elm = REXML::XPath.first(doc, "//parameter[@name=\"#{m}\"]")
result[:query][m] = elm.text if elm
end
doc.elements.each('response/analysis/beat') {|elm|
result[:beats].push(Mash.new({
:confidence => elm.attributes['confidence'],
:value => elm.text
}))
}
result
end
end
def get_tatums(args)
end
def get_bars(args)
end
def get_sections(args)
url = @base_url + '/api/get_sections?' +
['api_key=' + @api_key,
'version=3'].join('&')
if args[:id]
url += "&id=#{args[:id]}"
else
if args[:file]
md5 = Digest::MD5.hexdigest(File.open(args[:file], 'rb').read)
else
md5 = args[:md5]
end
url += "&md5=#{md5}"
end
response = Net::HTTP::get_response(URI.parse(url));
doc = REXML::Document.new response.body
result = Mash.new({
:status => Mash.new({}),
:query => Mash.new({}),
:sections => [],
})
%w[code message].each do |m|
result[:status][m] = doc.elements['response'].elements['status'].elements[m].text
end
# unknown md5
if result[:status][:code] == '5'
puts "unknown md5. uploading..."
upload args[:file]
get_sections :md5 => md5
else
%w[api_key id md5].each do |m|
elm = REXML::XPath.first(doc, "//parameter[@name=\"#{m}\"]")
result[:query][m] = elm.text if elm
end
doc.elements.each('response/analysis/section') {|elm|
result[:sections].push(Mash.new({
:start => elm.attributes['start'],
:duration => elm.attributes['duration'],
}))
}
result
end
end
def get_segments(args)
url = @base_url + '/api/get_segments?' +
['api_key=' + @api_key,
'version=3'].join('&')
if args[:id]
url += "&id=#{args[:id]}"
else
if args[:file]
md5 = Digest::MD5.hexdigest(File.open(args[:file], 'rb').read)
else
md5 = args[:md5]
end
url += "&md5=#{md5}"
end
response = Net::HTTP::get_response(URI.parse(url));
doc = REXML::Document.new response.body
result = Mash.new({
:status => Mash.new({}),
:query => Mash.new({}),
:segments => [],
})
%w[code message].each do |m|
result[:status][m] = doc.elements['response'].elements['status'].elements[m].text
end
# unknown md5
if result[:status][:code] == '5'
puts "unknown md5. uploading..."
upload args[:file]
get_segments :md5 => md5
else
%w[api_key id md5].each do |m|
elm = REXML::XPath.first(doc, "//parameter[@name=\"#{m}\"]")
result[:query][m] = elm.text if elm
end
doc.elements.each('response/analysis/segment') {|elm|
loudness = []
elm.elements.each('loudness/dB') {|e|
loudness.push({
:time => e.attributes['time'] || 0,
:value => e.text
})
}
pitches = []
elm.elements.each('pitches/pitch') {|e|
pitches.push e.text
}
timbre = []
elm.elements.each('timbre/coeff') {|e|
timbre.push e.text
}
result[:segments].push(Mash.new({
:start => elm.attributes['start'],
:duration => elm.attributes['duration'],
:loudness => {
:min => {
:time => loudness[0][:time],
:value => loudness[0][:value],
},
:max => {
:time => loudness[1][:time],
:value => loudness[1][:value],
},
},
:pitches => pitches,
:timbre => timbre,
}))
}
result
end
end
def search_tracks(query)
p 'search_tracks'
query = query.gsub(' ', '+')
url = @base_url + '/api/search_tracks?' +
['api_key=' + @api_key,
'version=3',
'query=' + query].join('&')
response = Net::HTTP::get_response(URI.parse(url));
REXML::Document.new response.body
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.