diff options
-rw-r--r-- | example.rb | 1 | ||||
-rw-r--r-- | report/external/mimeparse.rb | 220 | ||||
-rw-r--r-- | report/report_application.rb | 12 | ||||
-rw-r--r-- | report/report_format.rb | 25 | ||||
-rw-r--r-- | validation/validation_application.rb | 79 |
5 files changed, 73 insertions, 264 deletions
@@ -146,6 +146,7 @@ class Example result += line if result.size<50 end end + result.chomp! result.gsub!(/\n/, " \\n ") if ($?==0) if OpenTox::Utils.task_uri?(result) diff --git a/report/external/mimeparse.rb b/report/external/mimeparse.rb deleted file mode 100644 index 553c431..0000000 --- a/report/external/mimeparse.rb +++ /dev/null @@ -1,220 +0,0 @@ -# mimeparse.rb -# -# This module provides basic functions for handling mime-types. It can -# handle matching mime-types against a list of media-ranges. See section -# 14.1 of the HTTP specification [RFC 2616] for a complete explanation. -# -# http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1 -# -# --------- -# -# This is a port of Joe Gregario's mimeparse.py, which can be found at -# <http://code.google.com/p/mimeparse/>. -# -# ported from version 0.1.2 -# -# Comments are mostly excerpted from the original. - -module MIMEParse - module_function - -# Carves up a mime-type and returns an Array of the -# [type, subtype, params] where "params" is a Hash of all -# the parameters for the media range. -# -# For example, the media range "application/xhtml;q=0.5" would -# get parsed into: -# -# ["application", "xhtml", { "q" => "0.5" }] -def parse_mime_type(mime_type) - parts = mime_type.split(";") - - params = {} - - parts[1..-1].map do |param| - k,v = param.split("=").map { |s| s.strip } - params[k] = v - end - - full_type = parts[0].strip - # Java URLConnection class sends an Accept header that includes a single "*" - # Turn it into a legal wildcard. - full_type = "*/*" if full_type == "*" - type, subtype = full_type.split("/") - raise "malformed mime type" unless subtype - - [type.strip, subtype.strip, params] -end - -# Carves up a media range and returns an Array of the -# [type, subtype, params] where "params" is a Hash of all -# the parameters for the media range. -# -# For example, the media range "application/*;q=0.5" would -# get parsed into: -# -# ["application", "*", { "q", "0.5" }] -# -# In addition this function also guarantees that there -# is a value for "q" in the params dictionary, filling it -# in with a proper default if necessary. -def parse_media_range(range) - type, subtype, params = parse_mime_type(range) - unless params.has_key?("q") and params["q"] and params["q"].to_f and params["q"].to_f <= 1 and params["q"].to_f >= 0 - params["q"] = "1" - end - - [type, subtype, params] -end - -# Find the best match for a given mime-type against a list of -# media_ranges that have already been parsed by #parse_media_range -# -# Returns the fitness and the "q" quality parameter of the best match, -# or [-1, 0] if no match was found. Just as for #quality_parsed, -# "parsed_ranges" must be an Enumerable of parsed media ranges. -def fitness_and_quality_parsed(mime_type, parsed_ranges) - best_fitness = -1 - best_fit_q = 0 - target_type, target_subtype, target_params = parse_media_range(mime_type) - - parsed_ranges.each do |type,subtype,params| - if (type == target_type or type == "*" or target_type == "*") and - (subtype == target_subtype or subtype == "*" or target_subtype == "*") - param_matches = target_params.find_all { |k,v| k != "q" and params.has_key?(k) and v == params[k] }.length - - fitness = (type == target_type) ? 100 : 0 - fitness += (subtype == target_subtype) ? 10 : 0 - fitness += param_matches - - if fitness > best_fitness - best_fitness = fitness - best_fit_q = params["q"] - end - end - end - - [best_fitness, best_fit_q.to_f] -end - -# Find the best match for a given mime-type against a list of -# media_ranges that have already been parsed by #parse_media_range -# -# Returns the "q" quality parameter of the best match, 0 if no match -# was found. This function behaves the same as #quality except that -# "parsed_ranges" must be an Enumerable of parsed media ranges. -def quality_parsed(mime_type, parsed_ranges) - fitness_and_quality_parsed(mime_type, parsed_ranges)[1] -end - -# Returns the quality "q" of a mime_type when compared against -# the media-ranges in ranges. For example: -# -# irb> quality("text/html", "text/*;q=0.3, text/html;q=0.7, text/html;level=1, text/html;level=2;q=0.4, */*;q=0.5") -# => 0.7 -def quality(mime_type, ranges) - parsed_ranges = ranges.split(",").map { |r| parse_media_range(r) } - quality_parsed(mime_type, parsed_ranges) -end - -# Takes a list of supported mime-types and finds the best match -# for all the media-ranges listed in header. The value of header -# must be a string that conforms to the format of the HTTP Accept: -# header. The value of supported is an Enumerable of mime-types -# -# irb> best_match(["application/xbel+xml", "text/xml"], "text/*;q=0.5,*/*; q=0.1") -# => "text/xml" -def best_match(supported, header) - parsed_header = header.split(",").map { |r| parse_media_range(r) } - - weighted_matches = supported.map do |mime_type| - [fitness_and_quality_parsed(mime_type, parsed_header), mime_type] - end - - weighted_matches.sort! - - weighted_matches.last[0][1].zero? ? nil : weighted_matches.last[1] -end -end - -if __FILE__ == $0 - require "test/unit" - - class TestMimeParsing < Test::Unit::TestCase - include MIMEParse - - def test_parse_media_range - assert_equal [ "application", "xml", { "q" => "1" } ], - parse_media_range("application/xml;q=1") - - assert_equal [ "application", "xml", { "q" => "1" } ], - parse_media_range("application/xml") - - assert_equal [ "application", "xml", { "q" => "1" } ], - parse_media_range("application/xml;q=") - - assert_equal [ "application", "xml", { "q" => "1", "b" => "other" } ], - parse_media_range("application/xml ; q=1;b=other") - - assert_equal [ "application", "xml", { "q" => "1", "b" => "other" } ], - parse_media_range("application/xml ; q=2;b=other") - - # Java URLConnection class sends an Accept header that includes a single "*" - assert_equal [ "*", "*", { "q" => ".2" } ], - parse_media_range(" *; q=.2") - end - - def test_rfc_2616_example - accept = "text/*;q=0.3, text/html;q=0.7, text/html;level=1, text/html;level=2;q=0.4, */*;q=0.5" - - assert_equal 1, quality("text/html;level=1", accept) - assert_equal 0.7, quality("text/html", accept) - assert_equal 0.3, quality("text/plain", accept) - assert_equal 0.5, quality("image/jpeg", accept) - assert_equal 0.4, quality("text/html;level=2", accept) - assert_equal 0.7, quality("text/html;level=3", accept) - end - - def test_best_match - @supported_mime_types = [ "application/xbel+xml", "application/xml" ] - - # direct match - assert_best_match "application/xbel+xml", "application/xbel+xml" - # direct match with a q parameter - assert_best_match "application/xbel+xml", "application/xbel+xml; q=1" - # direct match of our second choice with a q parameter - assert_best_match "application/xml", "application/xml; q=1" - # match using a subtype wildcard - assert_best_match "application/xml", "application/*; q=1" - # match using a type wildcard - assert_best_match "application/xml", "*/*" - - @supported_mime_types = [ "application/xbel+xml", "text/xml" ] - # match using a type versus a lower weighted subtype - assert_best_match "text/xml", "text/*;q=0.5,*/*;q=0.1" - # fail to match anything - assert_best_match nil, "text/html,application/atom+xml; q=0.9" - # common AJAX scenario - @supported_mime_types = [ "application/json", "text/html" ] - assert_best_match "application/json", "application/json, text/javascript, */*" - # verify fitness sorting - assert_best_match "application/json", "application/json, text/html;q=0.9" - end - - def test_support_wildcards - @supported_mime_types = ['image/*', 'application/xml'] - # match using a type wildcard - assert_best_match 'image/*', 'image/png' - # match using a wildcard for both requested and supported - assert_best_match 'image/*', 'image/*' - end - - def assert_best_match(expected, header) - assert_equal(expected, best_match(@supported_mime_types, header)) - end - end -end - - -#puts MIMEParse::best_match(["text/xml","text/html","application/pdf"], -# 'application/x-ms-application,image/jpeg, application/xaml+xml, image/gif, image/pjpeg, application/x-ms-xbap, */*') diff --git a/report/report_application.rb b/report/report_application.rb index 95913cd..baa91a0 100644 --- a/report/report_application.rb +++ b/report/report_application.rb @@ -80,11 +80,15 @@ end post '/report/:type/:id/format_html' do - perform do |rs| - rs.get_report(params[:type],params[:id],"text/html",true,params) - content_type "text/uri-list" - rs.get_uri(params[:type],params[:id])+"\n" + task_uri = OpenTox::Task.as_task("Format report",url_for("/report/"+params[:type]+"/format_html", :full), params) do + perform do |rs| + rs.get_report(params[:type],params[:id],"text/html",true,params) + content_type "text/uri-list" + rs.get_uri(params[:type],params[:id])+"\n" + end end + content_type "text/uri-list" + halt 202,task_uri+"\n" end diff --git a/report/report_format.rb b/report/report_format.rb index e61d9be..aafa204 100644 --- a/report/report_format.rb +++ b/report/report_format.rb @@ -10,17 +10,26 @@ ENV['SAXON_JAR'] = "saxonhe9-2-0-3j/saxon9he.jar" unless ENV['SAXON_JAR'] # module Reports::ReportFormat - CONTENT_TYPES = ["application/x-yaml","text/html","application/rdf+xml", "text/xml","application/pdf"] - # returns report-format, according to header value def self.get_format(accept_header_value) - begin - content_type = MIMEParse::best_match(CONTENT_TYPES, accept_header_value) - raise RuntimeException.new unless content_type - rescue - raise Reports::BadRequest.new("Accept header '"+accept_header_value.to_s+"' not supported, supported types are "+CONTENT_TYPES.join(", ")) + + case accept_header_value + when /text\/html/ + "text/html" + when /application\/rdf\+xml/ + "application/rdf+xml" + when /text\/xml/ + "text/xml" + when /application\/x-yaml|\*\/\*/ + "application/x-yaml" + else + raise Reports::BadRequest.new("Accept header '"+accept_header_value.to_s+ + "' not supported, supported types are "+ + "text/html"+", "+ + "application/rdf+xml"+", "+ + "text/xml"+", "+ + "application/x-yaml") end - return content_type end def self.get_filename_extension(format) diff --git a/validation/validation_application.rb b/validation/validation_application.rb index 983f3bd..cf6fc78 100644 --- a/validation/validation_application.rb +++ b/validation/validation_application.rb @@ -84,19 +84,20 @@ get '/crossvalidation/:id' do when "application/rdf+xml" content_type "application/rdf+xml" crossvalidation.to_rdf - when /application\/x-yaml/ - content_type "application/x-yaml" - crossvalidation.to_yaml when /text\/html/ related_links = "Search for corresponding cv report: "+$sinatra.url_for("/report/crossvalidation?crossvalidation="+crossvalidation.crossvalidation_uri,:full)+"\n"+ "Statistics for this crossvalidation: "+$sinatra.url_for("/crossvalidation/"+params[:id]+"/statistics",:full)+"\n"+ + "Predictions of this crossvalidation: "+$sinatra.url_for("/crossvalidation/"+params[:id]+"/predictions",:full)+"\n"+ "All crossvalidations: "+$sinatra.url_for("/crossvalidation",:full)+"\n"+ "All crossvalidation reports: "+$sinatra.url_for("/report/crossvalidation",:full) description = "A crossvalidation resource." content_type "text/html" OpenTox.text_to_html crossvalidation.to_yaml,related_links,description + when /application\/x-yaml|\*\/\*/ + content_type "application/x-yaml" + crossvalidation.to_yaml else halt 400, "MIME type '"+request.env['HTTP_ACCEPT'].to_s+"' not supported, valid Accept-Headers: \"application/rdf+xml\", \"application/x-yaml\", \"text/html\"." end @@ -144,16 +145,16 @@ delete '/crossvalidation/:id/?' do Validation::Crossvalidation.delete(params[:id]) end -get '/crossvalidation/:id/validations' do - LOGGER.info "get all validations for crossvalidation with id "+params[:id].to_s - begin - crossvalidation = Validation::Crossvalidation.find(params[:id]) - rescue ActiveRecord::RecordNotFound => ex - halt 404, "Crossvalidation '#{params[:id]}' not found." - end - content_type "text/uri-list" - Validation::Validation.find( :all, :conditions => { :crossvalidation_id => params[:id] } ).collect{ |v| v.validation_uri.to_s }.join("\n")+"\n" -end +#get '/crossvalidation/:id/validations' do +# LOGGER.info "get all validations for crossvalidation with id "+params[:id].to_s +# begin +# crossvalidation = Validation::Crossvalidation.find(params[:id]) +# rescue ActiveRecord::RecordNotFound => ex +# halt 404, "Crossvalidation '#{params[:id]}' not found." +# end +# content_type "text/uri-list" +# Validation::Validation.find( :all, :conditions => { :crossvalidation_id => params[:id] } ).collect{ |v| v.validation_uri.to_s }.join("\n")+"\n" +#end get '/crossvalidation/:id/predictions' do LOGGER.info "get predictions for crossvalidation with id "+params[:id].to_s @@ -164,7 +165,21 @@ get '/crossvalidation/:id/predictions' do end content_type "application/x-yaml" validations = Validation::Validation.find( :all, :conditions => { :crossvalidation_id => params[:id] } ) - Lib::OTPredictions.to_array( validations.collect{ |v| v.compute_validation_stats_with_model(nil, true) } ).to_yaml + p = Lib::OTPredictions.to_array( validations.collect{ |v| v.compute_validation_stats_with_model(nil, true) } ).to_yaml + + case request.env['HTTP_ACCEPT'].to_s + when /text\/html/ + content_type "text/html" + description = + "The crossvalidation predictions as (yaml-)array." + related_links = + "All crossvalidations: "+$sinatra.url_for("/crossvalidation",:full)+"\n"+ + "Correspoding crossvalidation: "+$sinatra.url_for("/crossvalidation/"+params[:id],:full) + OpenTox.text_to_html p, related_links, description + else + content_type "text/x-yaml" + p + end end get '/?' do @@ -442,21 +457,21 @@ get '/:id/predictions' do end end -get '/:id/:attribute' do - LOGGER.info "access validation attribute "+params.inspect - begin - validation = Validation::Validation.find(params[:id]) - rescue ActiveRecord::RecordNotFound => ex - halt 404, "Validation '#{params[:id]}' not found." - end - begin - raise unless validation.attribute_loaded?(params[:attribute]) - rescue - halt 400, "Not a validation attribute: "+params[:attribute].to_s - end - content_type "text/plain" - return validation.send(params[:attribute]) -end +#get '/:id/:attribute' do +# LOGGER.info "access validation attribute "+params.inspect +# begin +# validation = Validation::Validation.find(params[:id]) +# rescue ActiveRecord::RecordNotFound => ex +# halt 404, "Validation '#{params[:id]}' not found." +# end +# begin +# raise unless validation.attribute_loaded?(params[:attribute]) +# rescue +# halt 400, "Not a validation attribute: "+params[:attribute].to_s +# end +# content_type "text/plain" +# return validation.send(params[:attribute]) +#end get '/:id' do LOGGER.info "get validation with id "+params[:id].to_s+" '"+request.env['HTTP_ACCEPT'].to_s+"'" @@ -470,9 +485,6 @@ get '/:id' do when "application/rdf+xml" content_type "application/rdf+xml" validation.to_rdf - when /application\/x-yaml/ - content_type "application/x-yaml" - validation.to_yaml when /text\/html/ content_type "text/html" description = @@ -483,6 +495,9 @@ get '/:id' do "All validations: "+$sinatra.url_for("/",:full)+"\n"+ "All validation reports: "+$sinatra.url_for("/report/validation",:full) OpenTox.text_to_html validation.to_yaml,related_links,description + when /application\/x-yaml|\*\/\*/ + content_type "application/x-yaml" + validation.to_yaml else halt 400, "MIME type '"+request.env['HTTP_ACCEPT'].to_s+"' not supported, valid Accept-Headers: \"application/rdf+xml\", \"application/x-yaml\", \"text/html\"." end |