opentox-ruby 0.0.2 → 1.0.0
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.markdown +41 -0
- data/Rakefile +4 -0
- data/VERSION +1 -1
- data/lib/algorithm.rb +15 -2
- data/lib/authorization.rb +381 -0
- data/lib/compound.rb +6 -0
- data/lib/config/config_ru.rb +1 -0
- data/lib/dataset.rb +98 -43
- data/lib/environment.rb +9 -18
- data/lib/error.rb +99 -0
- data/lib/feature.rb +30 -2
- data/lib/helper.rb +90 -17
- data/lib/model.rb +81 -34
- data/lib/ontology_service.rb +43 -0
- data/lib/opentox-ruby.rb +3 -2
- data/lib/opentox.rb +9 -4
- data/lib/overwrite.rb +87 -28
- data/lib/parser.rb +117 -22
- data/lib/policy.rb +261 -0
- data/lib/rest_client_wrapper.rb +110 -99
- data/lib/serializer.rb +130 -1
- data/lib/task.rb +179 -42
- data/lib/templates/config.yaml +45 -0
- data/lib/templates/default_guest_policy.xml +53 -0
- data/lib/templates/default_policy.xml +53 -0
- data/lib/to-html.rb +112 -0
- data/lib/validation.rb +183 -57
- metadata +31 -94
- data/README.rdoc +0 -23
data/lib/helper.rb
CHANGED
@@ -1,26 +1,99 @@
|
|
1
1
|
helpers do
|
2
2
|
|
3
|
-
|
4
|
-
def protected!
|
5
|
-
|
6
|
-
|
7
|
-
|
3
|
+
# Authentification
|
4
|
+
def protected!(subjectid)
|
5
|
+
if env["session"]
|
6
|
+
unless authorized?(subjectid)
|
7
|
+
flash[:notice] = "You don't have access to this section: "
|
8
|
+
redirect back
|
9
|
+
end
|
10
|
+
elsif !env["session"] && subjectid
|
11
|
+
unless authorized?(subjectid)
|
12
|
+
LOGGER.debug "URI not authorized: clean: " + clean_uri("#{request.env['rack.url_scheme']}://#{request.env['HTTP_HOST']}#{request.env['REQUEST_URI']}").to_s + " full: #{request.env['rack.url_scheme']}://#{request.env['HTTP_HOST']}#{request.env['REQUEST_URI']} with request: #{request.env['REQUEST_METHOD']}"
|
13
|
+
raise OpenTox::NotAuthorizedError.new "Not authorized"
|
14
|
+
end
|
15
|
+
else
|
16
|
+
raise OpenTox::NotAuthorizedError.new "Not authorized" unless authorized?(subjectid)
|
17
|
+
end
|
8
18
|
end
|
9
19
|
|
10
|
-
|
11
|
-
|
12
|
-
|
20
|
+
#Check Authorization for URI with method and subjectid.
|
21
|
+
def authorized?(subjectid)
|
22
|
+
request_method = request.env['REQUEST_METHOD']
|
23
|
+
uri = clean_uri("#{request.env['rack.url_scheme']}://#{request.env['HTTP_HOST']}#{request.env['REQUEST_URI']}")
|
24
|
+
request_method = "GET" if request_method == "POST" && uri =~ /\/model\/\d+\/?$/
|
25
|
+
return OpenTox::Authorization.authorized?(uri, request_method, subjectid)
|
13
26
|
end
|
14
27
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
=
|
28
|
+
#cleans URI from querystring and file-extension. Sets port 80 to emptystring
|
29
|
+
# @param [String] uri
|
30
|
+
def clean_uri(uri)
|
31
|
+
uri = uri.sub(" ", "%20") #dirty hacks => to fix
|
32
|
+
uri = uri[0,uri.index("InChI=")] if uri.index("InChI=")
|
33
|
+
|
34
|
+
out = URI.parse(uri)
|
35
|
+
out.path = out.path[0, out.path.length - (out.path.reverse.rindex(/\/{1}\d+\/{1}/))] if out.path.index(/\/{1}\d+\/{1}/) #cuts after /id/ for a&a
|
36
|
+
port = (out.scheme=="http" && out.port==80)||(out.scheme=="https" && out.port==443) ? "" : ":#{out.port.to_s}"
|
37
|
+
"#{out.scheme}://#{out.host}#{port}#{out.path.chomp("/")}" #"
|
38
|
+
end
|
39
|
+
|
40
|
+
#unprotected uri for login
|
41
|
+
def login_requests
|
42
|
+
return env['REQUEST_URI'] =~ /\/login$/
|
43
|
+
end
|
44
|
+
|
45
|
+
def uri_available?(urlStr)
|
46
|
+
url = URI.parse(urlStr)
|
47
|
+
unless @subjectid
|
48
|
+
Net::HTTP.start(url.host, url.port) do |http|
|
49
|
+
return http.head(url.request_uri).code == "200"
|
50
|
+
end
|
51
|
+
else
|
52
|
+
Net::HTTP.start(url.host, url.port) do |http|
|
53
|
+
return http.post(url.request_uri, "subjectid=#{@subjectid}").code == "202"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
24
57
|
|
25
58
|
end
|
26
59
|
|
60
|
+
before do
|
61
|
+
unless !AA_SERVER or login_requests or CONFIG[:authorization][:free_request].include?(env['REQUEST_METHOD'])
|
62
|
+
begin
|
63
|
+
subjectid = nil
|
64
|
+
subjectid = session[:subjectid] if session[:subjectid]
|
65
|
+
subjectid = params[:subjectid] if params[:subjectid] and !subjectid
|
66
|
+
subjectid = request.env['HTTP_SUBJECTID'] if request.env['HTTP_SUBJECTID'] and !subjectid
|
67
|
+
subjectid = request.cookies["subjectid"] unless subjectid
|
68
|
+
# see http://rack.rubyforge.org/doc/SPEC.html
|
69
|
+
subjectid = CGI.unescape(subjectid) if subjectid.include?("%23")
|
70
|
+
@subjectid = subjectid
|
71
|
+
rescue
|
72
|
+
#LOGGER.debug "OpenTox ruby api wrapper: helper before filter: NO subjectid for URI: #{request.env['rack.url_scheme']}://#{request.env['HTTP_HOST']}#{request.env['REQUEST_URI']}"
|
73
|
+
subjectid = ""
|
74
|
+
end
|
75
|
+
@subjectid = subjectid
|
76
|
+
protected!(subjectid)
|
77
|
+
|
78
|
+
extension = File.extname(request.path_info) # params[:id] is not yet available
|
79
|
+
unless extension.empty?
|
80
|
+
#request.path_info.sub!(/\.#{extension}$/,'')
|
81
|
+
case extension
|
82
|
+
when "html"
|
83
|
+
@accept = 'text/html'
|
84
|
+
when "yaml"
|
85
|
+
@accept = 'application/x-yaml'
|
86
|
+
when "csv"
|
87
|
+
@accept = 'text/csv'
|
88
|
+
when "rdfxml"
|
89
|
+
@accept = 'application/rdf+xml'
|
90
|
+
when "xls"
|
91
|
+
@accept = 'application/ms-excel'
|
92
|
+
else
|
93
|
+
halt 404, "File format #{extension} not supported."
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
data/lib/model.rb
CHANGED
@@ -6,33 +6,71 @@ module OpenTox
|
|
6
6
|
|
7
7
|
# Run a model with parameters
|
8
8
|
# @param [Hash] params Parameters for OpenTox model
|
9
|
+
# @param [optional,OpenTox::Task] waiting_task (can be a OpenTox::Subtask as well), progress is updated accordingly
|
9
10
|
# @return [text/uri-list] Task or resource URI
|
10
|
-
def run(params)
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
RestClientWrapper.post(@uri,{:accept => accept},params).to_s
|
18
|
-
rescue => e
|
19
|
-
LOGGER.error "Failed to run #{@uri} with #{params.inspect} (#{e.inspect})"
|
20
|
-
raise "Failed to run #{@uri} with #{params.inspect}"
|
11
|
+
def run( params, accept_header=nil, waiting_task=nil )
|
12
|
+
unless accept_header
|
13
|
+
if CONFIG[:yaml_hosts].include?(URI.parse(@uri).host)
|
14
|
+
accept_header = 'application/x-yaml'
|
15
|
+
else
|
16
|
+
accept_header = 'application/rdf+xml'
|
17
|
+
end
|
21
18
|
end
|
19
|
+
LOGGER.info "running model "+@uri.to_s+", params: "+params.inspect+", accept: "+accept_header.to_s
|
20
|
+
RestClientWrapper.post(@uri,params,{:accept => accept_header},waiting_task).to_s
|
22
21
|
end
|
23
22
|
|
24
23
|
# Generic OpenTox model class for all API compliant services
|
25
24
|
class Generic
|
26
25
|
include Model
|
26
|
+
|
27
|
+
# Find Generic Opentox Model via URI, and loads metadata, could raise NotFound/NotAuthorized error
|
28
|
+
# @param [String] uri Model URI
|
29
|
+
# @return [OpenTox::Model::Generic] Model instance
|
30
|
+
def self.find(uri,subjectid=nil)
|
31
|
+
return nil unless uri
|
32
|
+
model = Generic.new(uri)
|
33
|
+
model.load_metadata(subjectid)
|
34
|
+
raise "could not load model metadata '"+uri.to_s+"'" if model.metadata==nil or model.metadata.size==0
|
35
|
+
model
|
36
|
+
end
|
37
|
+
|
38
|
+
# provides feature type, possible types are "regression" or "classification"
|
39
|
+
# @return [String] feature type, "unknown" if type could not be estimated
|
40
|
+
def feature_type(subjectid=nil)
|
41
|
+
return @feature_type if @feature_type
|
42
|
+
|
43
|
+
# dynamically perform restcalls if necessary
|
44
|
+
load_metadata(subjectid) if @metadata==nil or @metadata.size==0 or (@metadata.size==1 && @metadata.values[0]==@uri)
|
45
|
+
algorithm = OpenTox::Algorithm::Generic.find(@metadata[OT.algorithm], subjectid)
|
46
|
+
algorithm_title = algorithm ? algorithm.metadata[DC.title] : nil
|
47
|
+
algorithm_type = algorithm ? algorithm.metadata[OT.isA] : nil
|
48
|
+
dependent_variable = OpenTox::Feature.find( @metadata[OT.dependentVariables],subjectid )
|
49
|
+
dependent_variable_type = dependent_variable ? dependent_variable.feature_type : nil
|
50
|
+
type_indicators = [dependent_variable_type, @metadata[OT.isA], @metadata[DC.title],
|
51
|
+
@uri, algorithm_type, algorithm_title]
|
52
|
+
type_indicators.each do |type|
|
53
|
+
case type
|
54
|
+
when /(?i)classification/
|
55
|
+
@feature_type = "classification"
|
56
|
+
break
|
57
|
+
when /(?i)regression/
|
58
|
+
@feature_type = "regression"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
raise "unknown model "+type_indicators.inspect unless @feature_type
|
62
|
+
@feature_type
|
63
|
+
end
|
64
|
+
|
27
65
|
end
|
28
|
-
|
66
|
+
|
29
67
|
# Lazy Structure Activity Relationship class
|
30
68
|
class Lazar
|
31
69
|
|
32
70
|
include Model
|
33
71
|
include Algorithm
|
34
72
|
|
35
|
-
attr_accessor :compound, :prediction_dataset, :features, :effects, :activities, :p_values, :fingerprints, :feature_calculation_algorithm, :similarity_algorithm, :prediction_algorithm, :min_sim
|
73
|
+
attr_accessor :compound, :prediction_dataset, :features, :effects, :activities, :p_values, :fingerprints, :feature_calculation_algorithm, :similarity_algorithm, :prediction_algorithm, :min_sim, :subjectid
|
36
74
|
|
37
75
|
def initialize(uri=nil)
|
38
76
|
|
@@ -60,15 +98,15 @@ module OpenTox
|
|
60
98
|
|
61
99
|
# Get URIs of all lazar models
|
62
100
|
# @return [Array] List of lazar model URIs
|
63
|
-
def self.all
|
64
|
-
RestClientWrapper.get(CONFIG[:services]["opentox-model"]).to_s.split("\n")
|
101
|
+
def self.all(subjectid=nil)
|
102
|
+
RestClientWrapper.get(CONFIG[:services]["opentox-model"], :subjectid => subjectid).to_s.split("\n")
|
65
103
|
end
|
66
104
|
|
67
105
|
# Find a lazar model
|
68
106
|
# @param [String] uri Model URI
|
69
107
|
# @return [OpenTox::Model::Lazar] lazar model
|
70
|
-
def self.find(uri)
|
71
|
-
YAML.load RestClientWrapper.get(uri
|
108
|
+
def self.find(uri, subjectid=nil)
|
109
|
+
YAML.load RestClientWrapper.get(uri,{:accept => 'application/x-yaml', :subjectid => subjectid})
|
72
110
|
end
|
73
111
|
|
74
112
|
# Create a new lazar model
|
@@ -77,7 +115,7 @@ module OpenTox
|
|
77
115
|
def self.create(params)
|
78
116
|
lazar_algorithm = OpenTox::Algorithm::Generic.new File.join( CONFIG[:services]["opentox-algorithm"],"lazar")
|
79
117
|
model_uri = lazar_algorithm.run(params)
|
80
|
-
OpenTox::Model::Lazar.find(model_uri)
|
118
|
+
OpenTox::Model::Lazar.find(model_uri, params[:subjectid])
|
81
119
|
end
|
82
120
|
|
83
121
|
# Get a parameter value
|
@@ -89,21 +127,30 @@ module OpenTox
|
|
89
127
|
|
90
128
|
# Predict a dataset
|
91
129
|
# @param [String] dataset_uri Dataset URI
|
130
|
+
# @param [optional,subjectid]
|
131
|
+
# @param [optional,OpenTox::Task] waiting_task (can be a OpenTox::Subtask as well), progress is updated accordingly
|
92
132
|
# @return [OpenTox::Dataset] Dataset with predictions
|
93
|
-
def predict_dataset(dataset_uri)
|
94
|
-
@prediction_dataset = Dataset.create
|
133
|
+
def predict_dataset(dataset_uri, subjectid=nil, waiting_task=nil)
|
134
|
+
@prediction_dataset = Dataset.create(CONFIG[:services]["opentox-dataset"], subjectid)
|
95
135
|
@prediction_dataset.add_metadata({
|
96
136
|
OT.hasSource => @uri,
|
97
137
|
DC.creator => @uri,
|
98
138
|
DC.title => URI.decode(File.basename( @metadata[OT.dependentVariables] )),
|
99
139
|
OT.parameters => [{DC.title => "dataset_uri", OT.paramValue => dataset_uri}]
|
100
140
|
})
|
101
|
-
d = Dataset.new(dataset_uri)
|
102
|
-
d.load_compounds
|
141
|
+
d = Dataset.new(dataset_uri,subjectid)
|
142
|
+
d.load_compounds(subjectid)
|
143
|
+
count = 0
|
103
144
|
d.compounds.each do |compound_uri|
|
104
|
-
|
145
|
+
begin
|
146
|
+
predict(compound_uri,false,subjectid)
|
147
|
+
count += 1
|
148
|
+
waiting_task.progress( count/d.compounds.size.to_f*100.0 ) if waiting_task
|
149
|
+
rescue => ex
|
150
|
+
LOGGER.warn "prediction for compound "+compound_uri.to_s+" failed: "+ex.message
|
151
|
+
end
|
105
152
|
end
|
106
|
-
@prediction_dataset.save
|
153
|
+
@prediction_dataset.save(subjectid)
|
107
154
|
@prediction_dataset
|
108
155
|
end
|
109
156
|
|
@@ -111,7 +158,7 @@ module OpenTox
|
|
111
158
|
# @param [String] compound_uri Compound URI
|
112
159
|
# @param [optinal,Boolean] verbose Verbose prediction (output includes neighbors and features)
|
113
160
|
# @return [OpenTox::Dataset] Dataset with prediction
|
114
|
-
def predict(compound_uri,verbose=false)
|
161
|
+
def predict(compound_uri,verbose=false,subjectid=nil)
|
115
162
|
|
116
163
|
@compound = Compound.new compound_uri
|
117
164
|
features = {}
|
@@ -119,7 +166,7 @@ module OpenTox
|
|
119
166
|
unless @prediction_dataset
|
120
167
|
#@prediction_dataset = cached_prediction
|
121
168
|
#return @prediction_dataset if cached_prediction
|
122
|
-
@prediction_dataset = Dataset.create
|
169
|
+
@prediction_dataset = Dataset.create(CONFIG[:services]["opentox-dataset"], subjectid)
|
123
170
|
@prediction_dataset.add_metadata( {
|
124
171
|
OT.hasSource => @uri,
|
125
172
|
DC.creator => @uri,
|
@@ -129,7 +176,7 @@ module OpenTox
|
|
129
176
|
} )
|
130
177
|
end
|
131
178
|
|
132
|
-
return @prediction_dataset if database_activity
|
179
|
+
return @prediction_dataset if database_activity(subjectid)
|
133
180
|
|
134
181
|
neighbors
|
135
182
|
prediction = eval("#{@prediction_algorithm}(@neighbors,{:similarity_algorithm => @similarity_algorithm, :p_values => @p_values})")
|
@@ -217,7 +264,7 @@ module OpenTox
|
|
217
264
|
end
|
218
265
|
end
|
219
266
|
|
220
|
-
@prediction_dataset.save
|
267
|
+
@prediction_dataset.save(subjectid)
|
221
268
|
@prediction_dataset
|
222
269
|
end
|
223
270
|
|
@@ -245,11 +292,11 @@ module OpenTox
|
|
245
292
|
|
246
293
|
# Find database activities and store them in @prediction_dataset
|
247
294
|
# @return [Boolean] true if compound has databasse activities, false if not
|
248
|
-
def database_activity
|
295
|
+
def database_activity(subjectid)
|
249
296
|
if @activities[@compound.uri]
|
250
297
|
@activities[@compound.uri].each { |act| @prediction_dataset.add @compound.uri, @metadata[OT.dependentVariables], act }
|
251
298
|
@prediction_dataset.add_metadata(OT.hasSource => @metadata[OT.trainingDataset])
|
252
|
-
@prediction_dataset.save
|
299
|
+
@prediction_dataset.save(subjectid)
|
253
300
|
true
|
254
301
|
else
|
255
302
|
false
|
@@ -257,13 +304,13 @@ module OpenTox
|
|
257
304
|
end
|
258
305
|
|
259
306
|
# Save model at model service
|
260
|
-
def save
|
261
|
-
self.uri = RestClientWrapper.post(@uri,{:content_type => "application/x-yaml"}
|
307
|
+
def save(subjectid)
|
308
|
+
self.uri = RestClientWrapper.post(@uri,self.to_yaml,{:content_type => "application/x-yaml", :subjectid => subjectid})
|
262
309
|
end
|
263
310
|
|
264
311
|
# Delete model at model service
|
265
|
-
def delete
|
266
|
-
RestClientWrapper.delete
|
312
|
+
def delete(subjectid)
|
313
|
+
RestClientWrapper.delete(@uri, :subjectid => subjectid) unless @uri == CONFIG[:services]["opentox-model"]
|
267
314
|
end
|
268
315
|
|
269
316
|
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module OpenTox
|
2
|
+
module OntologyService
|
3
|
+
module Endpoints
|
4
|
+
require 'sparql/client'
|
5
|
+
@sparql = SPARQL::Client.new("http://apps.ideaconsult.net:8080/ontology")
|
6
|
+
def self.qs(classname="Endpoints")
|
7
|
+
return "PREFIX ot:<http://www.opentox.org/api/1.1#>
|
8
|
+
PREFIX ota:<http://www.opentox.org/algorithms.owl#>
|
9
|
+
PREFIX owl:<http://www.w3.org/2002/07/owl#>
|
10
|
+
PREFIX dc:<http://purl.org/dc/elements/1.1/>
|
11
|
+
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
|
12
|
+
PREFIX rdf:<http://www.w3.org/1999/02/22-rdf-syntax-ns#>
|
13
|
+
PREFIX otee:<http://www.opentox.org/echaEndpoints.owl#>
|
14
|
+
PREFIX toxcast:<http://www.opentox.org/toxcast.owl#>
|
15
|
+
select ?Endpoints ?title ?id
|
16
|
+
where {?Endpoints rdfs:subClassOf otee:#{classname}.
|
17
|
+
OPTIONAL {?Endpoints dc:title ?title}.
|
18
|
+
OPTIONAL {?Endpoints dc:identifier ?id}.}
|
19
|
+
ORDER BY ?title"
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.make_option_list(endpoint="Endpoints", level=1)
|
23
|
+
out = ""
|
24
|
+
results = @sparql.query(qs(endpoint)) rescue results = []
|
25
|
+
results.each do |result|
|
26
|
+
endpointname = result.Endpoints.to_s.split('#').last
|
27
|
+
title = result.bound?(:title) ? result.title : endpointname
|
28
|
+
out += "<option value='#{title}' id='#{endpointname}' class='level_#{level}'>#{title}</option>\n"
|
29
|
+
out += make_option_list(endpointname, level + 1)
|
30
|
+
end
|
31
|
+
return out
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.get_endpoint_selectlist(include_blank=true)
|
35
|
+
out = "<select id='endpoint' name='endpoint'>\n"
|
36
|
+
out += "<option value='' id='please_select'>Please select</option>\n" if include_blank
|
37
|
+
out += make_option_list
|
38
|
+
out += "</select>\n"
|
39
|
+
return out
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/lib/opentox-ruby.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
['rubygems', 'sinatra', 'sinatra/url_for', 'rest_client', 'yaml', 'cgi', 'spork', 'overwrite', 'environment'].each do |lib|
|
1
|
+
['rubygems', 'sinatra', 'sinatra/url_for', 'ohm', 'rest_client', 'yaml', 'cgi', 'spork', 'error', 'overwrite', 'environment'].each do |lib|
|
2
2
|
require lib
|
3
3
|
end
|
4
4
|
|
@@ -8,6 +8,7 @@ rescue LoadError
|
|
8
8
|
puts "Please install Openbabel with 'rake openbabel:install' in the compound component"
|
9
9
|
end
|
10
10
|
|
11
|
-
['opentox', 'compound','dataset', 'parser','serializer', 'algorithm','model','task','validation','feature',
|
11
|
+
['opentox', 'compound','dataset', 'parser','serializer', 'algorithm','model','task','validation','feature',
|
12
|
+
'rest_client_wrapper', 'authorization', 'policy', 'helper', 'to-html' ].each do |lib|
|
12
13
|
require lib
|
13
14
|
end
|
data/lib/opentox.rb
CHANGED
@@ -19,14 +19,14 @@ module OpenTox
|
|
19
19
|
|
20
20
|
# Get all objects from a service
|
21
21
|
# @return [Array] List of available URIs
|
22
|
-
def self.all(uri)
|
23
|
-
RestClientWrapper.get(uri,:accept => "text/uri-list").to_s.split(/\n/)
|
22
|
+
def self.all(uri, subjectid=nil)
|
23
|
+
RestClientWrapper.get(uri,:accept => "text/uri-list", :subjectid => subjectid).to_s.split(/\n/)
|
24
24
|
end
|
25
25
|
|
26
26
|
# Load (and return) metadata from object URI
|
27
27
|
# @return [Hash] Metadata
|
28
|
-
def load_metadata
|
29
|
-
@metadata = Parser::Owl::Generic.new(@uri).load_metadata
|
28
|
+
def load_metadata(subjectid=nil)
|
29
|
+
@metadata = Parser::Owl::Generic.new(@uri).load_metadata(subjectid)
|
30
30
|
@metadata
|
31
31
|
end
|
32
32
|
|
@@ -43,5 +43,10 @@ module OpenTox
|
|
43
43
|
s.to_rdfxml
|
44
44
|
end
|
45
45
|
|
46
|
+
# deletes the resource, deletion should have worked when no RestCallError raised
|
47
|
+
def delete(subjectid=nil)
|
48
|
+
RestClientWrapper.delete(uri,:subjectid => subjectid)
|
49
|
+
end
|
50
|
+
|
46
51
|
end
|
47
52
|
|
data/lib/overwrite.rb
CHANGED
@@ -1,38 +1,91 @@
|
|
1
1
|
# class overwrites aka monkey patches
|
2
|
-
# hack: store sinatra in global var to make url_for and halt methods accessible
|
3
|
-
before{
|
2
|
+
# hack: store sinatra instance in global var $url_provider to make url_for and halt methods accessible
|
3
|
+
before {
|
4
|
+
raise "should not happen, url provider already differently initialized "+
|
5
|
+
$url_provider.request.host.to_s+" != "+self.request.host.to_s if
|
6
|
+
$url_provider and $url_provider.request.host!=self.request.host and
|
7
|
+
$url_provider.request.script_name!=self.request.script_name
|
8
|
+
$url_provider = self
|
9
|
+
# stupid internet explorer does not ask for text/html, add this manually
|
10
|
+
request.env['HTTP_ACCEPT'] += ";text/html" if request.env["HTTP_USER_AGENT"]=~/MSIE/
|
11
|
+
}
|
12
|
+
|
13
|
+
# Error handling
|
14
|
+
# Errors are logged as error and formated according to acccept-header
|
15
|
+
# Non OpenTox::Errors (defined in error.rb) are handled as internal error (500), stacktrace is logged
|
16
|
+
# IMPT: set sinatra settings :show_exceptions + :raise_errors to false in config.ru, otherwise Rack::Showexceptions takes over
|
17
|
+
error Exception do
|
18
|
+
error = request.env['sinatra.error']
|
19
|
+
# log error message and backtrace to logfile
|
20
|
+
LOGGER.error error.class.to_s+": "+error.message
|
21
|
+
LOGGER.error ":\n"+error.backtrace.join("\n")
|
22
|
+
|
23
|
+
actor = "#{request.env['rack.url_scheme']}://#{request.env['HTTP_HOST']}#{request.env['REQUEST_URI']}"
|
24
|
+
rep = OpenTox::ErrorReport.create(error, actor)
|
25
|
+
|
26
|
+
case request.env['HTTP_ACCEPT']
|
27
|
+
when /rdf/
|
28
|
+
content_type 'application/rdf+xml'
|
29
|
+
halt error.http_code,rep.to_rdfxml
|
30
|
+
when /html/
|
31
|
+
content_type 'text/html'
|
32
|
+
halt error.http_code,(OpenTox.text_to_html rep.to_yaml, @subjectid)
|
33
|
+
else
|
34
|
+
content_type 'application/x-yaml'
|
35
|
+
halt error.http_code,rep.to_yaml
|
36
|
+
end
|
37
|
+
end
|
4
38
|
|
5
39
|
class Sinatra::Base
|
6
|
-
|
7
|
-
def
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
40
|
+
|
41
|
+
def return_task( task )
|
42
|
+
code = task.running? ? 202 : 200
|
43
|
+
case request.env['HTTP_ACCEPT']
|
44
|
+
when /rdf/
|
45
|
+
response['Content-Type'] = "application/rdf+xml"
|
46
|
+
halt code,task.to_rdfxml
|
47
|
+
when /yaml/
|
48
|
+
response['Content-Type'] = "application/x-yaml"
|
49
|
+
halt code,task.to_yaml # PENDING differs from task-webservice
|
50
|
+
when /html/
|
51
|
+
response['Content-Type'] = "text/html"
|
52
|
+
halt code,OpenTox.text_to_html(task.to_yaml, @subjectid)
|
53
|
+
else # default /uri-list/
|
54
|
+
response['Content-Type'] = "text/uri-list"
|
55
|
+
halt code,task.uri+"\n"
|
56
|
+
end
|
12
57
|
end
|
13
58
|
end
|
14
59
|
|
15
60
|
class String
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
61
|
+
def task_uri?
|
62
|
+
self.uri? && !self.match(/task/).nil?
|
63
|
+
end
|
64
|
+
|
65
|
+
def dataset_uri?
|
66
|
+
self.uri? && !self.match(/dataset/).nil?
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.model_uri?
|
70
|
+
self.uri? && !self.match(/model/).nil?
|
71
|
+
end
|
27
72
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
end
|
73
|
+
def uri?
|
74
|
+
begin
|
75
|
+
u = URI::parse(self)
|
76
|
+
return (u.scheme!=nil and u.host!=nil)
|
77
|
+
rescue URI::InvalidURIError
|
78
|
+
return false
|
35
79
|
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def underscore
|
83
|
+
self.gsub(/::/, '/').
|
84
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
85
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
86
|
+
tr("-", "_").
|
87
|
+
downcase
|
88
|
+
end
|
36
89
|
end
|
37
90
|
|
38
91
|
require 'logger'
|
@@ -52,7 +105,7 @@ class OTLogger < Logger
|
|
52
105
|
n = 2
|
53
106
|
line = lines[n]
|
54
107
|
|
55
|
-
while (line =~ /spork.rb/ or line =~ /create/ or line =~ /
|
108
|
+
while (line =~ /spork.rb/ or line =~ /create/ or line =~ /overwrite.rb/)
|
56
109
|
n += 1
|
57
110
|
line = lines[n]
|
58
111
|
end
|
@@ -63,7 +116,7 @@ class OTLogger < Logger
|
|
63
116
|
end
|
64
117
|
|
65
118
|
def format(msg)
|
66
|
-
pwd.ljust(18)+" :: "+msg.to_s+" :: "+trace
|
119
|
+
pwd.ljust(18)+" :: "+msg.to_s+" :: "+trace
|
67
120
|
end
|
68
121
|
|
69
122
|
def debug(msg)
|
@@ -84,3 +137,9 @@ class OTLogger < Logger
|
|
84
137
|
|
85
138
|
end
|
86
139
|
|
140
|
+
# make migration from datamapper more straightforward
|
141
|
+
class Ohm::Model
|
142
|
+
def self.get(id)
|
143
|
+
self[id]
|
144
|
+
end
|
145
|
+
end
|