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 CHANGED
@@ -3,6 +3,11 @@ opentox-ruby-minimal
3
3
 
4
4
  Thin Ruby wrapper for the [OpenTox](http://www.opentox.org) REST API
5
5
 
6
+ Dependencies
7
+ ------------
8
+
9
+ libraptor1-dev
10
+
6
11
  Installation
7
12
  ------------
8
13
 
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::AA_SERVER = "https://opensso.in-silico.ch" #if not set in .opentox/conf/[environment].yaml
7
- # token = OpenTox::Authorization.authenticate("benutzer", "passwort")
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 AA to create and send default policies out of xml templates
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 AA
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
- @@logger.debug "Policy send with subjectid: #{@subjectid}"
45
- @@logger.warn "Not created Policy is: #{xml}" if !ret
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 AA_SERVER
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 !AA_SERVER
63
+ return nil if !AA
62
64
  begin
63
- resource = RestClient::Resource.new("#{AA_SERVER}/auth/authenticate")
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
- resource = RestClient::Resource.new("#{AA_SERVER}/auth/logout")
77
- resource.post(:subjectid => subjectid)
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 !AA_SERVER
89
+ return true if !AA
89
90
  begin
90
- resource = RestClient::Resource.new("#{AA_SERVER}/auth/authorize")
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 !AA_SERVER
101
+ return true if !AA
102
102
  begin
103
- resource = RestClient::Resource.new("#{AA_SERVER}/auth/isTokenValid")
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
- resource = RestClient::Resource.new("#{AA_SERVER}/pol")
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
- resource = RestClient::Resource.new("#{AA_SERVER}/pol")
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
- resource = RestClient::Resource.new("#{AA_SERVER}/pol")
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
- resource = RestClient::Resource.new("#{AA_SERVER}/pol")
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
- resource = RestClient::Resource.new("#{AA_SERVER}/Pol/opensso-pol")
203
- @@logger.debug "OpenTox::Authorization.create_policy policy: #{policy[168,43]} with token:" + subjectid.to_s + " length: " + subjectid.length.to_s
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
- resource = RestClient::Resource.new("#{AA_SERVER}/pol")
216
- @@logger.debug "OpenTox::Authorization.delete_policy policy: #{policy} with token: #{subjectid}"
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
- resource = RestClient::Resource.new("#{AA_SERVER}/opensso/identity/read")
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
- resource = RestClient::Resource.new("#{AA_SERVER}/opensso/identity/attributes")
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::AA class
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 !AA_SERVER
280
- aa = Authorization::AA.new(subjectid)
254
+ return true if !AA
255
+ aa = Authorization::Helper.new(subjectid)
281
256
  ret = aa.send(uri)
282
- @@logger.debug "OpenTox::Authorization send policy for URI: #{uri} | subjectid: #{subjectid} - policy created: #{ret}"
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
- @@logger.debug "OpenTox::Authorization delete policy: #{policy} - with result: #{ret}"
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
- @@logger.debug "OpenTox::Authorization.check_policy with uri: #{uri}, subjectid: #{subjectid} is valid: #{token_valid}"
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
- @@logger.error "OpenTox::Authorization.check_policy, subjectid NOT valid: #{subjectid}"
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
- @@logger.error "OpenTox::Authorization.check_policy, already exists, but no POST-authorization with subjectid: #{subjectid}"
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 CONFIG[:authorization][:free_request].include?(request_method)
341
- #@@logger.debug "authorized? >>true<< (request is free), method: #{request_method}, URI: #{uri}, subjectid: #{subjectid}"
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
- #@@logger.debug "authorized? >>true<< (uris is free_uri), method: #{request_method}, URI: #{uri}, subjectid: #{subjectid}"
320
+ #$logger.debug "authorized? >>true<< (uris is free_uri), method: #{request_method}, URI: #{uri}, subjectid: #{subjectid}"
345
321
  true
346
- elsif CONFIG[:authorization][:authenticate_request].include?(request_method)
322
+ elsif $aa[:authenticate_request].include?(request_method)
347
323
  ret = OpenTox::Authorization.is_token_valid(subjectid)
348
- @@logger.debug "authorized? >>#{ret}<< (token is in/valid), method: #{request_method}, URI: #{uri}, subjectid: #{subjectid}" unless ret
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
- @@logger.debug "authorized? >>#{ret}<< (uris is authorize exception, token is in/valid), method: #{request_method}, URI: #{uri}, subjectid: #{subjectid}" unless ret
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 CONFIG[:authorization][:authorize_request].include?(request_method)
330
+ elsif $aa[:authorize_request].include?(request_method)
355
331
  ret = OpenTox::Authorization.authorize(uri, request_method, subjectid)
356
- @@logger.debug "authorized? >>#{ret}<< (uri (not) authorized), method: #{request_method}, URI: #{uri}, subjectid: #{subjectid}" unless ret
332
+ $logger.debug "authorized? >>#{ret}<< (uri (not) authorized), method: #{request_method}, URI: #{uri}, subjectid: #{subjectid}" unless ret
357
333
  ret
358
334
  else
359
- @@logger.error "invalid request/uri method: #{request_method}, URI: #{uri}, subjectid: #{subjectid}"
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 CONFIG[:authorization][:free_uris]
367
- CONFIG[:authorization][:free_uris].each do |request_methods,uris|
368
- if request_methods and uris and request_methods.include?(request_method.to_sym)
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 CONFIG[:authorization][:authorize_exceptions]
380
- CONFIG[:authorization][:authorize_exceptions].each do |request_methods,uris|
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
- #include OpenTox
8
-
9
- #attr_reader :features, :compounds, :data_entries, :metadata
10
-
11
- # Create dataset with optional URI. Does not load data into the dataset - you will need to execute one of the load_* methods to pull data from a service or to insert it from other representations.
12
- # @example Create an empty dataset
13
- # dataset = OpenTox::Dataset.new
14
- # @example Create an empty dataset with URI
15
- # dataset = OpenTox::Dataset.new("http:://webservices.in-silico/ch/dataset/1")
16
- # @param [optional, String] uri Dataset URI
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
- # Get Excel representation (alias for to_spreadsheet)
177
- # @return [Spreadsheet::Workbook] Workbook which can be written with the spreadsheet gem (data_entries only, metadata will will be discarded))
178
- def to_xls
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
- # Get CSV string representation (data_entries only, metadata will be discarded)
183
- # @return [String] CSV representation
184
- def to_csv
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