summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristoph Helma <helma@in-silico.ch>2015-07-16 16:54:48 +0200
committerChristoph Helma <helma@in-silico.ch>2015-07-16 16:54:48 +0200
commitfceabfcc4e281c582ec5cc09ba84eb49e20a13f0 (patch)
tree7f2eff3d1952aae023dbca6031aa7b8abc498b68
parent3f9b45990e39f8cb379a1a85ab48819cb36599a8 (diff)
feature tests for standalone version
-rw-r--r--lib/dataset.rb2
-rw-r--r--lib/opentox-client.rb24
-rw-r--r--lib/opentox.rb228
-rw-r--r--opentox-client.gemspec8
4 files changed, 82 insertions, 180 deletions
diff --git a/lib/dataset.rb b/lib/dataset.rb
index c965388..1c938da 100644
--- a/lib/dataset.rb
+++ b/lib/dataset.rb
@@ -213,6 +213,7 @@ module OpenTox
end
end
+=begin
RDF_FORMATS.each do |format|
# redefine rdf parse methods for all formats e.g. parse_rdfxml
@@ -268,6 +269,7 @@ module OpenTox
end
end
+=end
# TODO: fix bug that affects data_entry positions # DG: who wrotes this comment ?
def to_ntriples # redefined string version for better performance
diff --git a/lib/opentox-client.rb b/lib/opentox-client.rb
index bafde4c..9f3373d 100644
--- a/lib/opentox-client.rb
+++ b/lib/opentox-client.rb
@@ -1,14 +1,16 @@
require 'rubygems'
require "bundler/setup"
-require 'rdf'
-require 'rdf/raptor'
-require 'rdf/turtle'
+#require 'rdf'
+#require 'rdf/raptor'
+#require 'rdf/turtle'
require "rest-client"
require 'uri'
require 'yaml'
require 'json'
require 'logger'
require "securerandom"
+require 'mongo'
+require 'bson'
default_config = File.join(ENV["HOME"],".opentox","config","default.rb")
client_config = File.join(ENV["HOME"],".opentox","config","opentox-client.rb")
@@ -18,16 +20,16 @@ require default_config if File.exist? default_config
require client_config if File.exist? client_config
# define constants and global variables
-RDF::OT = RDF::Vocabulary.new 'http://www.opentox.org/api/1.2#'
-RDF::OT1 = RDF::Vocabulary.new 'http://www.opentox.org/api/1.1#'
-RDF::OTA = RDF::Vocabulary.new 'http://www.opentox.org/algorithmTypes.owl#'
-RDF::OLO = RDF::Vocabulary.new 'http://purl.org/ontology/olo/core#'
-RDF::TB = RDF::Vocabulary.new "http://onto.toxbank.net/api/"
-RDF::ISA = RDF::Vocabulary.new "http://onto.toxbank.net/isa/"
-RDF::OWL = RDF::Vocabulary.new "http://www.w3.org/2002/07/owl#"
+#RDF::OT = RDF::Vocabulary.new 'http://www.opentox.org/api/1.2#'
+#RDF::OT1 = RDF::Vocabulary.new 'http://www.opentox.org/api/1.1#'
+#RDF::OTA = RDF::Vocabulary.new 'http://www.opentox.org/algorithmTypes.owl#'
+#RDF::OLO = RDF::Vocabulary.new 'http://purl.org/ontology/olo/core#'
+#RDF::TB = RDF::Vocabulary.new "http://onto.toxbank.net/api/"
+#RDF::ISA = RDF::Vocabulary.new "http://onto.toxbank.net/isa/"
+#RDF::OWL = RDF::Vocabulary.new "http://www.w3.org/2002/07/owl#"
CLASSES = ["Compound", "Feature", "Dataset", "Validation", "Task", "Investigation"]
-RDF_FORMATS = [:rdfxml,:ntriples,:turtle]
+#RDF_FORMATS = [:rdfxml,:ntriples,:turtle]
# Regular expressions for parsing classification data
TRUE_REGEXP = /^(true|active|1|1.0|tox|activating|carcinogen|mutagenic)$/i
diff --git a/lib/opentox.rb b/lib/opentox.rb
index fe49ece..b2e9c1b 100644
--- a/lib/opentox.rb
+++ b/lib/opentox.rb
@@ -1,31 +1,31 @@
# defaults to stderr, may be changed to file output (e.g in opentox-service)
$logger = OTLogger.new(STDERR)
$logger.level = Logger::DEBUG
+Mongo::Logger.logger = $logger
+Mongo::Logger.logger.level = Logger::WARN
+$mongo = Mongo::Client.new($mongodb[:uri])
module OpenTox
# Ruby interface
+ attr_accessor :data
# Create a new OpenTox object
- # @param uri [optional,String] URI
+ # @param id [optional,String] ID
# @return [OpenTox] OpenTox object
- def initialize uri=nil
+ def initialize
@data = {}
- if uri
- @data["uri"] = uri.to_s.chomp
- get
- else
- @data["uuid"] = SecureRandom.uuid
- @data["uri"] = File.join(service_uri, @data["uuid"])
- @data["created_at"] = DateTime.now.to_s
- @data["type"] = self.class.to_s.split('::').last
- end
+ @data["type"] = type
+ end
+
+ def created_at
+ # TODO from BSON::ObjectId
end
# Object metadata (lazy loading)
# @return [Hash] Object metadata
- def metadata force_update=false
- get if force_update and URI.accessible? @data["uri"]
+ def metadata
+ get if exists?
@data
end
@@ -43,167 +43,55 @@ module OpenTox
# @param values [Array, String] Predicate value(s)
def []=(predicate,values)
predicate = predicate.to_s
- @data[predicate] = [values].flatten
+ values.is_a?(Array) ? @data[predicate] = [values].flatten : @data[predicate] = values
end
-=begin
- # Object parameters (lazy loading)
- # {http://opentox.org/dev/apis/api-1.2/interfaces OpenTox API}
- # @return [Hash] Object parameters
- def parameters force_update=false
- if (@parameters.empty? or force_update) and URI.accessible? @uri
- get #if @rdf.empty? or force_update
- params = {}
- query = RDF::Query.new({
- :parameter => {
- RDF.type => RDF::OT.Parameter,
- :property => :value,
- }
- })
- query.execute(@rdf).each do |solution|
- params[solution.parameter] = {} unless params[solution.parameter]
- params[solution.parameter][solution.property] = solution.value
- end
- @parameters = params.values
- end
- @parameters
+ def id
+ @data["_id"]
end
-
- # Parameter value
- # @param [String] title
- # @return [String] value
- def parameter_value title
- @parameters.collect{|p| p[RDF::OT.paramValue] if p[RDF::DC.title] == title}.compact.first
+
+ def exists?
+ nr_items = $mongo[collection].find(:_id => @data["_id"]).count
+ nr_items > 0 ? true : false
end
-=end
# Get object from webservice
# @param [String,optional] mime_type
- def get mime_type="application/json"
- bad_request_error "Mime type #{mime_type} is not supported. Please use 'application/json' (default), 'text/plain' (ntriples) or mime_type == 'application/rdf+xml'." unless mime_type == "application/json" or mime_type == "text/plain" or mime_type == "application/rdf+xml"
- response = RestClientWrapper.get(@data["uri"],{},{:accept => mime_type})
- if URI.task?(response)
- uri = wait_for_task response
- response = RestClientWrapper.get(uri,{},{:accept => mime_type})
- end
- case mime_type
- when 'application/json'
- @data = JSON.parse(response) if response
- when "text/plain"
- parse_ntriples response
- when "application/rdf+xml"
- parse_rdfxml response
- end
+ def get
+ resource_not_found_error("#{@data[:type]} with ID #{@data["_id"]} not found.") unless exists?
+ @data = $mongo[collection].find(:_id => @data["_id"]).first
end
-=begin
- # Post object to webservice (append to object), rarely useful and deprecated
- # @deprecated
- def post wait=true, mime_type="text/plain"
- bad_request_error "Mime type #{mime_type} is not supported. Please use 'text/plain' (default) or 'application/rdf+xml'." unless mime_type == "text/plain" or mime_type == "application/rdf+xml"
- case mime_type
- when 'text/plain'
- body = self.to_ntriples
- when 'application/rdf+xml'
- body = self.to_rdfxml
- end
- #Authorization.check_policy(@uri) if $aa[:uri]
- uri = RestClientWrapper.post @uri.to_s, body, { :content_type => mime_type}
- wait ? wait_for_task(uri) : uri
+ def save
+ @data["_id"] = $mongo[collection].insert_one(@data).inserted_id
end
-=end
# Save object at webservice (replace or create object)
- def put wait=true, mime_type="application/json"
- case mime_type
- when 'application/json'
- body = @data.to_json
- else
- bad_request_error "Mime type #{mime_type} is not supported. Please use 'application/json' (default)."
- end
- uri = RestClientWrapper.put @data["uri"], body, { :content_type => mime_type}
- wait ? wait_for_task(uri) : uri
+ def put
+ #@data.delete("_id") # to enable updates
+ $mongo[collection].find(:_id => @data["_id"]).find_one_and_replace(@data, :upsert => true)
end
# Delete object at webservice
def delete
- RestClientWrapper.delete(@data["uri"])
- #Authorization.delete_policies_from_uri(@data["uri"]) if $aa[:uri]
- end
-
- def service_uri
- self.class.service_uri
- end
-
- def create_rdf
- #$logger.debug "#{eval("RDF::OT."+self.class.to_s.split('::').last)}\n"
- @rdf = RDF::Graph.new
- # DG: since model is no self.class anymore
- @metadata[RDF.type] ||= (eval("RDF::OT."+self.class.to_s.split('::').last) =~ /Lazar|Generic/) ? RDF::URI.new(RDF::OT.Model) : RDF::URI.new(eval("RDF::OT."+self.class.to_s.split('::').last))
- #@metadata[RDF.type] ||= RDF::URI.new(eval("RDF::OT."+self.class.to_s.split('::').last))
- @metadata[RDF::DC.date] ||= DateTime.now
- # DG: uri in object should be in brackets, otherwise query for uri-list ignores the object.
- # see: http://www.w3.org/TR/rdf-testcases/#sec-uri-encoding
- @metadata.each do |predicate,values|
- [values].flatten.each{ |value| @rdf << [RDF::URI.new(@data["uri"]), predicate, (URI.valid?(value) ? RDF::URI.new(value) : value)] unless value.nil? }
- end
- @parameters.each do |parameter|
- p_node = RDF::Node.new
- @rdf << [RDF::URI.new(@data["uri"]), RDF::OT.parameters, p_node]
- @rdf << [p_node, RDF.type, RDF::OT.Parameter]
- parameter.each { |k,v| @rdf << [p_node, k, v] unless v.nil?}
- end
+ $mongo[collection].find(:_id => @data["_id"]).find_one_and_delete
end
-
- # as defined in opentox-client.rb
- RDF_FORMATS.each do |format|
- # rdf parse methods for all formats e.g. parse_rdfxml
- send :define_method, "parse_#{format}".to_sym do |rdf|
- @rdf = RDF::Graph.new
- RDF::Reader.for(format).new(rdf) do |reader|
- reader.each_statement{ |statement| @rdf << statement }
- end
- # return values as plain strings instead of RDF objects
- @metadata = @rdf.to_hash[RDF::URI.new(@data["uri"])].inject({}) { |h, (predicate, values)| h[predicate] = values.collect{|v| v.to_s}; h }
- end
-
-=begin
- # rdf serialization methods for all formats e.g. to_rdfxml
- send :define_method, "to_#{format}".to_sym do
- create_rdf
- # if encoding is used iteration is necessary
- # see: http://rubydoc.info/github/ruby-rdf/rdf/RDF/NTriples/Writer
- RDF::Writer.for(format).buffer(:encoding => Encoding::ASCII) do |writer|
- @rdf.each_statement do |statement|
- writer << statement
- end
- end
- end
-=end
- end
-
- # @return [String] converts object to turtle-string
- def to_turtle # redefined to use prefixes (not supported by RDF::Writer)
- prefixes = {:rdf => "http://www.w3.org/1999/02/22-rdf-syntax-ns#"}
- ['OT', 'DC', 'XSD', 'OLO'].each{|p| prefixes[p.downcase.to_sym] = eval("RDF::#{p}.to_s") }
- create_rdf
- RDF::Turtle::Writer.for(:turtle).buffer(:prefixes => prefixes) do |writer|
- writer << @rdf
- end
+ # @return [String] converts OpenTox object into html document (by first converting it to a string)
+ def to_html
+ @data.to_json.to_html
end
- def to_json
- @data.to_json
+ def type
+ self.class.to_s.split('::').last
end
- # @return [String] converts OpenTox object into html document (by first converting it to a string)
- def to_html
- to_json.to_html
+ def collection
+ type.downcase
end
# short access for metadata keys title, description and type
- [ :title , :description , :type , :uri, :uuid ].each do |method|
+ [ :title , :description ].each do |method|
send :define_method, method do
self[method]
end
@@ -218,12 +106,6 @@ module OpenTox
end
module ClassMethods
- def service_uri
- service = self.to_s.split('::')[1].downcase
- eval("$#{service}[:uri]")
- rescue
- bad_request_error "$#{service}[:uri] variable not set. Please set $#{service}[:uri] or use an explicit uri as first constructor argument "
- end
def subjectid
RestClientWrapper.subjectid
end
@@ -239,30 +121,44 @@ module OpenTox
include OpenTox
def self.all
- uris = RestClientWrapper.get(service_uri, {},{:accept => 'text/uri-list'}).split("\n").compact
- uris.collect{|uri| self.new(uri)}
+ $mongo[collection].find.collect do |data|
+ f = self.new
+ f.data = data
+ f
+ end
+ end
+
+ def self.find_id id
+ self.find(:_id => id)
end
#@example fetching a model
- # OpenTox::Model.find(<model-uri>) -> model-object
- def self.find uri
- URI.accessible?(uri) ? self.new(uri) : nil
+ # OpenTox::Model.find(<model-id>) -> model-object
+ def self.find metadata
+ f = self.new
+ items = $mongo[collection].find metadata
+ items.count > 0 ? f.data = items.first : f = nil
+ f
end
def self.create metadata
object = self.new
- metadata.each{|k,v| object[k] = v}
- object.put
+ object.data = metadata
+ object.save
+ object.get
object
end
def self.find_or_create metadata
search = metadata
search.delete("_id")
- search.delete("uri")
- search.delete("uuid")
- uris = RestClientWrapper.get(service_uri,{:query => search},{:accept => "text/uri-list"}).split("\n")
- uris.empty? ? self.create(metadata) : self.new(uris.first)
+ ids = $mongo[collection].find(search).distinct(:_id)
+ ids.empty? ? self.create(metadata) : self.find_id(ids.first)
+ end
+
+ private
+ def self.collection
+ self.to_s.split('::').last.downcase
end
end
OpenTox.const_set klass,c
diff --git a/opentox-client.gemspec b/opentox-client.gemspec
index 872a985..91ee0ae 100644
--- a/opentox-client.gemspec
+++ b/opentox-client.gemspec
@@ -21,11 +21,13 @@ Gem::Specification.new do |s|
# specify any dependencies here; for example:
s.add_runtime_dependency "bundler"
s.add_runtime_dependency "rest-client"
- s.add_runtime_dependency "rdf"
- s.add_runtime_dependency "rdf-raptor"
- s.add_runtime_dependency 'rdf-turtle'
+ #s.add_runtime_dependency "rdf"
+ #s.add_runtime_dependency "rdf-raptor"
+ #s.add_runtime_dependency 'rdf-turtle'
s.add_runtime_dependency "open4"
s.add_runtime_dependency "openbabel"
+ s.add_runtime_dependency "mongo"
+ s.add_runtime_dependency "bson"
# external requirements
["libraptor-dev"].each{|r| s.requirements << r}