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/lib/error.rb CHANGED
@@ -45,20 +45,19 @@ module OpenTox
45
45
  OpenTox.const_set klass,c
46
46
 
47
47
  # define global methods for raising errors, eg. bad_request_error
48
- Object.send(:define_method, klass.underscore.to_sym) do |message|
49
- defined?(@uri) ? uri = @uri : uri=nil
50
- # TODO: insert uri from sinatra
48
+ Object.send(:define_method, klass.underscore.to_sym) do |message,uri=nil|
51
49
  raise c, message, uri
52
50
  end
53
51
  end
54
52
 
55
53
  # Errors received from RestClientWrapper calls
56
54
  class RestCallError < Error
57
- attr_accessor :request, :response
58
- def initialize request, response, message
55
+ attr_accessor :request#, :response
56
+ def initialize message, request, uri
57
+ #def initialize request, response, message
59
58
  @request = request
60
- @response = response
61
- super 502, message, request.url
59
+ #@response = response
60
+ super 502, message, uri
62
61
  end
63
62
  end
64
63
 
@@ -66,16 +65,24 @@ module OpenTox
66
65
  class ErrorReport
67
66
  def initialize http_code, error
68
67
  @http_code = http_code
69
- #@report = report#.to_yaml
70
68
  @report = {}
71
- @report[RDF::OT.actor] = error.uri
72
- @report[RDF::OT.message] = error.message
69
+ @report[RDF::OT.actor] = error.uri.to_s
70
+ @report[RDF::OT.message] = error.message.to_s
73
71
  @report[RDF::OT.statusCode] = @http_code
74
72
  @report[RDF::OT.errorCode] = error.class.to_s
