summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristoph Helma <helma@in-silico.ch>2010-11-10 17:44:03 +0100
committerChristoph Helma <helma@in-silico.ch>2010-11-10 17:44:03 +0100
commit9f489392359ab7d5fc3f80354acee5007cc89c55 (patch)
tree20261be533e59abd3a187ba6fa86bbb6e323d9c7
parent0ef88c5d416134dbc909c08186ebdd4bc9343035 (diff)
Adapted to new wrapper version, yard documentation added.
-rw-r--r--application.rb343
-rw-r--r--public/.gitignore2
2 files changed, 215 insertions, 130 deletions
diff --git a/application.rb b/application.rb
index 079614e..1d49ffb 100644
--- a/application.rb
+++ b/application.rb
@@ -11,88 +11,169 @@ class Dataset
property :yaml, Text, :length => 2**32-1
property :created_at, DateTime
+ def load(params,request)
+
+ data = request.env["rack.input"].read
+ content_type = request.content_type
+ content_type = "application/rdf+xml" if content_type.nil?
+ dataset = OpenTox::Dataset.new
+
+ case content_type
+
+ when /yaml/
+ dataset.load_yaml(data)
+
+ when "application/rdf+xml"
+ dataset.load_rdfxml(data)
+
+ when /multipart\/form-data/ # file uploads
+
+ case params[:file][:type]
+
+ when /yaml/
+ dataset.load_yaml(params[:file][:tempfile].read)
+
+ when "application/rdf+xml"
+ dataset.load_rdfxml_file(params[:file][:tempfile])
+
+ when "text/csv"
+ dataset = OpenTox::Dataset.new @uri
+ dataset.load_csv(params[:file][:tempfile].read)
+ dataset.add_metadata({
+ DC.title => File.basename(params[:file][:filename],".csv"),
+ OT.hasSource => File.basename(params[:file][:filename])
+ })
+
+ when /ms-excel/
+ extension = File.extname(params[:file][:filename])
+ case extension
+ when ".xls"
+ xls = params[:file][:tempfile].path + ".xls"
+ File.rename params[:file][:tempfile].path, xls # roo needs these endings
+ book = Excel.new xls
+ when ".xlsx"
+ xlsx = params[:file][:tempfile].path + ".xlsx"
+ File.rename params[:file][:tempfile].path, xlsx # roo needs these endings
+ book = Excel.new xlsx
+ else
+ raise "#{params[:file][:filename]} is not a valid Excel input file."
+ end
+ dataset.load_spreadsheet(book)
+ dataset.add_metadata({
+ DC.title => File.basename(params[:file][:filename],extension),
+ OT.hasSource => File.basename(params[:file][:filename])
+ })
+
+ else
+ raise "MIME type \"#{params[:file][:type]}\" not supported."
+ end
+
+ else
+ raise "MIME type \"#{@content_type}\" not supported."
+ end
+
+ dataset.uri = @uri # update uri (also in metdata)
+ dataset.features.keys.each { |f| dataset.features[f][OT.hasSource] = dataset.metadata[OT.hasSource] unless dataset.features[f][OT.hasSource]}
+ update(:yaml => dataset.to_yaml)
+ end
+
+ def create_representations
+ dataset = YAML.load yaml
+ ["rdfxml","xls"].each do |extension|
+ file = "public/#{@id}.#{extension}"
+ LOGGER.debug file
+ FileUtils.rm Dir["public/#{file}"] if File.exists? file
+ File.open(file,"w+") { |f| f.puts eval("dataset.to_#{extension}") }
+ end
+ end
+
end
DataMapper.auto_upgrade!
+before do
+ @accept = request.env['HTTP_ACCEPT']
+ @accept = 'application/rdf+xml' if @accept == '*/*' or @accept == '' or @accept.nil?
+end
## REST API
+# Get a list of available datasets
+# @return [text/uri-list] List of available datasets
get '/?' do
response['Content-Type'] = 'text/uri-list'
Dataset.all(params).collect{|d| d.uri}.join("\n") + "\n"
end
+# Get a dataset representation
+# @param [Header] Accept one of `application/rdf+xml, application-x-yaml, text/csv, application/ms-excel` (default application/rdf+xml)
+# @return [application/rdf+xml, application-x-yaml, text/csv, application/ms-excel] Dataset representation
get '/:id' do
- accept = request.env['HTTP_ACCEPT']
- accept = 'application/rdf+xml' if accept == '*/*' or accept == '' or accept.nil?
-
- begin
- dataset = OpenTox::Dataset.from_yaml(Dataset.get(params[:id]).yaml)
- halt 404, "Dataset #{params[:id]} not found." if dataset.nil? # not sure how an empty dataset can be returned, but if this happens stale processes keep runing at 100% cpu
- rescue => e
- LOGGER.error e.message
- LOGGER.info e.backtrace
- halt 404, "Dataset #{params[:id]} not found."
+ extension = File.extname(params[:id]).sub(/\./,'')
+ unless extension.empty?
+ params[:id].sub!(/\.#{extension}$/,'')
+ case extension
+ when "yaml"
+ @accept = 'application/x-yaml'
+ when "csv"
+ @accept = 'text/csv'
+ when "rdfxml"
+ @accept = 'application/rdf+xml'
+ when "xls"
+ @accept = 'application/ms-excel'
+ else
+ halt 404, "File format #{extension} not supported."
+ end
end
+
+ #begin
+ dataset = OpenTox::Dataset.new
+ dataset.load_yaml(Dataset.get(params[:id]).yaml)
+ halt 404, "Dataset #{params[:id]} empty." if dataset.nil? # not sure how an empty dataset can be returned, but if this happens stale processes keep runing at 100% cpu
+ #rescue => e
+ #LOGGER.error e.message
+ #LOGGER.info e.backtrace
+ #halt 404, "Dataset #{params[:id]} not found."
+ #end
- case accept
+ case @accept
when /rdf/ # redland sends text/rdf instead of application/rdf+xml
file = "public/#{params[:id]}.rdfxml"
- if File.exists? file
- response['Content-Type'] = 'application/rdf+xml'
- #redirect url_for("/#{params[:id]}",:full)+ ".rdfxml" # confuses curl (needs -L flag)
- File.read(file)
- else
- task_uri = OpenTox::Task.as_task("Converting dataset to OWL-DL (RDF/XML)", url_for(params[:id],:full)) do
- File.open(file,"w+") { |f| f.puts dataset.rdfxml }
- url_for("/#{params[:id]}",:full)+ ".rdfxml"
- end
- response['Content-Type'] = 'text/uri-list'
- halt 202,task_uri.to_s+"\n"
- end
+ response['Content-Type'] = 'application/rdf+xml'
+ File.open(file).read
when /yaml/
response['Content-Type'] = 'application/x-yaml'
- dataset.yaml
+ dataset.to_yaml
when "text/csv"
response['Content-Type'] = 'text/csv'
- dataset.csv
+ dataset.to_csv
when /ms-excel/
file = "public/#{params[:id]}.xls"
- if File.exists? file
- response['Content-Type'] = 'application/ms-excel'
- File.read(file)
- else
- task_uri = OpenTox::Task.as_task("Converting dataset to Excel", url_for(params[:id],:full)) do
- dataset.excel.write(file)
- url_for("/#{params[:id]}",:full)+ ".xls"
- end
- response['Content-Type'] = 'text/uri-list'
- halt 202,task_uri.to_s+"\n"
- end
+ response['Content-Type'] = 'application/ms-excel'
+ File.open(file).read
else
- halt 404, "Content-type #{accept} not supported."
+ halt 404, "Content-type #{@accept} not supported."
end
end
-get '/:id/metadata/?' do
+# Get metadata of the dataset
+# @return [application/rdf+xml] Metadata OWL-DL
+get '/:id/metadata' do
metadata = YAML.load(Dataset.get(params[:id]).yaml).metadata
- accept = request.env['HTTP_ACCEPT']
- accept = 'application/rdf+xml' if accept == '*/*' or accept == '' or accept.nil?
- case accept
+ case @accept
when /rdf/ # redland sends text/rdf instead of application/rdf+xml
response['Content-Type'] = 'application/rdf+xml'
serializer = OpenTox::Serializer::Owl.new
- serializer.add_metadata url_for(params[:id],:full), "Dataset", metadata
- serializer.rdfxml
+ serializer.add_metadata url_for("/#{params[:id]}",:full), metadata
+ serializer.to_rdfxml
when /yaml/
response['Content-Type'] = 'application/x-yaml'
metadata.to_yaml
@@ -100,21 +181,24 @@ get '/:id/metadata/?' do
end
+# Get a dataset feature
+# @param [Header] Accept one of `application/rdf+xml or application-x-yaml` (default application/rdf+xml)
+# @return [application/rdf+xml,application/x-yaml] Feature metadata
get %r{/(\d+)/feature/(.*)$} do |id,feature|
+#get '/:id/feature/:feature_name/?' do
- feature_uri = url_for("/#{id}/feature/#{feature}",:full)
- dataset = OpenTox::Dataset.from_yaml(Dataset.get(id).yaml)
+ #feature_uri = url_for("/#{params[:id]}/feature/#{URI.encode(params[:feature_name])}",:full) # work around racks internal uri decoding
+ #dataset = YAML.load(Dataset.get(params[:id]).yaml)
+ feature_uri = url_for("/#{id}/feature/#{URI.encode(feature)}",:full) # work around racks internal uri decoding
+ dataset = YAML.load(Dataset.get(id).yaml)
metadata = dataset.features[feature_uri]
-
- accept = request.env['HTTP_ACCEPT']
- accept = 'application/rdf+xml' if accept == '*/*' or accept == '' or accept.nil?
- case accept
+ case @accept
when /rdf/ # redland sends text/rdf instead of application/rdf+xml
response['Content-Type'] = 'application/rdf+xml'
serializer = OpenTox::Serializer::Owl.new
serializer.add_feature feature_uri, metadata
- serializer.rdfxml
+ serializer.to_rdfxml
when /yaml/
response['Content-Type'] = 'application/x-yaml'
metadata.to_yaml
@@ -122,97 +206,93 @@ get %r{/(\d+)/feature/(.*)$} do |id,feature|
end
-get '/:id/features/?' do
- response['Content-Type'] = 'text/uri-list'
- YAML.load(Dataset.get(params[:id]).yaml).features.keys.join("\n") + "\n"
+# Get a list of all features
+# @param [Header] Accept one of `application/rdf+xml, application-x-yaml, text/uri-list` (default application/rdf+xml)
+# @return [application/rdf+xml, application-x-yaml, text/uri-list] Feature list
+get '/:id/features' do
+
+ features = YAML.load(Dataset.get(params[:id]).yaml).features
+
+ case @accept
+ when /rdf/ # redland sends text/rdf instead of application/rdf+xml
+ response['Content-Type'] = 'application/rdf+xml'
+ serializer = OpenTox::Serializer::Owl.new
+ features.each { |feature,metadata| serializer.add_feature feature, metadata }
+ serializer.to_rdfxml
+ when /yaml/
+ response['Content-Type'] = 'application/x-yaml'
+ features.to_yaml
+ when "text/uri-list"
+ response['Content-Type'] = 'text/uri-list'
+ YAML.load(Dataset.get(params[:id]).yaml).features.keys.join("\n") + "\n"
+ end
end
-get '/:id/compounds/?' do
+# Get a list of all compounds
+# @return [text/uri-list] Feature list
+get '/:id/compounds' do
response['Content-Type'] = 'text/uri-list'
YAML.load(Dataset.get(params[:id]).yaml).compounds.join("\n") + "\n"
end
-post '/?' do # create an empty dataset
+# Create a new dataset.
+#
+# Posting without parameters creates and saves an empty dataset (with assigned URI).
+# Posting with parameters creates and saves a new dataset.
+# Data can be submitted either
+# - in the message body with the appropriate Content-type header or
+# - as file uploads with Content-type:multipart/form-data and a specified file type
+# @example
+# curl -X POST -F "file=@training.csv;type=text/csv" http://webservices.in-silico.ch/dataset
+# @param [Header] Content-type one of `application/x-yaml, application/rdf+xml, multipart/form-data/`
+# @param [BODY] - string with data in selected Content-type
+# @param [optional] file, for file uploads, Content-type should be multipart/form-data, please specify the file type `application/rdf+xml, application-x-yaml, text/csv, application/ms-excel`
+# @return [text/uri-list] Task ID or dataset ID (empty datasets without params)
+post '/?' do
+ @dataset = Dataset.create
response['Content-Type'] = 'text/uri-list'
- dataset = Dataset.create
- dataset.update(:uri => url_for("/#{dataset.id}", :full))
- dataset.update(:yaml => OpenTox::Dataset.new(url_for("/#{dataset.id}", :full)).to_yaml)
- "#{dataset.uri}\n"
-end
-
-post '/:id/?' do # insert data into a dataset
-
- begin
- dataset = Dataset.get(params[:id])
- halt 404, "Dataset #{params[:id]} not found." unless dataset
- data = request.env["rack.input"].read
-
- content_type = request.content_type
- content_type = "application/rdf+xml" if content_type.nil?
-
- case content_type
-
- when /yaml/
- dataset.update(:yaml => data)
-
- when "application/rdf+xml"
- dataset.update(:yaml => OpenTox::Dataset.from_rdfxml(data).yaml)
-
- when /multipart\/form-data/ # for file uploads
-
- case params[:file][:type]
-
- when /yaml/
- dataset.update(:yaml => params[:file][:tempfile].read)
-
- when "application/rdf+xml"
- dataset.update(:yaml => OpenTox::Dataset.from_rdfxml(params[:file][:tempfile]).yaml)
-
- when "text/csv"
- metadata = {DC.title => File.basename(params[:file][:filename],".csv"), OT.hasSource => File.basename(params[:file][:filename])}
- d = OpenTox::Dataset.from_csv(File.open(params[:file][:tempfile]).read)
- d.add_metadata metadata
- dataset.update(:yaml => d.yaml, :uri => d.uri)
-
- when /ms-excel/
- extension = File.extname(params[:file][:filename])
- metadata = {DC.title => File.basename(params[:file][:filename],extension), OT.hasSource => File.basename(params[:file][:filename])}
- case extension
- when ".xls"
- xls = params[:file][:tempfile].path + ".xls"
- File.rename params[:file][:tempfile].path, xls # roo needs these endings
- book = Excel.new xls
- when ".xlsx"
- xlsx = params[:file][:tempfile].path + ".xlsx"
- File.rename params[:file][:tempfile].path, xlsx # roo needs these endings
- book = Excel.new xlsx
- else
- halt 404, "#{params[:file][:filename]} is not a valid Excel input file."
- end
- d = OpenTox::Dataset.from_spreadsheet(book)
- d.add_metadata metadata
- dataset.update(:yaml => d.yaml, :uri => d.uri)
-
- else
- halt 404, "MIME type \"#{params[:file][:type]}\" not supported."
- end
-
- else
- halt 404, "MIME type \"#{content_type}\" not supported."
+ @dataset.update(:uri => url_for("/#{@dataset.id}", :full))
+ if params.empty? and request.env["rack.input"].read.empty?
+ ot_dataset = OpenTox::Dataset.new(@dataset.uri)
+ @dataset.update(:yaml => OpenTox::Dataset.new(@dataset.uri).to_yaml)
+ @dataset.create_representations
+ @dataset.uri
+ else
+ task_uri = OpenTox::Task.as_task("Converting and saving dataset ", @dataset.uri) do
+ @dataset.load params, request
+ @dataset.create_representations
+ @dataset.uri
end
+ halt 202,task_uri.to_s+"\n"
+ end
+end
- FileUtils.rm Dir["public/#{params[:id]}.*"] # delete all serialization files, will be recreated at next reques
- response['Content-Type'] = 'text/uri-list'
- "#{dataset.uri}\n"
-
- rescue => e
- LOGGER.error e.message
- LOGGER.info e.backtrace
- halt 500, "Could not save dataset #{dataset.uri}."
+# Save a dataset, will overwrite all existing data
+#
+# Data can be submitted either
+# - in the message body with the appropriate Content-type header or
+# - as file uploads with Content-type:multipart/form-data and a specified file type
+# @example
+# curl -X POST -F "file=@training.csv;type=text/csv" http://webservices.in-silico.ch/dataset/1
+# @param [Header] Content-type one of `application/x-yaml, application/rdf+xml, multipart/form-data/`
+# @param [BODY] - string with data in selected Content-type
+# @param [optional] file, for file uploads, Content-type should be multipart/form-data, please specify the file type `application/rdf+xml, application-x-yaml, text/csv, application/ms-excel`
+# @return [text/uri-list] Task ID
+post '/:id' do
+ @dataset = Dataset.get(params[:id])
+ halt 404, "Dataset #{params[:id]} not found." unless @dataset
+ response['Content-Type'] = 'text/uri-list'
+ task_uri = OpenTox::Task.as_task("Converting and saving dataset ", @dataset.uri) do
+ @dataset.load params, request
+ @dataset.create_representations
+ @dataset.uri
end
+ halt 202,task_uri.to_s+"\n"
end
-delete '/:id/?' do
+# Delete a dataset
+# @return [text/plain] Status message
+delete '/:id' do
begin
dataset = Dataset.get(params[:id])
FileUtils.rm Dir["public/#{params[:id]}.*"]
@@ -224,8 +304,11 @@ delete '/:id/?' do
end
end
+# Delete all datasets
+# @return [text/plain] Status message
delete '/?' do
- Dataset.all {|d| FileUtils.rm Dir["public/#{d.id}.*"] }
+ FileUtils.rm Dir["public/*.rdfxml"]
+ FileUtils.rm Dir["public/*.xls"]
Dataset.auto_migrate!
response['Content-Type'] = 'text/plain'
"All datasets deleted."
diff --git a/public/.gitignore b/public/.gitignore
new file mode 100644
index 0000000..debc7d4
--- /dev/null
+++ b/public/.gitignore
@@ -0,0 +1,2 @@
+*.rdfxml
+*.xls