opentox-client 0.0.2pre → 1.0.0pre1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -1
- data/ChangeLog +2 -0
- data/README.markdown +16 -1
- data/Rakefile +0 -10
- data/VERSION +1 -0
- data/bin/opentox-client-install +46 -0
- data/lib/authorization.rb +9 -7
- data/lib/compound.rb +40 -20
- data/lib/dataset.rb +126 -16
- data/lib/error.rb +41 -83
- data/lib/model.rb +3 -2
- data/lib/opentox-client.rb +17 -12
- data/lib/opentox.rb +122 -96
- data/lib/overwrite.rb +20 -3
- data/lib/policy.rb +17 -2
- data/lib/rest-client-wrapper.rb +24 -5
- data/lib/task.rb +36 -18
- data/opentox-client.gemspec +2 -1
- metadata +60 -38
- data/test/authorization.rb +0 -107
- data/test/compound.rb +0 -52
- data/test/data/CPDBAS_v5c_1547_29Apr2008part.sdf +0 -13553
- data/test/data/EPAFHM.csv +0 -618
- data/test/data/EPAFHM.mini.csv +0 -21
- data/test/data/ISSCAN-multi.csv +0 -59
- data/test/data/cpdb_100.csv +0 -101
- data/test/data/hamster_carcinogenicity.csv +0 -86
- data/test/data/hamster_carcinogenicity.mini.csv +0 -11
- data/test/data/hamster_carcinogenicity.sdf +0 -2805
- data/test/data/hamster_carcinogenicity.xls +0 -0
- data/test/data/hamster_carcinogenicity.yaml +0 -352
- data/test/data/hamster_carcinogenicity_with_errors.csv +0 -88
- data/test/data/kazius.csv +0 -4069
- data/test/data/multi_cell_call.csv +0 -1067
- data/test/data/multicolumn.csv +0 -5
- data/test/dataset.rb +0 -99
- data/test/error.rb +0 -35
- data/test/feature.rb +0 -36
- data/test/policy.rb +0 -120
- data/test/task.rb +0 -85
data/.gitignore
CHANGED
data/ChangeLog
ADDED
data/README.markdown
CHANGED
@@ -1,8 +1,23 @@
|
|
1
|
-
opentox-
|
1
|
+
opentox-client
|
2
2
|
====================
|
3
3
|
|
4
4
|
Thin Ruby wrapper for the [OpenTox](http://www.opentox.org) REST API
|
5
5
|
|
6
|
+
Libraries:
|
7
|
+
|
8
|
+
* {OpenTox::Algorithm} Wrapper for OpenTox Algorithms
|
9
|
+
* {OpenTox::Authorization} Authorization and Authentication
|
10
|
+
* {OpenTox::Compound} Compound Library
|
11
|
+
* {OpenTox::Dataset} Dataset Library
|
12
|
+
* {OpenTox::Error} extends Exception class according the OpenTox API
|
13
|
+
* {OpenTox::Model} Model Library
|
14
|
+
* {OpenTox} OpenTox Library - general definition of OpenTox objects
|
15
|
+
* {OTLogger} OpenTox Logger Extensions
|
16
|
+
* {OpenTox::Policies} parse and serialize XML for the openSSO A&A server
|
17
|
+
* {OpenTox::RestClientWrapper} wrapper for the RestClient gem
|
18
|
+
* {OpenTox::Task} Task Library
|
19
|
+
|
20
|
+
|
6
21
|
Dependencies
|
7
22
|
------------
|
8
23
|
|
data/Rakefile
CHANGED
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.0.0pre1
|
@@ -0,0 +1,46 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
|
3
|
+
# Installs Opentox Webservice.
|
4
|
+
# Author: Christoph Helma, Andreas Maunz.
|
5
|
+
|
6
|
+
SELF=$(basename $0 -install)
|
7
|
+
[ "`id -u`" = "0" ] && echo "This script must be run as non-root." 1>&2 && exit 1
|
8
|
+
|
9
|
+
# Adjust ruby version here!
|
10
|
+
RUBY_NUM_VER="1.9.3-p194"
|
11
|
+
|
12
|
+
echo
|
13
|
+
echo "Welcome to service installation (<Return> to continue)."
|
14
|
+
read delete_me
|
15
|
+
|
16
|
+
|
17
|
+
# check wd is root of service
|
18
|
+
DIR=`pwd`
|
19
|
+
if echo $DIR | grep "$SELF/bin" >/dev/null 2>&1 ; then cd ..; fi
|
20
|
+
|
21
|
+
# # # Boot the script
|
22
|
+
|
23
|
+
# load base config, helper funs, environment
|
24
|
+
OT_CONFIG_DIR="$HOME/.opentox"
|
25
|
+
! [ -f "$OT_CONFIG_DIR/config/install/config.sh" ] && echo "config.sh not found." 1>&2 && exit 1 || . $OT_CONFIG_DIR/config/install/config.sh
|
26
|
+
! [ -f "$OT_PREFIX/install/utils.sh" ] && echo "utils.sh not found." 1>&2 && exit 1 || . $OT_PREFIX/install/utils.sh
|
27
|
+
[ -f $OT_CONFIG_DIR/opentox-ui.sh ] && . $OT_CONFIG_DIR/opentox-ui.sh # should have been done by user already
|
28
|
+
RUBY_DIR="$HOME/.rbenv/versions/$RUBY_NUM_VER"
|
29
|
+
|
30
|
+
|
31
|
+
# # # Install
|
32
|
+
|
33
|
+
check_utils "rbenv find"
|
34
|
+
check_log $SELF
|
35
|
+
|
36
|
+
# ruby
|
37
|
+
install_ruby
|
38
|
+
|
39
|
+
# self
|
40
|
+
echo
|
41
|
+
install_with_bundler
|
42
|
+
|
43
|
+
notify
|
44
|
+
|
45
|
+
# return to wd
|
46
|
+
cd "$DIR"
|
data/lib/authorization.rb
CHANGED
@@ -5,7 +5,7 @@ module OpenTox
|
|
5
5
|
#@example Authentication
|
6
6
|
# require "opentox-client"
|
7
7
|
# OpenTox::Authorization::AA = "https://opensso.in-silico.ch" #if not set in .opentox/conf/[environment].yaml
|
8
|
-
#
|
8
|
+
# subjectid = OpenTox::Authorization.authenticate("username", "password")
|
9
9
|
#@see http://www.opentox.org/dev/apis/api-1.2/AA OpenTox A&A API 1.2 specification
|
10
10
|
|
11
11
|
module Authorization
|
@@ -65,6 +65,7 @@ module OpenTox
|
|
65
65
|
out = RestClientWrapper.post("#{AA}/auth/authenticate",{:username=>user, :password => pw}).sub("token.id=","").sub("\n","")
|
66
66
|
return out
|
67
67
|
rescue
|
68
|
+
resource_not_found_error "#{out.inspect}"
|
68
69
|
return nil
|
69
70
|
end
|
70
71
|
end
|
@@ -87,11 +88,12 @@ module OpenTox
|
|
87
88
|
# @return [Boolean, nil] returns true, false or nil (if authorization-request fails).
|
88
89
|
def self.authorize(uri, action, subjectid)
|
89
90
|
return true if !AA
|
90
|
-
begin
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
91
|
+
#begin
|
92
|
+
return true if RestClientWrapper.post("#{AA}/auth/authorize",{:uri => uri, :action => action, :subjectid => subjectid})== "boolean=true\n"
|
93
|
+
return false
|
94
|
+
#rescue
|
95
|
+
# return nil
|
96
|
+
#end
|
95
97
|
end
|
96
98
|
|
97
99
|
#Checks if a token is a valid token
|
@@ -101,7 +103,7 @@ module OpenTox
|
|
101
103
|
return true if !AA
|
102
104
|
begin
|
103
105
|
return true if RestClientWrapper.post("#{AA}/auth/isTokenValid",:tokenid => subjectid) == "boolean=true\n"
|
104
|
-
rescue
|
106
|
+
rescue #do rescue because openSSO throws 401
|
105
107
|
return false
|
106
108
|
end
|
107
109
|
return false
|
data/lib/compound.rb
CHANGED
@@ -11,6 +11,7 @@ module OpenTox
|
|
11
11
|
# @param [String] smiles Smiles string
|
12
12
|
# @return [OpenTox::Compound] Compound
|
13
13
|
def self.from_smiles service_uri, smiles, subjectid=nil
|
14
|
+
@smiles = smiles
|
14
15
|
Compound.new RestClientWrapper.post(service_uri, smiles, {:content_type => 'chemical/x-daylight-smiles', :subjectid => subjectid})
|
15
16
|
end
|
16
17
|
|
@@ -18,6 +19,7 @@ module OpenTox
|
|
18
19
|
# @param [String] smiles InChI string
|
19
20
|
# @return [OpenTox::Compound] Compound
|
20
21
|
def self.from_inchi service_uri, inchi, subjectid=nil
|
22
|
+
@inchi = inchi
|
21
23
|
Compound.new RestClientWrapper.post(service_uri, inchi, {:content_type => 'chemical/x-inchi', :subjectid => subjectid})
|
22
24
|
end
|
23
25
|
|
@@ -33,60 +35,78 @@ module OpenTox
|
|
33
35
|
# compound = OpenTox::Compound.from_name("Benzene")
|
34
36
|
# @param [String] name name can be also an InChI/InChiKey, CAS number, etc
|
35
37
|
# @return [OpenTox::Compound] Compound
|
38
|
+
#
|
36
39
|
def self.from_name service_uri, name, subjectid=nil
|
37
|
-
|
40
|
+
@inchi = RestClientWrapper.get File.join(CACTUS_URI,URI.escape(name),"stdinchi")
|
41
|
+
Compound.new RestClientWrapper.post(service_uri, @inchi, {:content_type => 'chemical/x-inchi', :subjectid => subjectid})
|
38
42
|
end
|
39
43
|
|
40
44
|
# Get InChI
|
41
45
|
# @return [String] InChI string
|
42
|
-
def
|
43
|
-
get(:accept => 'chemical/x-inchi').
|
46
|
+
def inchi
|
47
|
+
@inchi ||= RestClientWrapper.get(@uri,{},{:accept => 'chemical/x-inchi'}).chomp
|
48
|
+
end
|
49
|
+
|
50
|
+
# Get InChIKey
|
51
|
+
# @return [String] InChI string
|
52
|
+
def inchikey
|
53
|
+
@inchikey ||= RestClientWrapper.get(@uri,{},{:accept => 'chemical/x-inchikey'}).chomp
|
44
54
|
end
|
45
55
|
|
46
56
|
# Get (canonical) smiles
|
47
57
|
# @return [String] Smiles string
|
48
|
-
def
|
49
|
-
get(:accept => 'chemical/x-daylight-smiles').chomp
|
58
|
+
def smiles
|
59
|
+
@smiles ||= RestClientWrapper.get(@uri,{},{:accept => 'chemical/x-daylight-smiles'}).chomp
|
50
60
|
end
|
51
61
|
|
52
62
|
# Get sdf
|
53
63
|
# @return [String] SDF string
|
54
|
-
def
|
55
|
-
get(:accept => 'chemical/x-mdl-sdfile').chomp
|
64
|
+
def sdf
|
65
|
+
RestClientWrapper.get(@uri,{},{:accept => 'chemical/x-mdl-sdfile'}).chomp
|
56
66
|
end
|
57
67
|
|
58
68
|
# Get gif image
|
59
69
|
# @return [image/gif] Image data
|
60
|
-
def
|
61
|
-
|
70
|
+
def gif
|
71
|
+
RestClientWrapper.get File.join(CACTUS_URI,inchi,"image")
|
62
72
|
end
|
63
73
|
|
64
74
|
# Get png image
|
65
75
|
# @example
|
66
|
-
# image = compound.
|
76
|
+
# image = compound.png
|
67
77
|
# @return [image/png] Image data
|
68
|
-
def
|
69
|
-
get(File.join @uri, "image")
|
78
|
+
def png
|
79
|
+
RestClientWrapper.get(File.join @uri, "image")
|
70
80
|
end
|
71
81
|
|
72
82
|
# Get URI of compound image
|
73
83
|
# @return [String] Compound image URI
|
74
|
-
def
|
84
|
+
def image_uri
|
75
85
|
File.join @uri, "image"
|
76
86
|
end
|
77
87
|
|
78
88
|
# Get all known compound names. Relies on an external service for name lookups.
|
79
89
|
# @example
|
80
|
-
# names = compound.
|
90
|
+
# names = compound.names
|
81
91
|
# @return [String] Compound names
|
82
|
-
def
|
83
|
-
|
84
|
-
get("#{CACTUS_URI}#{to_inchi}/names").split("\n")
|
85
|
-
rescue
|
86
|
-
"not available"
|
87
|
-
end
|
92
|
+
def names
|
93
|
+
RestClientWrapper.get("#{CACTUS_URI}#{inchi}/names").split("\n")
|
88
94
|
end
|
89
95
|
|
96
|
+
def cid
|
97
|
+
pug_uri = "http://pubchem.ncbi.nlm.nih.gov/rest/pug/"
|
98
|
+
@cid ||= RestClientWrapper.post(File.join(pug_uri, "compound", "inchi", "cids", "TXT"),{:inchi => inchi}).strip
|
99
|
+
end
|
100
|
+
|
101
|
+
def chebi
|
102
|
+
end
|
103
|
+
|
104
|
+
def chemblid
|
105
|
+
# https://www.ebi.ac.uk/chembldb/ws#individualCompoundByInChiKey
|
106
|
+
uri = "http://www.ebi.ac.uk/chemblws/compounds/smiles/#{smiles}.json"
|
107
|
+
@chemblid = JSON.parse(RestClientWrapper.get(uri))["compounds"].first["chemblId"]
|
108
|
+
end
|
109
|
+
|
90
110
|
=begin
|
91
111
|
# Match a smarts string
|
92
112
|
# @example
|
data/lib/dataset.rb
CHANGED
@@ -3,27 +3,137 @@ module OpenTox
|
|
3
3
|
# Ruby wrapper for OpenTox Dataset Webservices (http://opentox.org/dev/apis/api-1.2/dataset).
|
4
4
|
class Dataset
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
@
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
6
|
+
attr_accessor :features, :compounds, :data_entries
|
7
|
+
|
8
|
+
def initialize uri=nil, subjectid=nil
|
9
|
+
super uri, subjectid
|
10
|
+
@features = []
|
11
|
+
@compounds = []
|
12
|
+
@data_entries = []
|
13
|
+
append RDF.type, RDF::OT.OrderedDataset
|
14
|
+
end
|
15
|
+
|
16
|
+
def upload filename, wait=true
|
17
|
+
uri = RestClientWrapper.put(@uri, {:file => File.new(filename)}, {:subjectid => @subjectid})
|
18
|
+
OpenTox::Task.new(uri).wait if URI.task?(uri) and wait
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_csv
|
22
|
+
CSV.generate do |csv|
|
23
|
+
csv << ["SMILES"] + @features.collect{|f| f.title}
|
24
|
+
@compounds.each_with_index do |c,i|
|
25
|
+
csv << [c.smiles] + @data_entries[i]
|
26
|
+
end
|
27
|
+
end
|
16
28
|
end
|
17
29
|
|
18
|
-
def
|
19
|
-
|
20
|
-
|
30
|
+
def get
|
31
|
+
super
|
32
|
+
@features = []
|
33
|
+
@compounds = []
|
34
|
+
@data_entries = []
|
35
|
+
query = RDF::Query.new do
|
36
|
+
pattern [:uri, RDF.type, RDF::OT.OrderedDataset]
|
37
|
+
end
|
38
|
+
if query.execute(@rdf).first # ordered dataset
|
39
|
+
query = RDF::Query.new do
|
40
|
+
pattern [:uri, RDF.type, RDF::OT.Compound]
|
41
|
+
pattern [:uri, RDF::OLO.index, :idx]
|
42
|
+
end
|
43
|
+
@compounds = query.execute(@rdf).sort_by{|s| s.idx}.collect{|s| OpenTox::Compound.new s.uri.to_s}
|
44
|
+
query = RDF::Query.new do
|
45
|
+
pattern [:uri, RDF.type, RDF::OT.Feature]
|
46
|
+
pattern [:uri, RDF::OLO.index, :idx]
|
47
|
+
end
|
48
|
+
@features = query.execute(@rdf).sort_by{|s| s.idx}.collect{|s| OpenTox::Feature.new(s.uri.to_s)}
|
49
|
+
numeric_features = @features.collect{|f| f.get; f[RDF.type].include? RDF::OT.NumericFeature}
|
50
|
+
@compounds.each_with_index do |compound,i|
|
51
|
+
query = RDF::Query.new do
|
52
|
+
pattern [:data_entry, RDF::OLO.index, i]
|
53
|
+
pattern [:data_entry, RDF::OT.values, :values]
|
54
|
+
pattern [:values, RDF::OT.feature, :feature]
|
55
|
+
pattern [:feature, RDF::OLO.index, :feature_idx]
|
56
|
+
pattern [:values, RDF::OT.value, :value]
|
57
|
+
end
|
58
|
+
values = query.execute(@rdf).sort_by{|s| s.feature_idx}.collect do |s|
|
59
|
+
(numeric_features[s.feature_idx] and s.value.to_s != "") ? s.value.to_s.to_f : s.value.to_s
|
60
|
+
end
|
61
|
+
@data_entries << values.collect{|v| v == "" ? nil : v}
|
62
|
+
end
|
63
|
+
else
|
64
|
+
query = RDF::Query.new do
|
65
|
+
pattern [:uri, RDF.type, RDF::OT.Feature]
|
66
|
+
end
|
67
|
+
@features = query.execute(@rdf).collect{|s| OpenTox::Feature.new(s.uri.to_s)}
|
68
|
+
query = RDF::Query.new do
|
69
|
+
pattern [:data_entry, RDF::OT.compound, :compound]
|
70
|
+
end
|
71
|
+
@compounds = query.execute(@rdf).sort_by{|s| s.data_entry}.collect{|s| OpenTox::Compound.new s.compound.to_s}
|
72
|
+
numeric_features = @features.collect{|f| f.get; f[RDF.type].include? RDF::OT.NumericFeature}
|
73
|
+
@compounds.each do |compound|
|
74
|
+
values = []
|
75
|
+
@features.each_with_index do |feature,i|
|
76
|
+
query = RDF::Query.new do
|
77
|
+
pattern [:data_entry, RDF::OT.compound, RDF::URI.new(compound.uri)]
|
78
|
+
pattern [:data_entry, RDF::OT.values, :values]
|
79
|
+
pattern [:values, RDF::OT.feature, RDF::URI.new(feature.uri)]
|
80
|
+
pattern [:values, RDF::OT.value, :value]
|
81
|
+
end
|
82
|
+
value = query.execute(@rdf).first.value.to_s
|
83
|
+
value = value.to_f if numeric_features[i] and !value.nil?
|
84
|
+
values << value
|
85
|
+
end
|
86
|
+
@data_entries << values
|
87
|
+
end
|
88
|
+
end
|
21
89
|
end
|
22
90
|
|
23
|
-
def
|
24
|
-
uri = File.join(@uri,"
|
25
|
-
|
91
|
+
def get_metadata
|
92
|
+
uri = File.join(@uri,"metadata")
|
93
|
+
begin
|
94
|
+
parse_ntriples RestClientWrapper.get(uri,{},{:accept => "text/plain", :subjectid => @subjectid})
|
95
|
+
rescue # fall back to rdfxml
|
96
|
+
parse_rdfxml RestClientWrapper.get(uri,{},{:accept => "application/rdf+xml", :subjectid => @subjectid})
|
97
|
+
end
|
98
|
+
metadata
|
26
99
|
end
|
27
100
|
|
101
|
+
def << data_entry
|
102
|
+
compound = data_entry.shift
|
103
|
+
bad_request_error "Dataset features are empty." unless features
|
104
|
+
bad_request_error "data_entry size does not match features size." unless data_entry.size == features.size
|
105
|
+
bad_request_error "First data_entry is not a OpenTox::Compound" unless compound.class == OpenTox::Compound
|
106
|
+
@compounds << compound
|
107
|
+
@data_entries << data_entry
|
108
|
+
end
|
109
|
+
|
110
|
+
RDF_FORMATS.each do |format|
|
111
|
+
|
112
|
+
# redefine rdf serialization methods
|
113
|
+
send :define_method, "to_#{format}".to_sym do
|
114
|
+
# TODO: check, might affect appending to unordered datasets
|
115
|
+
features.each_with_index do |feature,i|
|
116
|
+
@rdf << [RDF::URI.new(feature.uri), RDF::URI.new(RDF.type), RDF::URI.new(RDF::OT.Feature)]
|
117
|
+
@rdf << [RDF::URI.new(feature.uri), RDF::URI.new(RDF::OLO.index), RDF::Literal.new(i)]
|
118
|
+
end
|
119
|
+
compounds.each_with_index do |compound,i|
|
120
|
+
@rdf << [RDF::URI.new(compound.uri), RDF::URI.new(RDF.type), RDF::URI.new(RDF::OT.Compound)]
|
121
|
+
@rdf << [RDF::URI.new(compound.uri), RDF::URI.new(RDF::OLO.index), RDF::Literal.new(i)]
|
122
|
+
data_entry_node = RDF::Node.new
|
123
|
+
@rdf << [RDF::URI.new(@uri), RDF::URI.new(RDF::OT.dataEntry), data_entry_node]
|
124
|
+
@rdf << [data_entry_node, RDF::URI.new(RDF.type), RDF::URI.new(RDF::OT.DataEntry)]
|
125
|
+
@rdf << [data_entry_node, RDF::URI.new(RDF::OLO.index), RDF::Literal.new(i)]
|
126
|
+
@rdf << [data_entry_node, RDF::URI.new(RDF::OT.compound), RDF::URI.new(compound.uri)]
|
127
|
+
data_entries[i].each_with_index do |value,j|
|
128
|
+
value_node = RDF::Node.new
|
129
|
+
@rdf << [data_entry_node, RDF::URI.new(RDF::OT.values), value_node]
|
130
|
+
@rdf << [value_node, RDF::URI.new(RDF::OT.feature), RDF::URI.new(@features[j].uri)]
|
131
|
+
@rdf << [value_node, RDF::URI.new(RDF::OT.value), RDF::Literal.new(value)]
|
132
|
+
end
|
133
|
+
end
|
134
|
+
super()
|
135
|
+
end
|
136
|
+
|
137
|
+
end
|
28
138
|
end
|
29
139
|
end
|
data/lib/error.rb
CHANGED
@@ -5,20 +5,51 @@ class RuntimeError
|
|
5
5
|
attr_accessor :http_code, :uri
|
6
6
|
def initialize message, uri=nil
|
7
7
|
super message
|
8
|
-
@uri = uri
|
8
|
+
@uri = uri.to_s.sub(%r{//.*:.*@},'//') # remove credentials from uri
|
9
9
|
@http_code ||= 500
|
10
|
-
|
10
|
+
@rdf = RDF::Graph.new
|
11
|
+
subject = RDF::Node.new
|
12
|
+
@rdf << [subject, RDF.type, RDF::OT.ErrorReport]
|
13
|
+
@rdf << [subject, RDF::OT.actor, @uri]
|
14
|
+
@rdf << [subject, RDF::OT.message, message.to_s]
|
15
|
+
@rdf << [subject, RDF::OT.statusCode, @http_code]
|
16
|
+
@rdf << [subject, RDF::OT.errorCode, self.class.to_s]
|
17
|
+
@rdf << [subject, RDF::OT.errorCause, short_backtrace]
|
18
|
+
$logger.error("\n"+self.to_turtle)
|
11
19
|
end
|
12
20
|
|
13
|
-
def
|
14
|
-
|
15
|
-
|
21
|
+
def short_backtrace
|
22
|
+
backtrace = caller.collect{|line| line unless line =~ /#{File.dirname(__FILE__)}/}.compact
|
23
|
+
cut_index = backtrace.find_index{|line| line.match /sinatra|minitest/}
|
24
|
+
cut_index ||= backtrace.size
|
25
|
+
cut_index -= 1
|
26
|
+
cut_index = backtrace.size-1 if cut_index < 0
|
27
|
+
backtrace[0..cut_index].join("\n")
|
16
28
|
end
|
29
|
+
|
30
|
+
RDF_FORMATS.each do |format|
|
31
|
+
# rdf serialization methods for all formats e.g. to_rdfxml
|
32
|
+
send :define_method, "to_#{format}".to_sym do
|
33
|
+
RDF::Writer.for(format).buffer do |writer|
|
34
|
+
@rdf.each{|statement| writer << statement}
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def to_turtle # redefine to use prefixes (not supported by RDF::Writer)
|
40
|
+
prefixes = {:rdf => "http://www.w3.org/1999/02/22-rdf-syntax-ns#"}
|
41
|
+
['OT', 'DC', 'XSD', 'OLO'].each{|p| prefixes[p.downcase.to_sym] = eval("RDF::#{p}.to_s") }
|
42
|
+
RDF::N3::Writer.for(:turtle).buffer(:prefixes => prefixes) do |writer|
|
43
|
+
@rdf.each{|statement| writer << statement}
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
17
47
|
end
|
18
48
|
|
19
49
|
module OpenTox
|
20
50
|
|
21
51
|
class Error < RuntimeError
|
52
|
+
|
22
53
|
def initialize code, message, uri=nil
|
23
54
|
@http_code = code
|
24
55
|
super message, uri
|
@@ -26,92 +57,19 @@ module OpenTox
|
|
26
57
|
end
|
27
58
|
|
28
59
|
# OpenTox errors
|
29
|
-
|
30
|
-
"BadRequestError" => 400,
|
31
|
-
"NotAuthorizedError" => 401,
|
32
|
-
"NotFoundError" => 404,
|
33
|
-
"LockedError" => 423,
|
34
|
-
"InternalServerError" => 500,
|
35
|
-
"NotImplementedError" => 501,
|
36
|
-
"ServiceUnavailableError" => 503,
|
37
|
-
"TimeOutError" => 504,
|
38
|
-
}.each do |klass,code|
|
60
|
+
RestClientWrapper.known_errors.each do |error|
|
39
61
|
# create error classes
|
40
62
|
c = Class.new Error do
|
41
63
|
define_method :initialize do |message, uri=nil|
|
42
|
-
super code, message, uri
|
64
|
+
super error[:code], message, uri
|
43
65
|
end
|
44
66
|
end
|
45
|
-
OpenTox.const_set
|
67
|
+
OpenTox.const_set error[:class],c
|
46
68
|
|
47
69
|
# define global methods for raising errors, eg. bad_request_error
|
48
|
-
Object.send(:define_method,
|
49
|
-
raise c
|
70
|
+
Object.send(:define_method, error[:method]) do |message,uri=nil|
|
71
|
+
raise c.new(message, uri)
|
50
72
|
end
|
51
73
|
end
|
52
74
|
|
53
|
-
# Errors received from RestClientWrapper calls
|
54
|
-
class RestCallError < Error
|
55
|
-
attr_accessor :request#, :response
|
56
|
-
def initialize message, request, uri
|
57
|
-
#def initialize request, response, message
|
58
|
-
@request = request
|
59
|
-
#@response = response
|
60
|
-
super 502, message, uri
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
# TODO: create reports directly from errors, requires modified task service
|
65
|
-
class ErrorReport
|
66
|
-
def initialize http_code, error
|
67
|
-
@http_code = http_code
|
68
|
-
@report = {}
|
69
|
-
@report[RDF::OT.actor] = error.uri.to_s
|
70
|
-
@report[RDF::OT.message] = error.message.to_s
|
71
|
-
@report[RDF::OT.statusCode] = @http_code
|
72
|
-
@report[RDF::OT.errorCode] = error.class.to_s
|
73
|
-
|
74
|
-
# cut backtrace
|
75
|
-
backtrace = caller.collect{|line| line unless line =~ /#{File.dirname(__FILE__)}/}.compact
|
76
|
-
cut_index = backtrace.find_index{|line| line.match /sinatra|minitest/}
|
77
|
-
cut_index ||= backtrace.size
|
78
|
-
cut_index -= 1
|
79
|
-
cut_index = backtrace.size-1 if cut_index < 0
|
80
|
-
@report[RDF::OT.errorDetails] = backtrace[0..cut_index].join("\n")
|
81
|
-
@report[RDF::OT.errorDetails] += "REST paramenters:\n#{error.request.args.inspect}" if defined? error.request
|
82
|
-
#@report[RDF::OT.message] += "\n" + error.response.body.to_s if defined? error.response
|
83
|
-
# TODO fix Error cause
|
84
|
-
# should point to another errorReport, but errorReports do not have URIs
|
85
|
-
# create a separate service?
|
86
|
-
#report[RDF::OT.errorCause] = @report if defined?(@report)
|
87
|
-
end
|
88
|
-
|
89
|
-
# define to_ and self.from_ methods for various rdf formats
|
90
|
-
RDF_FORMATS.each do |format|
|
91
|
-
|
92
|
-
send :define_method, "to_#{format}".to_sym do
|
93
|
-
rdf = RDF::Writer.for(format).buffer do |writer|
|
94
|
-
# TODO: not used for turtle
|
95
|
-
# http://rdf.rubyforge.org/RDF/Writer.html#
|
96
|
-
writer.prefix :ot, RDF::URI('http://www.opentox.org/api/1.2#')
|
97
|
-
writer.prefix :ot1_1, RDF::URI('http://www.opentox.org/api/1.1#')
|
98
|
-
subject = RDF::Node.new
|
99
|
-
@report.each do |predicate,object|
|
100
|
-
writer << [subject, predicate, object] if object
|
101
|
-
end
|
102
|
-
end
|
103
|
-
rdf
|
104
|
-
end
|
105
|
-
|
106
|
-
=begin
|
107
|
-
define_singleton_method "from_#{format}".to_sym do |rdf|
|
108
|
-
report = ErrorReport.new
|
109
|
-
RDF::Reader.for(format).new(rdf) do |reader|
|
110
|
-
reader.each_statement{ |statement| report.rdf << statement }
|
111
|
-
end
|
112
|
-
report
|
113
|
-
end
|
114
|
-
=end
|
115
|
-
end
|
116
|
-
end
|
117
75
|
end
|