75
- @report[RDF::OT.errorDetails] = caller.collect{|line| line unless line =~ /#{File.dirname(__FILE__)}/}.compact.join("\n")
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")
76
81
  @report[RDF::OT.errorDetails] += "REST paramenters:\n#{error.request.args.inspect}" if defined? error.request
77
- @report[RDF::OT.message] += "\n" + error.response.body if defined? error.response
82
+ #@report[RDF::OT.message] += "\n" + error.response.body.to_s if defined? error.response
78
83
  # TODO fix Error cause
84
+ # should point to another errorReport, but errorReports do not have URIs
85
+ # create a separate service?
79
86
  #report[RDF::OT.errorCause] = @report if defined?(@report)
80
87
  end
81
88
 
@@ -84,6 +91,10 @@ module OpenTox
84
91
 
85
92
  send :define_method, "to_#{format}".to_sym do
86
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#')
87
98
  subject = RDF::Node.new
88
99
  @report.each do |predicate,object|
89
100
  writer << [subject, predicate, object] if object
@@ -5,6 +5,7 @@ require 'rdf/raptor'
5
5
  require "rest-client"
6
6
  require 'uri'
7
7
  require 'yaml'
8
+ require 'json'
8
9
  require 'logger'
9
10
 
10
11
  # define constants and global variables
@@ -14,7 +15,7 @@ RDF::OT1 = RDF::Vocabulary.new 'http://www.opentox.org/api/1.1#'
14
15
  RDF::OTA = RDF::Vocabulary.new 'http://www.opentox.org/algorithmTypes.owl#'
15
16
 
16
17
  #CLASSES = ["Compound", "Feature", "Dataset", "Algorithm", "Model", "Validation", "Task", "ErrorReport", "Investigation"]
17
- CLASSES = ["Compound", "Feature", "Dataset", "Algorithm", "Model", "Validation", "Task", "Investigation"]
18
+ CLASSES = ["Generic", "Compound", "Feature", "Dataset", "Algorithm", "Model", "Validation", "Task", "Investigation"]
18
19
  RDF_FORMATS = [:rdfxml,:ntriples,:turtle]
19
20
  $default_rdf = "application/rdf+xml"
20
21
 
@@ -25,8 +26,10 @@ FALSE_REGEXP = /^(false|inactive|0|0.0|low tox|deactivating|non-carcinogen|non-m
25
26
  require File.join(File.dirname(__FILE__),"overwrite.rb")
26
27
  require File.join(File.dirname(__FILE__),"error.rb")
27
28
  require File.join(File.dirname(__FILE__),"rest-client-wrapper.rb")
29
+ require File.join(File.dirname(__FILE__),"authorization.rb")
30
+ require File.join(File.dirname(__FILE__),"policy.rb")
28
31
  require File.join(File.dirname(__FILE__),"otlogger.rb") # avoid require conflicts with logger
29
32
  require File.join(File.dirname(__FILE__),"opentox.rb")
30
33
  require File.join(File.dirname(__FILE__),"task.rb")
31
34
  require File.join(File.dirname(__FILE__),"compound.rb")
32
- #require File.join(File.dirname(__FILE__),"dataset.rb")
35
+ require File.join(File.dirname(__FILE__),"dataset.rb")
data/lib/opentox.rb CHANGED
@@ -4,7 +4,7 @@ $logger.level = Logger::DEBUG
4
4
 
5
5
  module OpenTox
6
6
 
7
- attr_accessor :uri, :subjectid, :rdf, :response
7
+ attr_accessor :uri, :subjectid, :rdf, :response, :reload
8
8
 
9
9
  # Ruby interface
10
10
 
@@ -15,34 +15,34 @@ module OpenTox
15
15
  def initialize uri=nil, subjectid=nil
16
16
  @uri = uri.to_s.chomp
17
17
  @subjectid = subjectid
18
+ @reload = true
18
19
  @rdf = RDF::Graph.new
19
20
  end
20
21
 
21
22
  # Load metadata from service
22
23
  def pull
23
- kind_of?(OpenTox::Dataset) ? uri = File.join(@uri,"metadata") : uri = @uri
24
24
  # TODO generic method for all formats
25
- parse_rdfxml RestClientWrapper.get(uri,{},{:accept => $default_rdf, :subjectid => @subjectid})
25
+ parse_rdfxml RestClientWrapper.get(@uri,{},{:accept => $default_rdf, :subjectid => @subjectid})
26
26
  end
27
27
 
28
28
  # Get object metadata
29
29
  # @return [Hash] Metadata
30
30
  def metadata
31
- pull if @rdf.empty?
32
- metadata = {}
33
- @rdf.query([RDF::URI.new(@uri),nil,nil]).collect do |statement|
34
- metadata[statement.predicate] ||= []
35
- metadata[statement.predicate] << statement.object
36
- end
37
- metadata
31
+ pull if @reload # force update
32
+ @rdf.to_hash[RDF::URI.new(@uri)]
38
33
  end
39
34
 
40
35
  # Get metadata values
41
36
  # @param [RDF] Key from RDF Vocabularies
42
37
  # @return [Array] Values for supplied key
43
38
  def [](key)
44
- pull if @rdf.empty?
45
- @rdf.query([RDF::URI.new(@uri),key,nil]).collect{|statement| statement.object}
39
+ pull if @reload # force update
40
+ result = @rdf.query([RDF::URI.new(@uri),key,nil]).collect{|statement| statement.object}
41
+ # TODO: convert to OpenTox objects??
42
+ return nil if result and result.empty?
43
+ return result.first.to_s if result.size == 1
44
+ return result.collect{|r| r.to_s}
45
+ result
46
46
  end
47
47
 
48
48
  # Save object at service
@@ -70,6 +70,14 @@ module OpenTox
70
70
  end
71
71
  end
72
72
 
73
+ def to_yaml
74
+ @rdf.to_hash.to_yaml
75
+ end
76
+
77
+ def to_json
78
+ to_hash.to_json
79
+ end
80
+
73
81
  # REST API
74
82
  def get headers={}
75
83
  headers[:subjectid] ||= @subjectid
@@ -125,10 +133,14 @@ module OpenTox
125
133
 
126
134
  # guess class from uri, this is potentially unsafe, but polling metadata from large uri lists is way too slow (and not all service provide RDF.type in their metadata)
127
135
  result = CLASSES.collect{|s| s if uri =~ /#{s.downcase}/}.compact
128
- internal_server_error "Cannot determine class from URI: '#{uri}.\nCandidate classes are #{result.inspect}" unless result.size == 1
129
- klass = result.first
136
+ if result.size == 1
137
+ klass = result.first
138
+ else
139
+ klass = OpenTox::Generic.new(uri)[RDF.type]
140
+ internal_server_error "Cannot determine class from URI '#{uri} (Candidate classes are #{result.inspect}) or matadata." unless klass
141
+ end
130
142
  # initialize with/without subjectid
131
- subjectid ? eval("#{self}.new(\"#{uri}\", #{subjectid})") : eval("#{self}.new(\"#{uri}\")")
143
+ subjectid ? eval("#{self}.new(\"#{uri}\", \"#{subjectid}\")") : eval("#{self}.new(\"#{uri}\")")
132
144
  end
133
145
  end
134
146
 
data/lib/overwrite.rb CHANGED
@@ -21,18 +21,22 @@ module URI
21
21
  def self.dataset? uri, subjectid=nil
22
22
  uri =~ /dataset/ and URI.accessible? uri, subjectid=nil
23
23
  end
24
-
24
+
25
25
  def self.model? uri, subjectid=nil
26
26
  uri =~ /model/ and URI.accessible? uri, subjectid=nil
27
27
  end
28
28
 
29
- def self.accessible? uri, subjectid=nil
29
+ def self.ssl? uri, subjectid=nil
30
+ URI.parse(uri).instance_of? URI::HTTPS
31
+ end
32
+
33
+ def self.accessible?(uri, subjectid=nil)
30
34
  if URI.task? uri or URI.compound? uri
31
35
  # just try to get a response, valid tasks may return codes > 400
32
36
  Net::HTTP.get_response(URI.parse(uri))
33
37
  true
34
38
  else
35
- Net::HTTP.get_response(URI.parse(uri)).code.to_i < 400
39
+ Net::HTTP.get_response(URI.parse(uri + (subjectid ? "?subjectid=#{CGI.escape subjectid}" : ""))).code.to_i < 400
36
40
  end
37
41
  rescue
38
42
  false
@@ -64,27 +68,11 @@ module Kernel
64
68
  stdout = stdout_stream.read
65
69
  stderr = stderr_stream.read
66
70
  end
67
- raise stderr.strip if !status.success?
71
+ internal_server_error "`" + cmd + "` failed.\n" + stdout + stderr if !status.success?
68
72
  return stdout
69
- rescue Exception
70
- internal_server_error $!
73
+ rescue
74
+ internal_server_error $!.message
71
75
  end
72
76
 
73
- alias_method :system!, :system
74
-
75
- def system cmd
76
- `#{cmd}`
77
- return true
78
- end
79
77
  end
80
78
 
81
- class Array
82
- def short_backtrace
83
- short = []
84
- each do |c|
85
- break if c =~ /sinatra\/base/
86
- short << c
87
- end
88
- short.join("\n")
89
- end
90
- end