opentox-client 0.0.1pre → 0.0.2pre
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +5 -0
- data/lib/authorization.rb +55 -79
- data/lib/dataset.rb +17 -306
- data/lib/error.rb +23 -12
- data/lib/opentox-client.rb +5 -2
- data/lib/opentox.rb +27 -15
- data/lib/overwrite.rb +10 -22
- data/lib/policy.rb +204 -127
- data/lib/rest-client-wrapper.rb +14 -7
- data/lib/task.rb +22 -31
- data/opentox-client.gemspec +5 -1
- data/test/authorization.rb +107 -0
- data/test/dataset.rb +60 -14
- data/test/feature.rb +2 -2
- data/test/policy.rb +120 -0
- data/test/task.rb +5 -5
- metadata +19 -15
data/README.markdown
CHANGED
data/lib/authorization.rb
CHANGED
@@ -1,21 +1,22 @@
|
|
1
1
|
module OpenTox
|
2
|
-
|
2
|
+
AA = $aa[:uri] if defined? $aa
|
3
|
+
AA ||= "https://opensso.in-silico.ch" #if not set in .opentox/conf/[application]/[test].rb
|
3
4
|
#Module for Authorization and Authentication
|
4
5
|
#@example Authentication
|
5
6
|
# require "opentox-client"
|
6
|
-
# OpenTox::Authorization::
|
7
|
-
# token = OpenTox::Authorization.authenticate("
|
7
|
+
# OpenTox::Authorization::AA = "https://opensso.in-silico.ch" #if not set in .opentox/conf/[environment].yaml
|
8
|
+
# token = OpenTox::Authorization.authenticate("username", "password")
|
8
9
|
#@see http://www.opentox.org/dev/apis/api-1.2/AA OpenTox A&A API 1.2 specification
|
9
10
|
|
10
11
|
module Authorization
|
11
12
|
|
12
|
-
#Helper Class
|
13
|
+
#Helper Class to create and send default policies out of xml templates
|
13
14
|
#@example Creating a default policy to a URI
|
14
15
|
# aa=OpenTox::Authorization::AA.new(tok)
|
15
16
|
# xml=aa.get_xml('http://uri....')
|
16
17
|
# OpenTox::Authorization.create_policy(xml,tok)
|
17
18
|
|
18
|
-
class
|
19
|
+
class Helper
|
19
20
|
attr_accessor :user, :subjectid, :policy
|
20
21
|
|
21
22
|
#Generates AA object - requires subjectid
|
@@ -41,27 +42,27 @@ module OpenTox
|
|
41
42
|
xml = get_xml(uri)
|
42
43
|
ret = false
|
43
44
|
ret = Authorization.create_policy(xml, @subjectid)
|
44
|
-
|
45
|
-
|
45
|
+
$logger.warn "Create policy on openSSO failed for URI: #{uri} subjectid: #{@subjectid}. Will try again." if !ret
|
46
|
+
ret = Authorization.create_policy(xml, @subjectid) if !ret
|
47
|
+
$logger.debug "Policy send with subjectid: #{@subjectid}"
|
48
|
+
$logger.error "Not created Policy is: #{xml}" if !ret
|
46
49
|
ret
|
47
50
|
end
|
48
|
-
|
49
51
|
end
|
50
52
|
|
51
53
|
#Returns the open-sso server set in the config file .opentox/config/[environment].yaml
|
52
54
|
# @return [String, nil] the openSSO server URI or nil
|
53
55
|
def self.server
|
54
|
-
return
|
56
|
+
return AA
|
55
57
|
end
|
56
58
|
|
57
59
|
#Authentication against OpenSSO. Returns token. Requires Username and Password.
|
58
60
|
# @param [String, String]Username,Password
|
59
61
|
# @return [String, nil] gives subjectid or nil
|
60
62
|
def self.authenticate(user, pw)
|
61
|
-
return nil if !
|
63
|
+
return nil if !AA
|
62
64
|
begin
|
63
|
-
|
64
|
-
out = resource.post(:username=>user, :password => pw).sub("token.id=","").sub("\n","")
|
65
|
+
out = RestClientWrapper.post("#{AA}/auth/authenticate",{:username=>user, :password => pw}).sub("token.id=","").sub("\n","")
|
65
66
|
return out
|
66
67
|
rescue
|
67
68
|
return nil
|
@@ -73,22 +74,21 @@ module OpenTox
|
|
73
74
|
# @return [Boolean] true if logout is OK
|
74
75
|
def self.logout(subjectid)
|
75
76
|
begin
|
76
|
-
|
77
|
-
|
78
|
-
return true
|
77
|
+
out = RestClientWrapper.post("#{AA}/auth/logout",:subjectid => subjectid)
|
78
|
+
return true unless is_token_valid(subjectid)
|
79
79
|
rescue
|
80
80
|
return false
|
81
81
|
end
|
82
|
+
return false
|
82
83
|
end
|
83
84
|
|
84
85
|
#Authorization against OpenSSO for a URI with request-method (action) [GET/POST/PUT/DELETE]
|
85
86
|
# @param [String,String,String]uri,action,subjectid
|
86
87
|
# @return [Boolean, nil] returns true, false or nil (if authorization-request fails).
|
87
88
|
def self.authorize(uri, action, subjectid)
|
88
|
-
return true if !
|
89
|
+
return true if !AA
|
89
90
|
begin
|
90
|
-
|
91
|
-
return true if resource.post(:uri => uri, :action => action, :subjectid => subjectid) == "boolean=true\n"
|
91
|
+
return true if RestClientWrapper.post("#{AA}/auth/authorize",{:uri => uri, :action => action, :subjectid => subjectid})== "boolean=true\n"
|
92
92
|
rescue
|
93
93
|
return nil
|
94
94
|
end
|
@@ -98,13 +98,13 @@ module OpenTox
|
|
98
98
|
# @param [String]subjectid subjectid from openSSO session
|
99
99
|
# @return [Boolean] subjectid is valid or not.
|
100
100
|
def self.is_token_valid(subjectid)
|
101
|
-
return true if !
|
101
|
+
return true if !AA
|
102
102
|
begin
|
103
|
-
|
104
|
-
return true if resource.post(:tokenid => subjectid) == "boolean=true\n"
|
103
|
+
return true if RestClientWrapper.post("#{AA}/auth/isTokenValid",:tokenid => subjectid) == "boolean=true\n"
|
105
104
|
rescue
|
106
105
|
return false
|
107
106
|
end
|
107
|
+
return false
|
108
108
|
end
|
109
109
|
|
110
110
|
#Returns array with all policies of the token owner
|
@@ -112,11 +112,8 @@ module OpenTox
|
|
112
112
|
# @return [Array, nil] returns an Array of policy names or nil if request fails
|
113
113
|
def self.list_policies(subjectid)
|
114
114
|
begin
|
115
|
-
|
116
|
-
out = resource.get(:subjectid => subjectid)
|
115
|
+
out = RestClientWrapper.get("#{AA}/pol",nil,:subjectid => subjectid)
|
117
116
|
return out.split("\n")
|
118
|
-
rescue RestClient::InternalServerError => e
|
119
|
-
raise e.response
|
120
117
|
rescue
|
121
118
|
return nil
|
122
119
|
end
|
@@ -127,8 +124,7 @@ module OpenTox
|
|
127
124
|
# @return [String] XML of the policy
|
128
125
|
def self.list_policy(policy, subjectid)
|
129
126
|
begin
|
130
|
-
|
131
|
-
return resource.get(:subjectid => subjectid,:id => policy)
|
127
|
+
return RestClientWrapper.get("#{AA}/pol",nil,{:subjectid => subjectid,:id => policy})
|
132
128
|
rescue
|
133
129
|
return nil
|
134
130
|
end
|
@@ -160,8 +156,7 @@ module OpenTox
|
|
160
156
|
# return [String, nil]owner,nil returns owner of the URI
|
161
157
|
def self.get_uri_owner(uri, subjectid)
|
162
158
|
begin
|
163
|
-
|
164
|
-
return resource.get(:uri => uri, :subjectid => subjectid).sub("\n","")
|
159
|
+
return RestClientWrapper.get("#{AA}/pol",nil,{:subjectid => subjectid, :uri => uri}).sub("\n","")
|
165
160
|
rescue
|
166
161
|
return nil
|
167
162
|
end
|
@@ -181,8 +176,7 @@ module OpenTox
|
|
181
176
|
# return [Array, nil] returns an Array of policy names or nil if request fails
|
182
177
|
def self.list_uri_policies(uri, subjectid)
|
183
178
|
begin
|
184
|
-
|
185
|
-
out = resource.get(:uri => uri, :polnames => true, :subjectid => subjectid)
|
179
|
+
out = RestClientWrapper.get("#{AA}/pol",nil,{:uri => uri, :polnames => true, :subjectid => subjectid})
|
186
180
|
policies = []; notfirstline = false
|
187
181
|
out.split("\n").each do |line|
|
188
182
|
policies << line if notfirstline
|
@@ -199,9 +193,8 @@ module OpenTox
|
|
199
193
|
# return [Boolean] returns true if policy is created
|
200
194
|
def self.create_policy(policy, subjectid)
|
201
195
|
begin
|
202
|
-
|
203
|
-
|
204
|
-
return true if resource.post(policy, :subjectid => subjectid, :content_type => "application/xml")
|
196
|
+
$logger.debug "OpenTox::Authorization.create_policy policy: #{policy[168,43]} with token:" + subjectid.to_s + " length: " + subjectid.length.to_s
|
197
|
+
return true if RestClientWrapper.post("#{AA}/Pol/opensso-pol",policy, {:subjectid => subjectid, :content_type => "application/xml"})
|
205
198
|
rescue
|
206
199
|
return false
|
207
200
|
end
|
@@ -212,36 +205,19 @@ module OpenTox
|
|
212
205
|
# @return [Boolean,nil]
|
213
206
|
def self.delete_policy(policy, subjectid)
|
214
207
|
begin
|
215
|
-
|
216
|
-
|
217
|
-
return true if resource.delete(:subjectid => subjectid, :id => policy)
|
208
|
+
$logger.debug "OpenTox::Authorization.delete_policy policy: #{policy} with token: #{subjectid}"
|
209
|
+
return true if RestClientWrapper.delete("#{AA}/pol",nil, {:subjectid => subjectid, :id => policy})
|
218
210
|
rescue
|
219
211
|
return nil
|
220
212
|
end
|
221
213
|
end
|
222
214
|
|
223
|
-
#Returns array of all possible LDAP-Groups
|
224
|
-
# @param [String]subjectid
|
225
|
-
# @return [Array]
|
226
|
-
def self.list_groups(subjectid)
|
227
|
-
begin
|
228
|
-
resource = RestClient::Resource.new("#{AA_SERVER}/opensso/identity/search")
|
229
|
-
grps = resource.post(:admin => subjectid, :attributes_names => "objecttype", :attributes_values_objecttype => "group")
|
230
|
-
grps = grps.split("\n").collect{|x| x.sub("string=","")}
|
231
|
-
grps.delete_if{|g|g=="MemberManagement"||g=="Webmasters"}
|
232
|
-
grps
|
233
|
-
rescue
|
234
|
-
[]
|
235
|
-
end
|
236
|
-
end
|
237
|
-
|
238
215
|
#Returns array of the LDAP-Groups of an user
|
239
216
|
# @param [String]subjectid
|
240
217
|
# @return [Array] gives array of LDAP groups of a user
|
241
218
|
def self.list_user_groups(user, subjectid)
|
242
219
|
begin
|
243
|
-
|
244
|
-
out = resource.post(:name => user, :admin => subjectid, :attributes_names => "group")
|
220
|
+
out = RestClientWrapper.post("#{AA}/opensso/identity/read", {:name => user, :admin => subjectid, :attributes_names => "group"})
|
245
221
|
grps = []
|
246
222
|
out.split("\n").each do |line|
|
247
223
|
grps << line.sub("identitydetails.group=","") if line.include?("identitydetails.group=")
|
@@ -257,8 +233,7 @@ module OpenTox
|
|
257
233
|
# @return [String]user
|
258
234
|
def self.get_user(subjectid)
|
259
235
|
begin
|
260
|
-
|
261
|
-
out = resource.post(:subjectid => subjectid, :attributes_names => "uid")
|
236
|
+
out = RestClientWrapper.post("#{AA}/opensso/identity/attributes", {:subjectid => subjectid, :attributes_names => "uid"})
|
262
237
|
user = ""; check = false
|
263
238
|
out.split("\n").each do |line|
|
264
239
|
if check
|
@@ -273,13 +248,13 @@ module OpenTox
|
|
273
248
|
end
|
274
249
|
end
|
275
250
|
|
276
|
-
#Send default policy with Authorization::
|
251
|
+
#Send default policy with Authorization::Helper class
|
277
252
|
# @param [String, String]URI,subjectid
|
278
253
|
def self.send_policy(uri, subjectid)
|
279
|
-
return true if !
|
280
|
-
aa = Authorization::
|
254
|
+
return true if !AA
|
255
|
+
aa = Authorization::Helper.new(subjectid)
|
281
256
|
ret = aa.send(uri)
|
282
|
-
|
257
|
+
$logger.debug "OpenTox::Authorization send policy for URI: #{uri} | subjectid: #{subjectid} - policy created: #{ret}"
|
283
258
|
ret
|
284
259
|
end
|
285
260
|
|
@@ -291,7 +266,7 @@ module OpenTox
|
|
291
266
|
if policies
|
292
267
|
policies.each do |policy|
|
293
268
|
ret = delete_policy(policy, subjectid)
|
294
|
-
|
269
|
+
$logger.debug "OpenTox::Authorization delete policy: #{policy} - with result: #{ret}"
|
295
270
|
end
|
296
271
|
end
|
297
272
|
return true
|
@@ -300,15 +275,15 @@ module OpenTox
|
|
300
275
|
# Checks (if subjectid is valid) if a policy exist and create default policy if not
|
301
276
|
# @param [String] uri
|
302
277
|
# @param [String] subjectid
|
303
|
-
# @return [Boolean] true if policy checked/created successfully (or no uri/subjectid given), false else
|
278
|
+
# @return [Boolean] true if policy checked/created successfully (or no uri/subjectid given), false else
|
304
279
|
def self.check_policy(uri, subjectid)
|
305
280
|
return true unless uri and subjectid
|
306
281
|
token_valid = OpenTox::Authorization.is_token_valid(subjectid)
|
307
|
-
|
282
|
+
$logger.debug "OpenTox::Authorization.check_policy with uri: #{uri}, subjectid: #{subjectid} is valid: #{token_valid}"
|
308
283
|
# check if subjectid is valid
|
309
284
|
unless token_valid
|
310
285
|
# abort if invalid
|
311
|
-
|
286
|
+
$logger.error "OpenTox::Authorization.check_policy, subjectid NOT valid: #{subjectid}"
|
312
287
|
return false
|
313
288
|
end
|
314
289
|
|
@@ -320,7 +295,7 @@ module OpenTox
|
|
320
295
|
if authorize(uri, "POST", subjectid)
|
321
296
|
true
|
322
297
|
else
|
323
|
-
|
298
|
+
$logger.error "OpenTox::Authorization.check_policy, already exists, but no POST-authorization with subjectid: #{subjectid}"
|
324
299
|
false
|
325
300
|
end
|
326
301
|
end
|
@@ -337,35 +312,36 @@ module OpenTox
|
|
337
312
|
# @param [String] subjectid
|
338
313
|
# @return [Boolean] true if access granted, else otherwise
|
339
314
|
def self.authorized?(uri, request_method, subjectid)
|
340
|
-
if
|
341
|
-
|
315
|
+
request_method = request_method.to_sym if request_method
|
316
|
+
if $aa[:free_request].include?(request_method)
|
317
|
+
#$logger.debug "authorized? >>true<< (request is free), method: #{request_method}, URI: #{uri}, subjectid: #{subjectid}"
|
342
318
|
true
|
343
319
|
elsif OpenTox::Authorization.free_uri?(uri, request_method)
|
344
|
-
|
320
|
+
#$logger.debug "authorized? >>true<< (uris is free_uri), method: #{request_method}, URI: #{uri}, subjectid: #{subjectid}"
|
345
321
|
true
|
346
|
-
elsif
|
322
|
+
elsif $aa[:authenticate_request].include?(request_method)
|
347
323
|
ret = OpenTox::Authorization.is_token_valid(subjectid)
|
348
|
-
|
324
|
+
$logger.debug "authorized? >>#{ret}<< (token is in/valid), method: #{request_method}, URI: #{uri}, subjectid: #{subjectid}" unless ret
|
349
325
|
ret
|
350
326
|
elsif OpenTox::Authorization.authorize_exception?(uri, request_method)
|
351
327
|
ret = OpenTox::Authorization.is_token_valid(subjectid)
|
352
|
-
|
328
|
+
$logger.debug "authorized? >>#{ret}<< (uris is authorize exception, token is in/valid), method: #{request_method}, URI: #{uri}, subjectid: #{subjectid}" unless ret
|
353
329
|
ret
|
354
|
-
elsif
|
330
|
+
elsif $aa[:authorize_request].include?(request_method)
|
355
331
|
ret = OpenTox::Authorization.authorize(uri, request_method, subjectid)
|
356
|
-
|
332
|
+
$logger.debug "authorized? >>#{ret}<< (uri (not) authorized), method: #{request_method}, URI: #{uri}, subjectid: #{subjectid}" unless ret
|
357
333
|
ret
|
358
334
|
else
|
359
|
-
|
335
|
+
$logger.error "invalid request/uri method: #{request_method}, URI: #{uri}, subjectid: #{subjectid}"
|
360
336
|
false
|
361
337
|
end
|
362
338
|
end
|
363
339
|
|
364
340
|
private
|
365
341
|
def self.free_uri?(uri, request_method)
|
366
|
-
if
|
367
|
-
|
368
|
-
if request_methods and uris and request_methods.include?(request_method.
|
342
|
+
if $aa[:free_uris]
|
343
|
+
$aa[:free_uris].each do |request_methods,uris|
|
344
|
+
if request_methods and uris and request_methods.include?(request_method.to_s)
|
369
345
|
uris.each do |u|
|
370
346
|
return true if u.match uri
|
371
347
|
end
|
@@ -376,8 +352,8 @@ module OpenTox
|
|
376
352
|
end
|
377
353
|
|
378
354
|
def self.authorize_exception?(uri, request_method)
|
379
|
-
if
|
380
|
-
|
355
|
+
if $aa[:authorize_exceptions]
|
356
|
+
$aa[:authorize_exceptions].each do |request_methods,uris|
|
381
357
|
if request_methods and uris and request_methods.include?(request_method.to_sym)
|
382
358
|
uris.each do |u|
|
383
359
|
return true if u.match uri
|
data/lib/dataset.rb
CHANGED
@@ -1,318 +1,29 @@
|
|
1
1
|
module OpenTox
|
2
|
-
|
2
|
+
|
3
3
|
# Ruby wrapper for OpenTox Dataset Webservices (http://opentox.org/dev/apis/api-1.2/dataset).
|
4
|
-
# TODO: fix API Doc
|
5
4
|
class Dataset
|
6
5
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
# @return [OpenTox::Dataset] Dataset object
|
18
|
-
def initialize(uri=nil,subjectid=nil)
|
19
|
-
super uri, subjectid
|
20
|
-
@features = {}
|
21
|
-
@compounds = []
|
22
|
-
@data_entries = {}
|
23
|
-
end
|
24
|
-
|
25
|
-
=begin
|
26
|
-
# Load YAML representation into the dataset
|
27
|
-
# @param [String] yaml YAML representation of the dataset
|
28
|
-
# @return [OpenTox::Dataset] Dataset object with YAML data
|
29
|
-
def self.from_yaml service_uri, yaml, subjectid=nil
|
30
|
-
Dataset.create(service_uri, subjectid).post yaml, :content_type => "application/x-yaml"
|
31
|
-
end
|
32
|
-
|
33
|
-
# Load RDF/XML representation from a file
|
34
|
-
# @param [String] file File with RDF/XML representation of the dataset
|
35
|
-
# @return [OpenTox::Dataset] Dataset object with RDF/XML data
|
36
|
-
def self.from_rdfxml service_uri, rdfxml, subjectid=nil
|
37
|
-
Dataset.create(service_uri, subjectid).post rdfxml, :content_type => "application/rdf+xml"
|
38
|
-
end
|
39
|
-
|
40
|
-
# Load CSV string (format specification: http://toxcreate.org/help)
|
41
|
-
# - loads data_entries, compounds, features
|
42
|
-
# - sets metadata (warnings) for parser errors
|
43
|
-
# - you will have to set remaining metadata manually
|
44
|
-
# @param [String] csv CSV representation of the dataset
|
45
|
-
# @return [OpenTox::Dataset] Dataset object with CSV data
|
46
|
-
def self.from_csv service_uri, csv, subjectid=nil
|
47
|
-
Dataset.from_file(service_uri, csv, subjectid)
|
48
|
-
end
|
49
|
-
|
50
|
-
# Load Spreadsheet book (created with roo gem http://roo.rubyforge.org/, excel format specification: http://toxcreate.org/help)
|
51
|
-
# - loads data_entries, compounds, features
|
52
|
-
# - sets metadata (warnings) for parser errors
|
53
|
-
# - you will have to set remaining metadata manually
|
54
|
-
# @param [Excel] book Excel workbook object (created with roo gem)
|
55
|
-
# @return [OpenTox::Dataset] Dataset object with Excel data
|
56
|
-
def self.from_xls service_uri, xls, subjectid=nil
|
57
|
-
Dataset.create(service_uri, subjectid).post xls, :content_type => "application/vnd.ms-excel"
|
58
|
-
end
|
59
|
-
|
60
|
-
def self.from_sdf service_uri, sdf, subjectid=nil
|
61
|
-
Dataset.create(service_uri, subjectid).post sdf, :content_type => 'chemical/x-mdl-sdfile'
|
62
|
-
end
|
63
|
-
=end
|
64
|
-
|
65
|
-
# Load all data (metadata, data_entries, compounds and features) from URI
|
66
|
-
# TODO: move to opentox-server
|
67
|
-
def data_entries reload=true
|
68
|
-
if reload
|
69
|
-
file = Tempfile.new("ot-rdfxml")
|
70
|
-
file.puts get :accept => "application/rdf+xml"
|
71
|
-
file.close
|
72
|
-
to_delete = file.path
|
73
|
-
|
74
|
-
data = {}
|
75
|
-
feature_values = {}
|
76
|
-
feature = {}
|
77
|
-
feature_accept_values = {}
|
78
|
-
other_statements = {}
|
79
|
-
`rapper -i rdfxml -o ntriples #{file.path} 2>/dev/null`.each_line do |line|
|
80
|
-
triple = line.chomp.split(' ',3)
|
81
|
-
triple = triple[0..2].collect{|i| i.sub(/\s+.$/,'').gsub(/[<>"]/,'')}
|
82
|
-
case triple[1]
|
83
|
-
when /#{RDF::OT.values}|#{RDF::OT1.values}/i
|
84
|
-
data[triple[0]] = {:compound => "", :values => []} unless data[triple[0]]
|
85
|
-
data[triple[0]][:values] << triple[2]
|
86
|
-
when /#{RDF::OT.value}|#{RDF::OT1.value}/i
|
87
|
-
feature_values[triple[0]] = triple[2]
|
88
|
-
when /#{RDF::OT.compound}|#{RDF::OT1.compound}/i
|
89
|
-
data[triple[0]] = {:compound => "", :values => []} unless data[triple[0]]
|
90
|
-
data[triple[0]][:compound] = triple[2]
|
91
|
-
when /#{RDF::OT.feature}|#{RDF::OT1.feature}/i
|
92
|
-
feature[triple[0]] = triple[2]
|
93
|
-
when /#{RDF.type}/i
|
94
|
-
if triple[2]=~/#{RDF::OT.Compound}|#{RDF::OT1.Compound}/i and !data[triple[0]]
|
95
|
-
data[triple[0]] = {:compound => triple[0], :values => []}
|
96
|
-
end
|
97
|
-
when /#{RDF::OT.acceptValue}|#{RDF::OT1.acceptValue}/i # acceptValue in ambit datasets is only provided in dataset/<id> no in dataset/<id>/features
|
98
|
-
feature_accept_values[triple[0]] = [] unless feature_accept_values[triple[0]]
|
99
|
-
feature_accept_values[triple[0]] << triple[2]
|
100
|
-
else
|
101
|
-
end
|
102
|
-
end
|
103
|
-
File.delete(to_delete) if to_delete
|
104
|
-
data.each do |id,entry|
|
105
|
-
if entry[:values].size==0
|
106
|
-
# no feature values add plain compounds
|
107
|
-
@compounds << entry[:compound] unless @compounds.include? entry[:compound]
|
108
|
-
else
|
109
|
-
entry[:values].each do |value_id|
|
110
|
-
if feature_values[value_id]
|
111
|
-
split = feature_values[value_id].split(/\^\^/)
|
112
|
-
case split[-1]
|
113
|
-
when RDF::XSD.double, RDF::XSD.float
|
114
|
-
value = split.first.to_f
|
115
|
-
when RDF::XSD.boolean
|
116
|
-
value = split.first=~/(?i)true/ ? true : false
|
117
|
-
else
|
118
|
-
value = split.first
|
119
|
-
end
|
120
|
-
end
|
121
|
-
@compounds << entry[:compound] unless @compounds.include? entry[:compound]
|
122
|
-
@features[feature[value_id][value_id]] = {} unless @features[feature[value_id]]
|
123
|
-
@data_entries[entry[:compound].to_s] = {} unless @data_entries[entry[:compound].to_s]
|
124
|
-
@data_entries[entry[:compound].to_s][feature[value_id]] = [] unless @data_entries[entry[:compound]][feature[value_id]]
|
125
|
-
@data_entries[entry[:compound].to_s][feature[value_id]] << value if value!=nil
|
126
|
-
end
|
127
|
-
end
|
128
|
-
end
|
129
|
-
features subjectid
|
130
|
-
#feature_accept_values.each do |feature, values|
|
131
|
-
#self.features[feature][OT.acceptValue] = values
|
132
|
-
#end
|
133
|
-
self.metadata = metadata(subjectid)
|
134
|
-
end
|
135
|
-
@data_entries
|
136
|
-
end
|
137
|
-
|
138
|
-
# Load and return only compound URIs from the dataset service
|
139
|
-
# @return [Array] Compound URIs in the dataset
|
140
|
-
def compounds reload=true
|
141
|
-
reload ? @compounds = Compound.all(File.join(@uri,"compounds")) : @compounds
|
142
|
-
end
|
143
|
-
|
144
|
-
# Load and return only features from the dataset service
|
145
|
-
# @return [Hash] Features of the dataset
|
146
|
-
def features reload=true
|
147
|
-
reload ? @features = Feature.all(File.join(@uri,"features")) : @features
|
148
|
-
end
|
149
|
-
|
150
|
-
=begin
|
151
|
-
# returns the accept_values of a feature, i.e. the classification domain / all possible feature values
|
152
|
-
# @param [String] feature the URI of the feature
|
153
|
-
# @return [Array] return array with strings, nil if value is not set (e.g. when feature is numeric)
|
154
|
-
def accept_values(feature)
|
155
|
-
load_features
|
156
|
-
accept_values = features[feature][OT.acceptValue]
|
157
|
-
accept_values.sort if accept_values
|
158
|
-
accept_values
|
159
|
-
end
|
160
|
-
|
161
|
-
# Detect feature type(s) in the dataset
|
162
|
-
# @return [String] `classification", "regression", "mixed" or unknown`
|
163
|
-
def feature_type
|
164
|
-
load_features
|
165
|
-
feature_types = @features.collect{|f,metadata| metadata[RDF.type]}.flatten.uniq
|
166
|
-
if feature_types.include?(OT.NominalFeature)
|
167
|
-
"classification"
|
168
|
-
elsif feature_types.include?(OT.NumericFeature)
|
169
|
-
"regression"
|
170
|
-
else
|
171
|
-
"unknown"
|
172
|
-
end
|
6
|
+
def data_entries
|
7
|
+
# TODO fix for api 1.2
|
8
|
+
data_entries = []
|
9
|
+
pull
|
10
|
+
@reload = false
|
11
|
+
metadata[RDF::OT1.dataEntry].collect{|data_entry|
|
12
|
+
data_entries << @rdf.to_hash[data_entry]
|
13
|
+
}
|
14
|
+
@reload = true
|
15
|
+
data_entries
|
173
16
|
end
|
174
|
-
=end
|
175
17
|
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
get :accept => "application/vnd.ms-excel"
|
18
|
+
def compounds
|
19
|
+
uri = File.join(@uri,"compounds")
|
20
|
+
RestClientWrapper.get(uri,{},{:accept => "text/uri-list", :subjectid => @subjectid}).split("\n").collect{|uri| OpenTox::Compound.new uri}
|
180
21
|
end
|
181
22
|
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
get :accept => "text/csv"
|
23
|
+
def features
|
24
|
+
uri = File.join(@uri,"features")
|
25
|
+
RestClientWrapper.get(uri,{},{:accept => "text/uri-list", :subjectid => @subjectid}).split("\n").collect{|uri| OpenTox::Feature.new uri}
|
186
26
|
end
|
187
27
|
|
188
|
-
def to_sdf
|
189
|
-
get :accept => 'chemical/x-mdl-sdfile'
|
190
|
-
end
|
191
|
-
|
192
|
-
|
193
|
-
# Get OWL-DL in ntriples format
|
194
|
-
# @return [String] N-Triples representation
|
195
|
-
def to_ntriples
|
196
|
-
get :accept => "application/rdf+xml"
|
197
|
-
end
|
198
|
-
|
199
|
-
# Get OWL-DL in RDF/XML format
|
200
|
-
# @return [String] RDF/XML representation
|
201
|
-
def to_rdfxml
|
202
|
-
get :accept => "application/rdf+xml"
|
203
|
-
end
|
204
|
-
|
205
|
-
# Get name (DC.title) of a feature
|
206
|
-
# @param [String] feature Feature URI
|
207
|
-
# @return [String] Feture title
|
208
|
-
def feature_name(feature)
|
209
|
-
features[feature][DC.title]
|
210
|
-
end
|
211
|
-
|
212
|
-
def title
|
213
|
-
metadata[DC.title]
|
214
|
-
end
|
215
|
-
|
216
|
-
# Insert a statement (compound_uri,feature_uri,value)
|
217
|
-
# @example Insert a statement (compound_uri,feature_uri,value)
|
218
|
-
# dataset.add "http://webservices.in-silico.ch/compound/InChI=1S/C6Cl6/c7-1-2(8)4(10)6(12)5(11)3(1)9", "http://webservices.in-silico.ch/dataset/1/feature/hamster_carcinogenicity", true
|
219
|
-
# @param [String] compound Compound URI
|
220
|
-
# @param [String] feature Compound URI
|
221
|
-
# @param [Boolean,Float] value Feature value
|
222
|
-
def add (compound,feature,value)
|
223
|
-
@compounds << compound unless @compounds.include? compound
|
224
|
-
@features[feature] = {} unless @features[feature]
|
225
|
-
@data_entries[compound] = {} unless @data_entries[compound]
|
226
|
-
@data_entries[compound][feature] = [] unless @data_entries[compound][feature]
|
227
|
-
@data_entries[compound][feature] << value if value!=nil
|
228
|
-
end
|
229
|
-
|
230
|
-
# Add a feature
|
231
|
-
# @param [String] feature Feature URI
|
232
|
-
# @param [Hash] metadata Hash with feature metadata
|
233
|
-
def add_feature(feature,metadata={})
|
234
|
-
@features[feature] = metadata
|
235
|
-
end
|
236
|
-
|
237
|
-
# Add/modify metadata for a feature
|
238
|
-
# @param [String] feature Feature URI
|
239
|
-
# @param [Hash] metadata Hash with feature metadata
|
240
|
-
def add_feature_metadata(feature,metadata)
|
241
|
-
metadata.each { |k,v| @features[feature][k] = v }
|
242
|
-
end
|
243
|
-
|
244
|
-
# Add a new compound
|
245
|
-
# @param [String] compound Compound URI
|
246
|
-
def add_compound (compound)
|
247
|
-
@compounds << compound unless @compounds.include? compound
|
248
|
-
end
|
249
|
-
|
250
|
-
# Creates a new dataset, by splitting the current dataset, i.e. using only a subset of compounds and features
|
251
|
-
# @param [Array] compounds List of compound URIs
|
252
|
-
# @param [Array] features List of feature URIs
|
253
|
-
# @param [Hash] metadata Hash containing the metadata for the new dataset
|
254
|
-
# @param [String] subjectid
|
255
|
-
# @return [OpenTox::Dataset] newly created dataset, already saved
|
256
|
-
def split( compounds, features, metadata)
|
257
|
-
LOGGER.debug "split dataset using "+compounds.size.to_s+"/"+@compounds.size.to_s+" compounds"
|
258
|
-
raise "no new compounds selected" unless compounds and compounds.size>0
|
259
|
-
dataset = OpenTox::Dataset.create(CONFIG[:services]["opentox-dataset"],@subjectid)
|
260
|
-
if features.size==0
|
261
|
-
compounds.each{ |c| dataset.add_compound(c) }
|
262
|
-
else
|
263
|
-
compounds.each do |c|
|
264
|
-
features.each do |f|
|
265
|
-
if @data_entries[c]==nil or @data_entries[c][f]==nil
|
266
|
-
dataset.add(c,f,nil)
|
267
|
-
else
|
268
|
-
@data_entries[c][f].each do |v|
|
269
|
-
dataset.add(c,f,v)
|
270
|
-
end
|
271
|
-
end
|
272
|
-
end
|
273
|
-
end
|
274
|
-
end
|
275
|
-
# set feature metadata in new dataset accordingly (including accept values)
|
276
|
-
features.each do |f|
|
277
|
-
self.features[f].each do |k,v|
|
278
|
-
dataset.features[f][k] = v
|
279
|
-
end
|
280
|
-
end
|
281
|
-
dataset.add_metadata(metadata)
|
282
|
-
dataset.save
|
283
|
-
dataset
|
284
|
-
end
|
285
|
-
|
286
|
-
# Save dataset at the dataset service
|
287
|
-
# - creates a new dataset if uri is not set
|
288
|
-
# - overwrites dataset if uri exists
|
289
|
-
# @return [String] Dataset URI
|
290
|
-
def save
|
291
|
-
@compounds.uniq!
|
292
|
-
# create dataset if uri is empty
|
293
|
-
self.uri = RestClientWrapper.post(CONFIG[:services]["opentox-dataset"],{:subjectid => @subjectid}).to_s.chomp unless @uri
|
294
|
-
if (CONFIG[:yaml_hosts].include?(URI.parse(@uri).host))
|
295
|
-
RestClientWrapper.post(@uri,self.to_yaml,{:content_type => "application/x-yaml", :subjectid => @subjectid})
|
296
|
-
else
|
297
|
-
s = Serializer::Owl.new
|
298
|
-
s.add_dataset(self)
|
299
|
-
RestClientWrapper.post(@uri, s.to_rdfxml,{:content_type => "application/rdf+xml" , :subjectid => @subjectid})
|
300
|
-
end
|
301
|
-
@uri
|
302
|
-
end
|
303
|
-
|
304
|
-
private
|
305
|
-
# Copy a dataset (rewrites URI)
|
306
|
-
def copy(dataset)
|
307
|
-
@metadata = dataset.metadata
|
308
|
-
@data_entries = dataset.data_entries
|
309
|
-
@compounds = dataset.compounds
|
310
|
-
@features = dataset.features
|
311
|
-
if @uri
|
312
|
-
self.uri = @uri
|
313
|
-
else
|
314
|
-
@uri = dataset.metadata[XSD.anyURI]
|
315
|
-
end
|
316
|
-
end
|
317
28
|
end
|
318
29
|
end
|