opentox-ruby-api-wrapper 1.4.0 → 1.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +2 -2
- data/VERSION +1 -1
- data/bin/opentox-install-ubuntu.sh +2 -2
- data/bin/yaml2owl.rb +1 -1
- data/lib/algorithm.rb +4 -1
- data/lib/compound.rb +4 -4
- data/lib/config/config_ru.rb +8 -0
- data/lib/dataset.rb +162 -158
- data/lib/environment.rb +77 -6
- data/lib/features.rb +15 -0
- data/lib/model.rb +88 -103
- data/lib/opentox-ruby-api-wrapper.rb +1 -1
- data/lib/owl.rb +386 -149
- data/lib/rest_client_wrapper.rb +170 -0
- data/lib/spork.rb +2 -0
- data/lib/task.rb +148 -75
- data/lib/templates/config.yaml +53 -5
- data/lib/utils.rb +34 -2
- data/lib/validation.rb +10 -2
- metadata +97 -62
data/Rakefile
CHANGED
@@ -10,10 +10,10 @@ begin
|
|
10
10
|
gem.email = "helma@in-silico.ch"
|
11
11
|
gem.homepage = "http://github.com/helma/opentox-ruby-api-wrapper"
|
12
12
|
gem.authors = ["Christoph Helma"]
|
13
|
-
["sinatra", "rest-client", "rack", "rack-contrib", "rack-flash", "emk-sinatra-url-for", "
|
13
|
+
["sinatra", "rest-client", "rack", "rack-contrib", "rack-flash", "emk-sinatra-url-for", "sinatra-respond_to", "dm-more", "dm-core", "sinatra-static-assets","tmail"].each do |dep|
|
14
14
|
gem.add_dependency dep
|
15
15
|
end
|
16
|
-
['cucumber','jeweler'
|
16
|
+
['cucumber','jeweler'].each do |dep|
|
17
17
|
gem.add_development_dependency dep
|
18
18
|
end
|
19
19
|
gem.files = FileList["[A-Z]*", "{bin,generators,lib,test}/**/*", 'lib/jeweler/templates/.gitignore']
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.5.0
|
@@ -90,9 +90,9 @@ sudo apt-get install postgresql-server-dev-8.4 | tee -a $INSTALLLOG
|
|
90
90
|
#echo "Installing gems jeweler sinatra emk-sinatra-url-for dm-core cehoffman-sinatra-respond_to rest-client rack-contrib thin cucumber datamapper data_objects do_sqlite3 rinruby"
|
91
91
|
sudo gem install jeweler | tee -a $INSTALLLOG
|
92
92
|
sudo gem install sinatra | tee -a $INSTALLLOG
|
93
|
-
sudo gem install
|
93
|
+
sudo gem install sinatra-url-for | tee -a $INSTALLLOG
|
94
94
|
sudo gem install dm-core | tee -a $INSTALLLOG
|
95
|
-
sudo gem install
|
95
|
+
sudo gem install sinatra-respond_to | tee -a $INSTALLLOG
|
96
96
|
sudo gem install rest-client | tee -a $INSTALLLOG
|
97
97
|
sudo gem install rack-contrib | tee -a $INSTALLLOG
|
98
98
|
sudo gem install thin | tee -a $INSTALLLOG
|
data/bin/yaml2owl.rb
CHANGED
@@ -5,7 +5,7 @@ require 'opentox-ruby-api-wrapper'
|
|
5
5
|
input = YAML.load_file(ARGV[0])
|
6
6
|
dataset = OpenTox::Dataset.new
|
7
7
|
dataset.title = input[:title]
|
8
|
-
dataset.
|
8
|
+
dataset.creator = input[:source]
|
9
9
|
input[:data].each do |c,f|
|
10
10
|
f.each do |k,v|
|
11
11
|
v.each do |value|
|
data/lib/algorithm.rb
CHANGED
@@ -21,8 +21,11 @@ module OpenTox
|
|
21
21
|
def self.create_model(params)
|
22
22
|
LOGGER.debug params
|
23
23
|
LOGGER.debug File.basename(__FILE__) + ": creating model"
|
24
|
+
LOGGER.debug File.join(@@config[:services]["opentox-algorithm"], "lazar")
|
25
|
+
#resource = RestClient::Resource.new(File.join(@@config[:services]["opentox-algorithm"], "lazar"), :user => @@users[:users].keys[0], :password => @@users[:users].values[0], :content_type => "application/x-yaml")
|
24
26
|
resource = RestClient::Resource.new(File.join(@@config[:services]["opentox-algorithm"], "lazar"), :user => @@users[:users].keys[0], :password => @@users[:users].values[0], :content_type => "application/x-yaml")
|
25
|
-
|
27
|
+
#@uri = resource.post(:dataset_uri => params[:dataset_uri], :feature_uri => params[:feature_uri], :feature_generation_uri => File.join(@@config[:services]["opentox-algorithm"], "fminer")).chomp
|
28
|
+
@uri = resource.post(:dataset_uri => params[:dataset_uri], :prediction_feature => params[:prediction_feature], :feature_generation_uri => File.join(@@config[:services]["opentox-algorithm"], "fminer")).body.chomp
|
26
29
|
end
|
27
30
|
|
28
31
|
def self.uri
|
data/lib/compound.rb
CHANGED
@@ -18,18 +18,18 @@ module OpenTox
|
|
18
18
|
@uri = File.join(@@config[:services]["opentox-compound"],URI.escape(@inchi))
|
19
19
|
elsif params[:name]
|
20
20
|
# paranoid URI encoding to keep SMILES charges and brackets
|
21
|
-
@inchi =
|
21
|
+
@inchi = RestClientWrapper.get("#{@@cactus_uri}#{URI.encode(params[:name], Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))}/stdinchi").chomp
|
22
22
|
@uri = File.join(@@config[:services]["opentox-compound"],URI.escape(@inchi))
|
23
23
|
elsif params[:uri]
|
24
24
|
@uri = params[:uri]
|
25
25
|
case params[:uri]
|
26
26
|
when /ambit/ # Ambit does not deliver InChIs reliably
|
27
|
-
smiles =
|
27
|
+
smiles = RestClientWrapper.get @uri, :accept => 'chemical/x-daylight-smiles'
|
28
28
|
@inchi = obconversion(smiles,'smi','inchi')
|
29
29
|
when /InChI/ # shortcut for IST services
|
30
30
|
@inchi = params[:uri].sub(/^.*InChI/, 'InChI')
|
31
31
|
else
|
32
|
-
@inchi =
|
32
|
+
@inchi = RestClientWrapper.get @uri, :accept => 'chemical/x-inchi'
|
33
33
|
end
|
34
34
|
end
|
35
35
|
end
|
@@ -44,7 +44,7 @@ module OpenTox
|
|
44
44
|
end
|
45
45
|
|
46
46
|
def image
|
47
|
-
|
47
|
+
RestClientWrapper.get("#{@@cactus_uri}#{@inchi}/image")
|
48
48
|
end
|
49
49
|
|
50
50
|
def image_uri
|
data/lib/config/config_ru.rb
CHANGED
data/lib/dataset.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
LOGGER.progname = File.expand_path(__FILE__)
|
2
2
|
|
3
3
|
module OpenTox
|
4
|
-
|
4
|
+
|
5
5
|
class Dataset
|
6
6
|
|
7
|
-
attr_accessor :uri, :title, :
|
7
|
+
attr_accessor :uri, :title, :creator, :data, :features, :compounds
|
8
8
|
|
9
9
|
def initialize
|
10
10
|
@data = {}
|
@@ -12,171 +12,175 @@ module OpenTox
|
|
12
12
|
@compounds = []
|
13
13
|
end
|
14
14
|
|
15
|
-
def self.find(uri)
|
16
|
-
|
15
|
+
def self.find(uri, accept_header=nil)
|
16
|
+
|
17
|
+
unless accept_header
|
18
|
+
#if uri.match(@@config[:services]["opentox-dataset"]) || uri=~ /188.40.32.88/ || uri =~ /informatik/
|
19
|
+
if !@@config[:accept_headers]["opentox-dataset"].grep(/yaml/).empty?
|
20
|
+
accept_header = 'application/x-yaml'
|
21
|
+
else
|
22
|
+
accept_header = "application/rdf+xml"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
case accept_header
|
27
|
+
when "application/x-yaml"
|
28
|
+
d = YAML.load RestClientWrapper.get(uri.to_s.strip, :accept => 'application/x-yaml').to_s
|
29
|
+
d.uri = uri unless d.uri
|
30
|
+
when "application/rdf+xml"
|
31
|
+
owl = OpenTox::Owl.from_uri(uri.to_s.strip, "Dataset")
|
32
|
+
|
33
|
+
d = Dataset.new
|
34
|
+
d.title = owl.get("title")
|
35
|
+
d.creator = owl.get("creator")
|
36
|
+
d.uri = owl.uri
|
37
|
+
|
38
|
+
# when loading a dataset from owl, only compound- and feature-uris are loaded
|
39
|
+
owl.load_dataset(d.compounds, d.features)
|
40
|
+
# all features are marked as dirty, loaded dynamically later
|
41
|
+
d.init_dirty_features(owl)
|
42
|
+
|
43
|
+
d.compounds.uniq!
|
44
|
+
d.features.uniq!
|
45
|
+
else
|
46
|
+
raise "cannot get datset with accept header: "+accept_header.to_s
|
47
|
+
end
|
48
|
+
return d
|
17
49
|
end
|
50
|
+
|
51
|
+
# creates a new dataset, using only those compounsd specified in new_compounds
|
52
|
+
# returns uri of new dataset
|
53
|
+
def create_new_dataset( new_compounds, new_features, new_title, new_creator )
|
54
|
+
|
55
|
+
raise "no new compounds selected" unless new_compounds and new_compounds.size>0
|
56
|
+
|
57
|
+
# load require features
|
58
|
+
if ((defined? @dirty_features) && (@dirty_features - new_features).size > 0)
|
59
|
+
(@dirty_features - new_features).each{|f| load_feature_values(f)}
|
60
|
+
end
|
61
|
+
|
62
|
+
dataset = OpenTox::Dataset.new
|
63
|
+
dataset.title = new_title
|
64
|
+
dataset.creator = new_creator
|
65
|
+
dataset.features = new_features
|
66
|
+
dataset.compounds = new_compounds
|
67
|
+
|
68
|
+
# Copy dataset data for compounds and features
|
69
|
+
# PENDING: why storing feature values in an array?
|
70
|
+
new_compounds.each do |c|
|
71
|
+
data_c = []
|
72
|
+
@data[c].each do |d|
|
73
|
+
m = {}
|
74
|
+
new_features.each do |f|
|
75
|
+
m[f] = d[f]
|
76
|
+
end
|
77
|
+
data_c << m
|
78
|
+
end
|
79
|
+
|
80
|
+
dataset.data[c] = data_c
|
81
|
+
end
|
82
|
+
return dataset.save
|
83
|
+
end
|
84
|
+
|
85
|
+
# returns classification value
|
86
|
+
def get_predicted_class(compound, feature)
|
87
|
+
v = get_value(compound, feature)
|
88
|
+
if v.is_a?(Hash)
|
89
|
+
if v.has_key?(:classification)
|
90
|
+
return v[:classification]
|
91
|
+
else
|
92
|
+
return "no classification key"
|
93
|
+
end
|
94
|
+
else
|
95
|
+
raise "predicted class value is not a hash\n"+
|
96
|
+
"value "+v.to_s+"\n"+
|
97
|
+
"value-class "+v.class.to_s+"\n"+
|
98
|
+
"dataset "+@uri.to_s+"\n"+
|
99
|
+
"compound "+compound.to_s+"\n"+
|
100
|
+
"feature "+feature.to_s+"\n"
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
|
105
|
+
# returns prediction confidence if available
|
106
|
+
def get_prediction_confidence(compound, feature)
|
107
|
+
v = get_value(compound, feature)
|
108
|
+
if v.is_a?(Hash)
|
109
|
+
if v.has_key?(:confidence)
|
110
|
+
return v[:confidence].abs
|
111
|
+
else
|
112
|
+
# PENDING: return nil isntead of raising an exception
|
113
|
+
raise "no confidence key"
|
114
|
+
end
|
115
|
+
else
|
116
|
+
raise "prediction confidence value is not a hash value\n"+
|
117
|
+
"value "+v.to_s+"\n"+
|
118
|
+
"value-class "+v.class.to_s+"\n"+
|
119
|
+
"dataset "+@uri.to_s+"\n"+
|
120
|
+
"compound "+compound.to_s+"\n"+
|
121
|
+
"feature "+feature.to_s+"\n"
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
# return compound-feature value
|
126
|
+
def get_value(compound, feature)
|
127
|
+
if (defined? @dirty_features) && @dirty_features.include?(feature)
|
128
|
+
load_feature_values(feature)
|
129
|
+
end
|
130
|
+
|
131
|
+
v = @data[compound]
|
132
|
+
raise "no values for compound "+compound.to_s if v==nil
|
133
|
+
if v.is_a?(Array)
|
134
|
+
# PENDING: why using an array here?
|
135
|
+
v.each do |e|
|
136
|
+
if e.is_a?(Hash)
|
137
|
+
if e.has_key?(feature)
|
138
|
+
return e[feature]
|
139
|
+
end
|
140
|
+
else
|
141
|
+
raise "invalid internal value type"
|
142
|
+
end
|
143
|
+
end
|
144
|
+
raise "feature value no found: "+feature.to_s
|
145
|
+
else
|
146
|
+
raise "value is not an array\n"+
|
147
|
+
"value "+v.to_s+"\n"+
|
148
|
+
"value-class "+v.class.to_s+"\n"+
|
149
|
+
"dataset "+@uri.to_s+"\n"+
|
150
|
+
"compound "+compound.to_s+"\n"+
|
151
|
+
"feature "+feature.to_s+"\n"
|
152
|
+
end
|
153
|
+
end
|
18
154
|
|
155
|
+
# loads specified feature and removes dirty-flag, loads all features if feature is nil
|
156
|
+
def load_feature_values(feature=nil)
|
157
|
+
if feature
|
158
|
+
raise "feature already loaded" unless @dirty_features.include?(feature)
|
159
|
+
@owl.load_dataset_feature_values(@compounds, @data, feature)
|
160
|
+
@dirty_features.delete(feature)
|
161
|
+
else
|
162
|
+
@data = {}
|
163
|
+
@owl.load_dataset_feature_values(@compounds, @data)
|
164
|
+
@dirty_features.clear
|
165
|
+
end
|
166
|
+
end
|
19
167
|
|
20
168
|
def save
|
169
|
+
# loads all features before loading
|
170
|
+
if ((defined? @dirty_features) && @dirty_features.size > 0)
|
171
|
+
load_feature_values()
|
172
|
+
end
|
173
|
+
|
21
174
|
@features.uniq!
|
22
175
|
@compounds.uniq!
|
23
|
-
|
24
|
-
end
|
25
|
-
|
26
|
-
=begin
|
27
|
-
# create/add to entry from uris or Redland::Resources
|
28
|
-
def add(compound,feature,value)
|
29
|
-
compound = self.find_or_create_compound compound unless compound.class == Redland::Resource
|
30
|
-
feature = self.find_or_create_feature feature unless feature.class == Redland::Resource
|
31
|
-
data_entry = @model.subject OT['compound'], compound
|
32
|
-
if data_entry.nil?
|
33
|
-
data_entry = @model.create_resource
|
34
|
-
dataset = @model.subject(RDF['type'],OT[self.owl_class])
|
35
|
-
@model.add dataset, OT['dataEntry'], data_entry
|
36
|
-
@model.add data_entry, RDF['type'], OT["DataEntry"]
|
37
|
-
@model.add data_entry, OT['compound'], compound
|
38
|
-
end
|
39
|
-
values = @model.create_resource
|
40
|
-
@model.add data_entry, OT['values'], values
|
41
|
-
@model.add values, RDF['type'], OT['FeatureValue']
|
42
|
-
@model.add values, OT['feature'], feature
|
43
|
-
@model.add values, OT['value'], value.to_s
|
44
|
-
end
|
45
|
-
|
46
|
-
def add_tuple(compound,tuple)
|
47
|
-
compound = self.find_or_create_compound compound unless compound.class == Redland::Resource
|
48
|
-
data_entry = @model.subject OT['compound'], compound
|
49
|
-
if data_entry.nil?
|
50
|
-
data_entry = @model.create_resource
|
51
|
-
dataset = @model.subject(RDF['type'],OT[self.owl_class])
|
52
|
-
@model.add dataset, OT['dataEntry'], data_entry
|
53
|
-
@model.add data_entry, RDF['type'], OT["DataEntry"]
|
54
|
-
@model.add data_entry, OT['compound'], compound
|
55
|
-
end
|
56
|
-
@model.add data_entry, OT['values'], tuple
|
176
|
+
OpenTox::RestClientWrapper.post(@@config[:services]["opentox-dataset"],{:content_type => "application/x-yaml"},self.to_yaml).strip
|
57
177
|
end
|
58
178
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
@model.add tuple, RDF['type'], OT["Tuple"]
|
63
|
-
@model.add tuple, OT['feature'], feature
|
64
|
-
t.each do |name,value|
|
65
|
-
f = self.find_or_create_feature name unless name.class == Redland::Resource
|
66
|
-
complex_value = @model.create_resource
|
67
|
-
feature = self.find_or_create_feature(name)
|
68
|
-
@model.add tuple, OT['complexValue'], complex_value
|
69
|
-
@model.add complex_value, RDF['type'], OT["FeatureValue"]
|
70
|
-
@model.add complex_value, OT['feature'], f
|
71
|
-
@model.add complex_value, OT['value'], value.to_s
|
72
|
-
end
|
73
|
-
|
74
|
-
tuple
|
75
|
-
end
|
76
|
-
|
77
|
-
# find or create a new compound and return the resource
|
78
|
-
def find_or_create_compound(uri)
|
79
|
-
compound = @model.subject(DC["identifier"], uri)
|
80
|
-
if compound.nil?
|
81
|
-
compound = @model.create_resource(uri)
|
82
|
-
@model.add compound, RDF['type'], OT["Compound"]
|
83
|
-
@model.add compound, DC["identifier"], uri
|
84
|
-
end
|
85
|
-
compound
|
86
|
-
end
|
87
|
-
|
88
|
-
# find or create a new feature and return the resource
|
89
|
-
def find_or_create_feature(uri)
|
90
|
-
feature = @model.subject(DC["identifier"], uri)
|
91
|
-
if feature.nil?
|
92
|
-
feature = @model.create_resource(uri)
|
93
|
-
@model.add feature, RDF['type'], OT["Feature"]
|
94
|
-
@model.add feature, DC["identifier"], uri
|
95
|
-
@model.add feature, DC["title"], File.basename(uri).split(/#/)[1]
|
96
|
-
@model.add feature, DC['source'], uri
|
97
|
-
end
|
98
|
-
feature
|
99
|
-
end
|
100
|
-
|
101
|
-
def self.create(data, content_type = 'application/rdf+xml')
|
102
|
-
resource = RestClient::Resource.new(@@config[:services]["opentox-dataset"], :user => @@users[:users].keys[0], :password => @@users[:users].values[0])
|
103
|
-
uri = resource.post data, :content_type => content_type
|
104
|
-
dataset = Dataset.new
|
105
|
-
dataset.read uri.chomp.to_s
|
106
|
-
dataset
|
107
|
-
end
|
108
|
-
|
109
|
-
def features
|
110
|
-
features = []
|
111
|
-
@model.subjects(RDF['type'], OT["Feature"]).each do |feature_node|
|
112
|
-
features << @model.object(feature_node, DC["identifier"])#
|
113
|
-
end
|
114
|
-
features
|
115
|
-
end
|
116
|
-
|
117
|
-
def data
|
118
|
-
data = {}
|
119
|
-
@model.subjects(RDF['type'], OT['DataEntry']).each do |data_entry|
|
120
|
-
compound_node = @model.object(data_entry, OT['compound'])
|
121
|
-
compound_uri = @model.object(compound_node, DC['identifier']).to_s
|
122
|
-
@model.find(data_entry, OT['values'], nil) do |s,p,values|
|
123
|
-
feature_node = @model.object values, OT['feature']
|
124
|
-
feature_uri = @model.object(feature_node, DC['identifier']).to_s.sub(/\^\^.*$/,'') # remove XML datatype
|
125
|
-
type = @model.object(values, RDF['type'])
|
126
|
-
if type == OT['FeatureValue']
|
127
|
-
value = @model.object(values, OT['value']).to_s
|
128
|
-
case value.to_s
|
129
|
-
when TRUE_REGEXP # defined in environment.rb
|
130
|
-
value = true
|
131
|
-
when FALSE_REGEXP # defined in environment.rb
|
132
|
-
value = false
|
133
|
-
else
|
134
|
-
LOGGER.warn compound_uri + " has value '" + value.to_s + "' for feature " + feature_uri
|
135
|
-
value = nil
|
136
|
-
end
|
137
|
-
data[compound_uri] = {} unless data[compound_uri]
|
138
|
-
data[compound_uri][feature_uri] = [] unless data[compound_uri][feature_uri]
|
139
|
-
data[compound_uri][feature_uri] << value unless value.nil?
|
140
|
-
elsif type == OT['Tuple']
|
141
|
-
entry = {}
|
142
|
-
data[compound_uri] = {} unless data[compound_uri]
|
143
|
-
data[compound_uri][feature_uri] = [] unless data[compound_uri][feature_uri]
|
144
|
-
@model.find(values, OT['complexValue'],nil) do |s,p,complex_value|
|
145
|
-
name_node = @model.object complex_value, OT['feature']
|
146
|
-
name = @model.object(name_node, DC['title']).to_s
|
147
|
-
value = @model.object(complex_value, OT['value']).to_s
|
148
|
-
v = value.sub(/\^\^.*$/,'') # remove XML datatype
|
149
|
-
v = v.to_f if v.match(/^[\.|\d]+$/) # guess numeric datatype
|
150
|
-
entry[name] = v
|
151
|
-
end
|
152
|
-
data[compound_uri][feature_uri] << entry
|
153
|
-
end
|
154
|
-
end
|
155
|
-
end
|
156
|
-
data
|
157
|
-
end
|
158
|
-
|
159
|
-
def compounds
|
160
|
-
compounds = []
|
161
|
-
@model.subjects(RDF['type'], OT["Compound"]).each do |compound_node|
|
162
|
-
compounds << @model.object(compound_node, DC["identifier"]).to_s
|
163
|
-
end
|
164
|
-
compounds
|
165
|
-
end
|
166
|
-
|
167
|
-
# Delete a dataset
|
168
|
-
def delete
|
169
|
-
resource = RestClient::Resource.new(@uri, :user => @@users[:users].keys[0], :password => @@users[:users].values[0])
|
170
|
-
resource.delete
|
179
|
+
def init_dirty_features(owl)
|
180
|
+
@dirty_features = @features
|
181
|
+
@owl = owl
|
171
182
|
end
|
183
|
+
end
|
172
184
|
|
173
|
-
def to_owl
|
174
|
-
end
|
175
|
-
|
176
|
-
def from_owl
|
177
|
-
end
|
178
|
-
|
179
|
-
=end
|
180
|
-
end
|
181
185
|
|
182
186
|
end
|
data/lib/environment.rb
CHANGED
@@ -40,10 +40,77 @@ if @@config[:database]
|
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
+
# mail for error messages
|
44
|
+
load File.join config_dir,"mail.rb" if File.exists?(File.join config_dir,"mail.rb")
|
45
|
+
|
46
|
+
# hack: store sinatra in global var to make url_for and halt methods accessible
|
47
|
+
before {$sinatra = self unless $sinatra}
|
48
|
+
|
49
|
+
class Sinatra::Base
|
50
|
+
# overwriting halt to log halts (!= 202)
|
51
|
+
def halt(*response)
|
52
|
+
LOGGER.error "halt "+response.first.to_s+" "+(response.size>1 ? response[1].to_s : "") if response and response.first and response.first >= 300
|
53
|
+
# orig sinatra code:
|
54
|
+
response = response.first if response.length == 1
|
55
|
+
throw :halt, response
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
43
59
|
# logging
|
60
|
+
class MyLogger < Logger
|
61
|
+
|
62
|
+
def pwd
|
63
|
+
path = Dir.pwd.to_s
|
64
|
+
index = path.rindex(/\//)
|
65
|
+
return path if index==nil
|
66
|
+
path[(index+1)..-1]
|
67
|
+
end
|
68
|
+
|
69
|
+
def trace()
|
70
|
+
lines = caller(0)
|
71
|
+
n = 2
|
72
|
+
line = lines[n]
|
73
|
+
|
74
|
+
while (line =~ /spork.rb/ or line =~ /as_task/ or line =~ /environment.rb/)
|
75
|
+
n += 1
|
76
|
+
line = lines[n]
|
77
|
+
end
|
78
|
+
|
79
|
+
index = line.rindex(/\/.*\.rb/)
|
80
|
+
return line if index==nil
|
81
|
+
line[index..-1]
|
82
|
+
end
|
83
|
+
|
84
|
+
def format(msg)
|
85
|
+
pwd.ljust(18)+" :: "+msg.to_s+" :: "+trace+" :: "+ENV['REMOTE_ADDR'].to_s
|
86
|
+
end
|
87
|
+
|
88
|
+
def debug(msg)
|
89
|
+
super format(msg)
|
90
|
+
end
|
91
|
+
|
92
|
+
def info(msg)
|
93
|
+
super format(msg)
|
94
|
+
end
|
95
|
+
|
96
|
+
def warn(msg)
|
97
|
+
super format(msg)
|
98
|
+
end
|
99
|
+
|
100
|
+
def error(msg)
|
101
|
+
super format(msg)
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
|
44
107
|
logfile = "#{LOG_DIR}/#{ENV["RACK_ENV"]}.log"
|
45
|
-
LOGGER =
|
46
|
-
|
108
|
+
LOGGER = MyLogger.new(logfile,'daily') # daily rotation
|
109
|
+
|
110
|
+
#LOGGER = MyLogger.new(STDOUT)
|
111
|
+
#LOGGER.datetime_format = "%Y-%m-%d %H:%M:%S "
|
112
|
+
|
113
|
+
#LOGGER.level = Logger::DEBUG
|
47
114
|
|
48
115
|
if File.exist?(user_file)
|
49
116
|
@@users = YAML.load_file(user_file)
|
@@ -56,8 +123,7 @@ end
|
|
56
123
|
begin
|
57
124
|
0 < @@users[:users].keys.length
|
58
125
|
rescue
|
59
|
-
|
60
|
-
exit
|
126
|
+
raise "Please edit #{user_file} and restart your application. Create at least one user with password."
|
61
127
|
end
|
62
128
|
|
63
129
|
# RDF namespaces
|
@@ -65,7 +131,12 @@ RDF = Redland::Namespace.new 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'
|
|
65
131
|
OWL = Redland::Namespace.new 'http://www.w3.org/2002/07/owl#'
|
66
132
|
DC = Redland::Namespace.new 'http://purl.org/dc/elements/1.1/'
|
67
133
|
OT = Redland::Namespace.new 'http://www.opentox.org/api/1.1#'
|
134
|
+
XML = Redland::Namespace.new 'http://www.w3.org/2001/XMLSchema#'
|
68
135
|
|
69
136
|
# Regular expressions for parsing classification data
|
70
|
-
TRUE_REGEXP = /^(true|active
|
71
|
-
FALSE_REGEXP = /^(false|inactive
|
137
|
+
TRUE_REGEXP = /^(true|active|$1^)/
|
138
|
+
FALSE_REGEXP = /^(false|inactive|$0^)/
|
139
|
+
|
140
|
+
# Task durations
|
141
|
+
DEFAULT_TASK_MAX_DURATION = @@config[:default_task_max_duration]
|
142
|
+
EXTERNAL_TASK_MAX_DURATION = @@config[:external_task_max_duration]
|