opentox-ruby-api-wrapper 1.4.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Rakefile +2 -2
 - data/VERSION +1 -1
 - data/bin/opentox-install-ubuntu.sh +2 -2
 - data/bin/yaml2owl.rb +1 -1
 - data/lib/algorithm.rb +4 -1
 - data/lib/compound.rb +4 -4
 - data/lib/config/config_ru.rb +8 -0
 - data/lib/dataset.rb +162 -158
 - data/lib/environment.rb +77 -6
 - data/lib/features.rb +15 -0
 - data/lib/model.rb +88 -103
 - data/lib/opentox-ruby-api-wrapper.rb +1 -1
 - data/lib/owl.rb +386 -149
 - data/lib/rest_client_wrapper.rb +170 -0
 - data/lib/spork.rb +2 -0
 - data/lib/task.rb +148 -75
 - data/lib/templates/config.yaml +53 -5
 - data/lib/utils.rb +34 -2
 - data/lib/validation.rb +10 -2
 - metadata +97 -62
 
    
        data/Rakefile
    CHANGED
    
    | 
         @@ -10,10 +10,10 @@ begin 
     | 
|
| 
       10 
10 
     | 
    
         
             
                gem.email = "helma@in-silico.ch"
         
     | 
| 
       11 
11 
     | 
    
         
             
                gem.homepage = "http://github.com/helma/opentox-ruby-api-wrapper"
         
     | 
| 
       12 
12 
     | 
    
         
             
                gem.authors = ["Christoph Helma"]
         
     | 
| 
       13 
     | 
    
         
            -
            		["sinatra", "rest-client", "rack", "rack-contrib", "rack-flash", "emk-sinatra-url-for", " 
     | 
| 
      
 13 
     | 
    
         
            +
            		["sinatra", "rest-client", "rack", "rack-contrib", "rack-flash", "emk-sinatra-url-for", "sinatra-respond_to", "dm-more", "dm-core", "sinatra-static-assets","tmail"].each do |dep|
         
     | 
| 
       14 
14 
     | 
    
         
             
            			gem.add_dependency dep
         
     | 
| 
       15 
15 
     | 
    
         
             
            		end
         
     | 
| 
       16 
     | 
    
         
            -
            		['cucumber','jeweler' 
     | 
| 
      
 16 
     | 
    
         
            +
            		['cucumber','jeweler'].each do |dep|
         
     | 
| 
       17 
17 
     | 
    
         
             
            			gem.add_development_dependency dep
         
     | 
| 
       18 
18 
     | 
    
         
             
            		end
         
     | 
| 
       19 
19 
     | 
    
         
             
            		gem.files =  FileList["[A-Z]*", "{bin,generators,lib,test}/**/*", 'lib/jeweler/templates/.gitignore']
         
     | 
    
        data/VERSION
    CHANGED
    
    | 
         @@ -1 +1 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            1. 
     | 
| 
      
 1 
     | 
    
         
            +
            1.5.0
         
     | 
| 
         @@ -90,9 +90,9 @@ sudo apt-get install postgresql-server-dev-8.4 | tee -a $INSTALLLOG 
     | 
|
| 
       90 
90 
     | 
    
         
             
            #echo "Installing gems jeweler sinatra emk-sinatra-url-for dm-core cehoffman-sinatra-respond_to rest-client rack-contrib thin cucumber datamapper data_objects do_sqlite3 rinruby"
         
     | 
| 
       91 
91 
     | 
    
         
             
            sudo gem install jeweler  | tee -a $INSTALLLOG
         
     | 
| 
       92 
92 
     | 
    
         
             
            sudo gem install sinatra | tee -a $INSTALLLOG
         
     | 
| 
       93 
     | 
    
         
            -
            sudo gem install  
     | 
| 
      
 93 
     | 
    
         
            +
            sudo gem install sinatra-url-for | tee -a $INSTALLLOG
         
     | 
| 
       94 
94 
     | 
    
         
             
            sudo gem install dm-core  | tee -a $INSTALLLOG
         
     | 
| 
       95 
     | 
    
         
            -
            sudo gem install  
     | 
| 
      
 95 
     | 
    
         
            +
            sudo gem install sinatra-respond_to | tee -a $INSTALLLOG
         
     | 
| 
       96 
96 
     | 
    
         
             
            sudo gem install rest-client | tee -a $INSTALLLOG
         
     | 
| 
       97 
97 
     | 
    
         
             
            sudo gem install rack-contrib | tee -a $INSTALLLOG
         
     | 
| 
       98 
98 
     | 
    
         
             
            sudo gem install thin | tee -a $INSTALLLOG
         
     | 
    
        data/bin/yaml2owl.rb
    CHANGED
    
    | 
         @@ -5,7 +5,7 @@ require 'opentox-ruby-api-wrapper' 
     | 
|
| 
       5 
5 
     | 
    
         
             
            input = YAML.load_file(ARGV[0])
         
     | 
| 
       6 
6 
     | 
    
         
             
            dataset = OpenTox::Dataset.new
         
     | 
| 
       7 
7 
     | 
    
         
             
            dataset.title = input[:title]
         
     | 
| 
       8 
     | 
    
         
            -
            dataset. 
     | 
| 
      
 8 
     | 
    
         
            +
            dataset.creator = input[:source]
         
     | 
| 
       9 
9 
     | 
    
         
             
            input[:data].each do |c,f|
         
     | 
| 
       10 
10 
     | 
    
         
             
            	f.each do |k,v|
         
     | 
| 
       11 
11 
     | 
    
         
             
            		v.each do |value|
         
     | 
    
        data/lib/algorithm.rb
    CHANGED
    
    | 
         @@ -21,8 +21,11 @@ module OpenTox 
     | 
|
| 
       21 
21 
     | 
    
         
             
            			def self.create_model(params)
         
     | 
| 
       22 
22 
     | 
    
         
             
            				LOGGER.debug params
         
     | 
| 
       23 
23 
     | 
    
         
             
            				LOGGER.debug File.basename(__FILE__) + ": creating model"
         
     | 
| 
      
 24 
     | 
    
         
            +
            				LOGGER.debug File.join(@@config[:services]["opentox-algorithm"], "lazar")
         
     | 
| 
      
 25 
     | 
    
         
            +
                    #resource = RestClient::Resource.new(File.join(@@config[:services]["opentox-algorithm"], "lazar"), :user => @@users[:users].keys[0], :password => @@users[:users].values[0], :content_type => "application/x-yaml")
         
     | 
| 
       24 
26 
     | 
    
         
             
                    resource = RestClient::Resource.new(File.join(@@config[:services]["opentox-algorithm"], "lazar"), :user => @@users[:users].keys[0], :password => @@users[:users].values[0], :content_type => "application/x-yaml")
         
     | 
| 
       25 
     | 
    
         
            -
                     
     | 
| 
      
 27 
     | 
    
         
            +
                    #@uri = resource.post(:dataset_uri => params[:dataset_uri], :feature_uri => params[:feature_uri], :feature_generation_uri => File.join(@@config[:services]["opentox-algorithm"], "fminer")).chomp
         
     | 
| 
      
 28 
     | 
    
         
            +
                    @uri = resource.post(:dataset_uri => params[:dataset_uri], :prediction_feature => params[:prediction_feature], :feature_generation_uri => File.join(@@config[:services]["opentox-algorithm"], "fminer")).body.chomp
         
     | 
| 
       26 
29 
     | 
    
         
             
            			end
         
     | 
| 
       27 
30 
     | 
    
         | 
| 
       28 
31 
     | 
    
         
             
            			def self.uri
         
     | 
    
        data/lib/compound.rb
    CHANGED
    
    | 
         @@ -18,18 +18,18 @@ module OpenTox 
     | 
|
| 
       18 
18 
     | 
    
         
             
            				@uri = File.join(@@config[:services]["opentox-compound"],URI.escape(@inchi))
         
     | 
| 
       19 
19 
     | 
    
         
             
            			elsif params[:name]
         
     | 
| 
       20 
20 
     | 
    
         
             
            				# paranoid URI encoding to keep SMILES charges and brackets
         
     | 
| 
       21 
     | 
    
         
            -
            				@inchi =  
     | 
| 
      
 21 
     | 
    
         
            +
            				@inchi = RestClientWrapper.get("#{@@cactus_uri}#{URI.encode(params[:name], Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))}/stdinchi").chomp
         
     | 
| 
       22 
22 
     | 
    
         
             
            				@uri = File.join(@@config[:services]["opentox-compound"],URI.escape(@inchi))
         
     | 
| 
       23 
23 
     | 
    
         
             
            			elsif params[:uri]
         
     | 
| 
       24 
24 
     | 
    
         
             
            				@uri = params[:uri]
         
     | 
| 
       25 
25 
     | 
    
         
             
            				case params[:uri]
         
     | 
| 
       26 
26 
     | 
    
         
             
            				when /ambit/ # Ambit does not deliver InChIs reliably
         
     | 
| 
       27 
     | 
    
         
            -
            					smiles =  
     | 
| 
      
 27 
     | 
    
         
            +
            					smiles = RestClientWrapper.get @uri, :accept => 'chemical/x-daylight-smiles'
         
     | 
| 
       28 
28 
     | 
    
         
             
            					@inchi = obconversion(smiles,'smi','inchi')
         
     | 
| 
       29 
29 
     | 
    
         
             
            				when /InChI/ # shortcut for IST services
         
     | 
| 
       30 
30 
     | 
    
         
             
            					@inchi = params[:uri].sub(/^.*InChI/, 'InChI')
         
     | 
| 
       31 
31 
     | 
    
         
             
            				else
         
     | 
| 
       32 
     | 
    
         
            -
            					@inchi =  
     | 
| 
      
 32 
     | 
    
         
            +
            					@inchi = RestClientWrapper.get @uri, :accept => 'chemical/x-inchi'
         
     | 
| 
       33 
33 
     | 
    
         
             
            				end
         
     | 
| 
       34 
34 
     | 
    
         
             
            			end
         
     | 
| 
       35 
35 
     | 
    
         
             
            		end
         
     | 
| 
         @@ -44,7 +44,7 @@ module OpenTox 
     | 
|
| 
       44 
44 
     | 
    
         
             
            		end
         
     | 
| 
       45 
45 
     | 
    
         | 
| 
       46 
46 
     | 
    
         
             
            		def image
         
     | 
| 
       47 
     | 
    
         
            -
            			 
     | 
| 
      
 47 
     | 
    
         
            +
            			RestClientWrapper.get("#{@@cactus_uri}#{@inchi}/image")
         
     | 
| 
       48 
48 
     | 
    
         
             
            		end
         
     | 
| 
       49 
49 
     | 
    
         | 
| 
       50 
50 
     | 
    
         
             
            		def image_uri
         
     | 
    
        data/lib/config/config_ru.rb
    CHANGED
    
    
    
        data/lib/dataset.rb
    CHANGED
    
    | 
         @@ -1,10 +1,10 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            LOGGER.progname = File.expand_path(__FILE__)
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            module OpenTox
         
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
      
 4 
     | 
    
         
            +
              
         
     | 
| 
       5 
5 
     | 
    
         
             
            	class Dataset 
         
     | 
| 
       6 
6 
     | 
    
         | 
| 
       7 
     | 
    
         
            -
            		attr_accessor :uri, :title, : 
     | 
| 
      
 7 
     | 
    
         
            +
            		attr_accessor :uri, :title, :creator, :data, :features, :compounds
         
     | 
| 
       8 
8 
     | 
    
         | 
| 
       9 
9 
     | 
    
         
             
            		def initialize 
         
     | 
| 
       10 
10 
     | 
    
         
             
            			@data = {}
         
     | 
| 
         @@ -12,171 +12,175 @@ module OpenTox 
     | 
|
| 
       12 
12 
     | 
    
         
             
            			@compounds = []
         
     | 
| 
       13 
13 
     | 
    
         
             
            		end
         
     | 
| 
       14 
14 
     | 
    
         | 
| 
       15 
     | 
    
         
            -
            		def self.find(uri)
         
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
      
 15 
     | 
    
         
            +
            		def self.find(uri, accept_header=nil) 
         
     | 
| 
      
 16 
     | 
    
         
            +
                
         
     | 
| 
      
 17 
     | 
    
         
            +
                  unless accept_header
         
     | 
| 
      
 18 
     | 
    
         
            +
                    #if uri.match(@@config[:services]["opentox-dataset"]) || uri=~ /188.40.32.88/ || uri =~ /informatik/
         
     | 
| 
      
 19 
     | 
    
         
            +
                    if !@@config[:accept_headers]["opentox-dataset"].grep(/yaml/).empty?
         
     | 
| 
      
 20 
     | 
    
         
            +
                      accept_header = 'application/x-yaml'
         
     | 
| 
      
 21 
     | 
    
         
            +
                    else
         
     | 
| 
      
 22 
     | 
    
         
            +
                      accept_header = "application/rdf+xml"
         
     | 
| 
      
 23 
     | 
    
         
            +
                    end
         
     | 
| 
      
 24 
     | 
    
         
            +
                  end
         
     | 
| 
      
 25 
     | 
    
         
            +
                  
         
     | 
| 
      
 26 
     | 
    
         
            +
                  case accept_header
         
     | 
| 
      
 27 
     | 
    
         
            +
                  when "application/x-yaml"
         
     | 
| 
      
 28 
     | 
    
         
            +
            				d = YAML.load RestClientWrapper.get(uri.to_s.strip, :accept => 'application/x-yaml').to_s 
         
     | 
| 
      
 29 
     | 
    
         
            +
                    d.uri = uri unless d.uri
         
     | 
| 
      
 30 
     | 
    
         
            +
            			when "application/rdf+xml"
         
     | 
| 
      
 31 
     | 
    
         
            +
            				owl = OpenTox::Owl.from_uri(uri.to_s.strip, "Dataset")
         
     | 
| 
      
 32 
     | 
    
         
            +
                    
         
     | 
| 
      
 33 
     | 
    
         
            +
                    d = Dataset.new
         
     | 
| 
      
 34 
     | 
    
         
            +
            				d.title = owl.get("title")
         
     | 
| 
      
 35 
     | 
    
         
            +
            				d.creator = owl.get("creator")
         
     | 
| 
      
 36 
     | 
    
         
            +
            				d.uri = owl.uri
         
     | 
| 
      
 37 
     | 
    
         
            +
                    
         
     | 
| 
      
 38 
     | 
    
         
            +
                    # when loading a dataset from owl, only compound- and feature-uris are loaded 
         
     | 
| 
      
 39 
     | 
    
         
            +
                    owl.load_dataset(d.compounds, d.features)
         
     | 
| 
      
 40 
     | 
    
         
            +
            				# all features are marked as dirty, loaded dynamically later
         
     | 
| 
      
 41 
     | 
    
         
            +
                    d.init_dirty_features(owl)
         
     | 
| 
      
 42 
     | 
    
         
            +
                    
         
     | 
| 
      
 43 
     | 
    
         
            +
                    d.compounds.uniq!
         
     | 
| 
      
 44 
     | 
    
         
            +
                    d.features.uniq!
         
     | 
| 
      
 45 
     | 
    
         
            +
                  else
         
     | 
| 
      
 46 
     | 
    
         
            +
                    raise "cannot get datset with accept header: "+accept_header.to_s
         
     | 
| 
      
 47 
     | 
    
         
            +
            		  end
         
     | 
| 
      
 48 
     | 
    
         
            +
                  return d
         
     | 
| 
       17 
49 
     | 
    
         
             
            		end
         
     | 
| 
      
 50 
     | 
    
         
            +
                
         
     | 
| 
      
 51 
     | 
    
         
            +
                # creates a new dataset, using only those compounsd specified in new_compounds
         
     | 
| 
      
 52 
     | 
    
         
            +
                # returns uri of new dataset
         
     | 
| 
      
 53 
     | 
    
         
            +
                def create_new_dataset( new_compounds, new_features, new_title, new_creator )
         
     | 
| 
      
 54 
     | 
    
         
            +
                  
         
     | 
| 
      
 55 
     | 
    
         
            +
                  raise "no new compounds selected" unless new_compounds and new_compounds.size>0
         
     | 
| 
      
 56 
     | 
    
         
            +
                  
         
     | 
| 
      
 57 
     | 
    
         
            +
                  # load require features 
         
     | 
| 
      
 58 
     | 
    
         
            +
                  if ((defined? @dirty_features) && (@dirty_features - new_features).size > 0)
         
     | 
| 
      
 59 
     | 
    
         
            +
                    (@dirty_features - new_features).each{|f| load_feature_values(f)}
         
     | 
| 
      
 60 
     | 
    
         
            +
                  end
         
     | 
| 
      
 61 
     | 
    
         
            +
                  
         
     | 
| 
      
 62 
     | 
    
         
            +
                  dataset = OpenTox::Dataset.new
         
     | 
| 
      
 63 
     | 
    
         
            +
                  dataset.title = new_title
         
     | 
| 
      
 64 
     | 
    
         
            +
                  dataset.creator = new_creator
         
     | 
| 
      
 65 
     | 
    
         
            +
                  dataset.features = new_features
         
     | 
| 
      
 66 
     | 
    
         
            +
                  dataset.compounds = new_compounds
         
     | 
| 
      
 67 
     | 
    
         
            +
                  
         
     | 
| 
      
 68 
     | 
    
         
            +
                  # Copy dataset data for compounds and features
         
     | 
| 
      
 69 
     | 
    
         
            +
                  # PENDING: why storing feature values in an array? 
         
     | 
| 
      
 70 
     | 
    
         
            +
                  new_compounds.each do |c|
         
     | 
| 
      
 71 
     | 
    
         
            +
                    data_c = []
         
     | 
| 
      
 72 
     | 
    
         
            +
                    @data[c].each do |d|
         
     | 
| 
      
 73 
     | 
    
         
            +
                      m = {}
         
     | 
| 
      
 74 
     | 
    
         
            +
                      new_features.each do |f|
         
     | 
| 
      
 75 
     | 
    
         
            +
                        m[f] = d[f]
         
     | 
| 
      
 76 
     | 
    
         
            +
                      end
         
     | 
| 
      
 77 
     | 
    
         
            +
                      data_c << m 
         
     | 
| 
      
 78 
     | 
    
         
            +
                    end
         
     | 
| 
      
 79 
     | 
    
         
            +
                    
         
     | 
| 
      
 80 
     | 
    
         
            +
                    dataset.data[c] = data_c
         
     | 
| 
      
 81 
     | 
    
         
            +
                  end
         
     | 
| 
      
 82 
     | 
    
         
            +
                  return dataset.save
         
     | 
| 
      
 83 
     | 
    
         
            +
                end
         
     | 
| 
      
 84 
     | 
    
         
            +
                
         
     | 
| 
      
 85 
     | 
    
         
            +
                # returns classification value
         
     | 
| 
      
 86 
     | 
    
         
            +
                def get_predicted_class(compound, feature)
         
     | 
| 
      
 87 
     | 
    
         
            +
                  v = get_value(compound, feature)
         
     | 
| 
      
 88 
     | 
    
         
            +
                  if v.is_a?(Hash)
         
     | 
| 
      
 89 
     | 
    
         
            +
                    if v.has_key?(:classification)
         
     | 
| 
      
 90 
     | 
    
         
            +
                      return v[:classification]
         
     | 
| 
      
 91 
     | 
    
         
            +
                    else
         
     | 
| 
      
 92 
     | 
    
         
            +
                      return "no classification key"
         
     | 
| 
      
 93 
     | 
    
         
            +
                    end
         
     | 
| 
      
 94 
     | 
    
         
            +
                  else
         
     | 
| 
      
 95 
     | 
    
         
            +
                    raise "predicted class value is not a hash\n"+
         
     | 
| 
      
 96 
     | 
    
         
            +
                      "value "+v.to_s+"\n"+
         
     | 
| 
      
 97 
     | 
    
         
            +
                      "value-class "+v.class.to_s+"\n"+
         
     | 
| 
      
 98 
     | 
    
         
            +
                      "dataset "+@uri.to_s+"\n"+
         
     | 
| 
      
 99 
     | 
    
         
            +
                      "compound "+compound.to_s+"\n"+
         
     | 
| 
      
 100 
     | 
    
         
            +
                      "feature "+feature.to_s+"\n"
         
     | 
| 
      
 101 
     | 
    
         
            +
                  end
         
     | 
| 
      
 102 
     | 
    
         
            +
                  
         
     | 
| 
      
 103 
     | 
    
         
            +
                end
         
     | 
| 
      
 104 
     | 
    
         
            +
                
         
     | 
| 
      
 105 
     | 
    
         
            +
                # returns prediction confidence if available
         
     | 
| 
      
 106 
     | 
    
         
            +
                def get_prediction_confidence(compound, feature)
         
     | 
| 
      
 107 
     | 
    
         
            +
                  v = get_value(compound, feature)
         
     | 
| 
      
 108 
     | 
    
         
            +
                  if v.is_a?(Hash)
         
     | 
| 
      
 109 
     | 
    
         
            +
                    if v.has_key?(:confidence)
         
     | 
| 
      
 110 
     | 
    
         
            +
                      return v[:confidence].abs
         
     | 
| 
      
 111 
     | 
    
         
            +
                    else
         
     | 
| 
      
 112 
     | 
    
         
            +
                      # PENDING: return nil isntead of raising an exception
         
     | 
| 
      
 113 
     | 
    
         
            +
                      raise "no confidence key"
         
     | 
| 
      
 114 
     | 
    
         
            +
                    end
         
     | 
| 
      
 115 
     | 
    
         
            +
                  else
         
     | 
| 
      
 116 
     | 
    
         
            +
                    raise "prediction confidence value is not a hash value\n"+
         
     | 
| 
      
 117 
     | 
    
         
            +
                      "value "+v.to_s+"\n"+
         
     | 
| 
      
 118 
     | 
    
         
            +
                      "value-class "+v.class.to_s+"\n"+
         
     | 
| 
      
 119 
     | 
    
         
            +
                      "dataset "+@uri.to_s+"\n"+
         
     | 
| 
      
 120 
     | 
    
         
            +
                      "compound "+compound.to_s+"\n"+
         
     | 
| 
      
 121 
     | 
    
         
            +
                      "feature "+feature.to_s+"\n"
         
     | 
| 
      
 122 
     | 
    
         
            +
                  end
         
     | 
| 
      
 123 
     | 
    
         
            +
                end
         
     | 
| 
      
 124 
     | 
    
         
            +
                
         
     | 
| 
      
 125 
     | 
    
         
            +
                # return compound-feature value
         
     | 
| 
      
 126 
     | 
    
         
            +
                def get_value(compound, feature)
         
     | 
| 
      
 127 
     | 
    
         
            +
                  if (defined? @dirty_features) && @dirty_features.include?(feature)
         
     | 
| 
      
 128 
     | 
    
         
            +
                    load_feature_values(feature)
         
     | 
| 
      
 129 
     | 
    
         
            +
                  end
         
     | 
| 
      
 130 
     | 
    
         
            +
                  
         
     | 
| 
      
 131 
     | 
    
         
            +
                  v = @data[compound]
         
     | 
| 
      
 132 
     | 
    
         
            +
                  raise "no values for compound "+compound.to_s if v==nil
         
     | 
| 
      
 133 
     | 
    
         
            +
                  if v.is_a?(Array)
         
     | 
| 
      
 134 
     | 
    
         
            +
                    # PENDING: why using an array here?
         
     | 
| 
      
 135 
     | 
    
         
            +
                    v.each do |e|
         
     | 
| 
      
 136 
     | 
    
         
            +
                      if e.is_a?(Hash)
         
     | 
| 
      
 137 
     | 
    
         
            +
                        if e.has_key?(feature)
         
     | 
| 
      
 138 
     | 
    
         
            +
                          return e[feature]
         
     | 
| 
      
 139 
     | 
    
         
            +
                        end
         
     | 
| 
      
 140 
     | 
    
         
            +
                      else
         
     | 
| 
      
 141 
     | 
    
         
            +
                        raise "invalid internal value type"
         
     | 
| 
      
 142 
     | 
    
         
            +
                      end
         
     | 
| 
      
 143 
     | 
    
         
            +
                    end
         
     | 
| 
      
 144 
     | 
    
         
            +
                    raise "feature value no found: "+feature.to_s
         
     | 
| 
      
 145 
     | 
    
         
            +
                  else
         
     | 
| 
      
 146 
     | 
    
         
            +
                    raise "value is not an array\n"+
         
     | 
| 
      
 147 
     | 
    
         
            +
                          "value "+v.to_s+"\n"+
         
     | 
| 
      
 148 
     | 
    
         
            +
                          "value-class "+v.class.to_s+"\n"+
         
     | 
| 
      
 149 
     | 
    
         
            +
                          "dataset "+@uri.to_s+"\n"+
         
     | 
| 
      
 150 
     | 
    
         
            +
                          "compound "+compound.to_s+"\n"+
         
     | 
| 
      
 151 
     | 
    
         
            +
                          "feature "+feature.to_s+"\n"
         
     | 
| 
      
 152 
     | 
    
         
            +
                  end
         
     | 
| 
      
 153 
     | 
    
         
            +
                end
         
     | 
| 
       18 
154 
     | 
    
         | 
| 
      
 155 
     | 
    
         
            +
                # loads specified feature and removes dirty-flag, loads all features if feature is nil
         
     | 
| 
      
 156 
     | 
    
         
            +
                def load_feature_values(feature=nil)
         
     | 
| 
      
 157 
     | 
    
         
            +
                  if feature
         
     | 
| 
      
 158 
     | 
    
         
            +
                    raise "feature already loaded" unless @dirty_features.include?(feature)
         
     | 
| 
      
 159 
     | 
    
         
            +
                    @owl.load_dataset_feature_values(@compounds, @data, feature)
         
     | 
| 
      
 160 
     | 
    
         
            +
                    @dirty_features.delete(feature)
         
     | 
| 
      
 161 
     | 
    
         
            +
                  else
         
     | 
| 
      
 162 
     | 
    
         
            +
                    @data = {}
         
     | 
| 
      
 163 
     | 
    
         
            +
                    @owl.load_dataset_feature_values(@compounds, @data)
         
     | 
| 
      
 164 
     | 
    
         
            +
                    @dirty_features.clear
         
     | 
| 
      
 165 
     | 
    
         
            +
                  end
         
     | 
| 
      
 166 
     | 
    
         
            +
                end
         
     | 
| 
       19 
167 
     | 
    
         | 
| 
       20 
168 
     | 
    
         
             
            		def save
         
     | 
| 
      
 169 
     | 
    
         
            +
                  # loads all features before loading  
         
     | 
| 
      
 170 
     | 
    
         
            +
                  if ((defined? @dirty_features) && @dirty_features.size > 0)
         
     | 
| 
      
 171 
     | 
    
         
            +
                    load_feature_values()
         
     | 
| 
      
 172 
     | 
    
         
            +
                  end
         
     | 
| 
      
 173 
     | 
    
         
            +
                
         
     | 
| 
       21 
174 
     | 
    
         
             
            			@features.uniq!
         
     | 
| 
       22 
175 
     | 
    
         
             
            			@compounds.uniq!
         
     | 
| 
       23 
     | 
    
         
            -
                   
     | 
| 
       24 
     | 
    
         
            -
            		end
         
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
       26 
     | 
    
         
            -
            =begin
         
     | 
| 
       27 
     | 
    
         
            -
            		# create/add to entry from uris or Redland::Resources
         
     | 
| 
       28 
     | 
    
         
            -
            		def add(compound,feature,value)
         
     | 
| 
       29 
     | 
    
         
            -
            			compound = self.find_or_create_compound compound unless compound.class == Redland::Resource
         
     | 
| 
       30 
     | 
    
         
            -
            			feature = self.find_or_create_feature feature unless feature.class == Redland::Resource
         
     | 
| 
       31 
     | 
    
         
            -
            			data_entry = @model.subject OT['compound'], compound
         
     | 
| 
       32 
     | 
    
         
            -
            			if data_entry.nil?
         
     | 
| 
       33 
     | 
    
         
            -
            				data_entry = @model.create_resource
         
     | 
| 
       34 
     | 
    
         
            -
            				dataset = @model.subject(RDF['type'],OT[self.owl_class])
         
     | 
| 
       35 
     | 
    
         
            -
            				@model.add dataset, OT['dataEntry'], data_entry
         
     | 
| 
       36 
     | 
    
         
            -
            				@model.add data_entry, RDF['type'], OT["DataEntry"]
         
     | 
| 
       37 
     | 
    
         
            -
            				@model.add data_entry, OT['compound'], compound
         
     | 
| 
       38 
     | 
    
         
            -
            			end
         
     | 
| 
       39 
     | 
    
         
            -
            			values = @model.create_resource
         
     | 
| 
       40 
     | 
    
         
            -
            			@model.add data_entry, OT['values'], values
         
     | 
| 
       41 
     | 
    
         
            -
            			@model.add values, RDF['type'], OT['FeatureValue']
         
     | 
| 
       42 
     | 
    
         
            -
            			@model.add values, OT['feature'], feature
         
     | 
| 
       43 
     | 
    
         
            -
            			@model.add values, OT['value'], value.to_s
         
     | 
| 
       44 
     | 
    
         
            -
            		end
         
     | 
| 
       45 
     | 
    
         
            -
             
     | 
| 
       46 
     | 
    
         
            -
            		def add_tuple(compound,tuple)
         
     | 
| 
       47 
     | 
    
         
            -
            			compound = self.find_or_create_compound compound unless compound.class == Redland::Resource
         
     | 
| 
       48 
     | 
    
         
            -
            			data_entry = @model.subject OT['compound'], compound
         
     | 
| 
       49 
     | 
    
         
            -
            			if data_entry.nil?
         
     | 
| 
       50 
     | 
    
         
            -
            				data_entry = @model.create_resource
         
     | 
| 
       51 
     | 
    
         
            -
            				dataset = @model.subject(RDF['type'],OT[self.owl_class])
         
     | 
| 
       52 
     | 
    
         
            -
            				@model.add dataset, OT['dataEntry'], data_entry
         
     | 
| 
       53 
     | 
    
         
            -
            				@model.add data_entry, RDF['type'], OT["DataEntry"]
         
     | 
| 
       54 
     | 
    
         
            -
            				@model.add data_entry, OT['compound'], compound
         
     | 
| 
       55 
     | 
    
         
            -
            			end
         
     | 
| 
       56 
     | 
    
         
            -
            			@model.add data_entry, OT['values'], tuple
         
     | 
| 
      
 176 
     | 
    
         
            +
                  OpenTox::RestClientWrapper.post(@@config[:services]["opentox-dataset"],{:content_type =>  "application/x-yaml"},self.to_yaml).strip 	
         
     | 
| 
       57 
177 
     | 
    
         
             
            		end
         
     | 
| 
       58 
178 
     | 
    
         | 
| 
       59 
     | 
    
         
            -
             
     | 
| 
       60 
     | 
    
         
            -
             
     | 
| 
       61 
     | 
    
         
            -
             
     | 
| 
       62 
     | 
    
         
            -
            			@model.add tuple, RDF['type'], OT["Tuple"]
         
     | 
| 
       63 
     | 
    
         
            -
            			@model.add tuple, OT['feature'], feature
         
     | 
| 
       64 
     | 
    
         
            -
            			t.each do |name,value|
         
     | 
| 
       65 
     | 
    
         
            -
            				f = self.find_or_create_feature name unless name.class == Redland::Resource
         
     | 
| 
       66 
     | 
    
         
            -
            				complex_value = @model.create_resource
         
     | 
| 
       67 
     | 
    
         
            -
            				feature = self.find_or_create_feature(name) 
         
     | 
| 
       68 
     | 
    
         
            -
            				@model.add tuple, OT['complexValue'], complex_value
         
     | 
| 
       69 
     | 
    
         
            -
            				@model.add complex_value, RDF['type'], OT["FeatureValue"]
         
     | 
| 
       70 
     | 
    
         
            -
            				@model.add complex_value, OT['feature'], f
         
     | 
| 
       71 
     | 
    
         
            -
            				@model.add complex_value, OT['value'], value.to_s
         
     | 
| 
       72 
     | 
    
         
            -
                  end
         
     | 
| 
       73 
     | 
    
         
            -
              	
         
     | 
| 
       74 
     | 
    
         
            -
            			tuple
         
     | 
| 
       75 
     | 
    
         
            -
            		end
         
     | 
| 
       76 
     | 
    
         
            -
             
     | 
| 
       77 
     | 
    
         
            -
            		# find or create a new compound and return the resource
         
     | 
| 
       78 
     | 
    
         
            -
            		def find_or_create_compound(uri)
         
     | 
| 
       79 
     | 
    
         
            -
            			compound = @model.subject(DC["identifier"], uri)
         
     | 
| 
       80 
     | 
    
         
            -
            			if compound.nil?
         
     | 
| 
       81 
     | 
    
         
            -
            				compound = @model.create_resource(uri)
         
     | 
| 
       82 
     | 
    
         
            -
            				@model.add compound, RDF['type'], OT["Compound"]
         
     | 
| 
       83 
     | 
    
         
            -
            				@model.add compound, DC["identifier"], uri
         
     | 
| 
       84 
     | 
    
         
            -
            			end
         
     | 
| 
       85 
     | 
    
         
            -
            			compound
         
     | 
| 
       86 
     | 
    
         
            -
            		end
         
     | 
| 
       87 
     | 
    
         
            -
             
     | 
| 
       88 
     | 
    
         
            -
            		# find or create a new feature and return the resource
         
     | 
| 
       89 
     | 
    
         
            -
            		def find_or_create_feature(uri)
         
     | 
| 
       90 
     | 
    
         
            -
            			feature = @model.subject(DC["identifier"], uri)
         
     | 
| 
       91 
     | 
    
         
            -
            			if feature.nil?
         
     | 
| 
       92 
     | 
    
         
            -
            				feature = @model.create_resource(uri)
         
     | 
| 
       93 
     | 
    
         
            -
            				@model.add feature, RDF['type'], OT["Feature"]
         
     | 
| 
       94 
     | 
    
         
            -
            				@model.add feature, DC["identifier"], uri
         
     | 
| 
       95 
     | 
    
         
            -
            				@model.add feature, DC["title"], File.basename(uri).split(/#/)[1]
         
     | 
| 
       96 
     | 
    
         
            -
            				@model.add feature, DC['source'], uri
         
     | 
| 
       97 
     | 
    
         
            -
            			end
         
     | 
| 
       98 
     | 
    
         
            -
            			feature
         
     | 
| 
       99 
     | 
    
         
            -
            		end
         
     | 
| 
       100 
     | 
    
         
            -
             
     | 
| 
       101 
     | 
    
         
            -
            		def self.create(data, content_type = 'application/rdf+xml')
         
     | 
| 
       102 
     | 
    
         
            -
                  resource = RestClient::Resource.new(@@config[:services]["opentox-dataset"], :user => @@users[:users].keys[0], :password => @@users[:users].values[0])		  
         
     | 
| 
       103 
     | 
    
         
            -
            		  uri = resource.post data, :content_type => content_type
         
     | 
| 
       104 
     | 
    
         
            -
            			dataset = Dataset.new
         
     | 
| 
       105 
     | 
    
         
            -
            			dataset.read uri.chomp.to_s
         
     | 
| 
       106 
     | 
    
         
            -
            			dataset
         
     | 
| 
       107 
     | 
    
         
            -
            		end
         
     | 
| 
       108 
     | 
    
         
            -
             
     | 
| 
       109 
     | 
    
         
            -
            		def features
         
     | 
| 
       110 
     | 
    
         
            -
            			features = []
         
     | 
| 
       111 
     | 
    
         
            -
            			@model.subjects(RDF['type'], OT["Feature"]).each do |feature_node|
         
     | 
| 
       112 
     | 
    
         
            -
            				features << @model.object(feature_node,  DC["identifier"])#
         
     | 
| 
       113 
     | 
    
         
            -
            			end
         
     | 
| 
       114 
     | 
    
         
            -
            			features
         
     | 
| 
       115 
     | 
    
         
            -
            		end
         
     | 
| 
       116 
     | 
    
         
            -
             
     | 
| 
       117 
     | 
    
         
            -
            		def data
         
     | 
| 
       118 
     | 
    
         
            -
            			data = {}
         
     | 
| 
       119 
     | 
    
         
            -
            			@model.subjects(RDF['type'], OT['DataEntry']).each do |data_entry|
         
     | 
| 
       120 
     | 
    
         
            -
            				compound_node  = @model.object(data_entry, OT['compound'])
         
     | 
| 
       121 
     | 
    
         
            -
            				compound_uri = @model.object(compound_node, DC['identifier']).to_s
         
     | 
| 
       122 
     | 
    
         
            -
            				@model.find(data_entry, OT['values'], nil) do |s,p,values|
         
     | 
| 
       123 
     | 
    
         
            -
            					feature_node = @model.object values, OT['feature']
         
     | 
| 
       124 
     | 
    
         
            -
            					feature_uri = @model.object(feature_node, DC['identifier']).to_s.sub(/\^\^.*$/,'') # remove XML datatype
         
     | 
| 
       125 
     | 
    
         
            -
            					type = @model.object(values, RDF['type'])
         
     | 
| 
       126 
     | 
    
         
            -
            					if type == OT['FeatureValue']
         
     | 
| 
       127 
     | 
    
         
            -
            						value = @model.object(values, OT['value']).to_s
         
     | 
| 
       128 
     | 
    
         
            -
            						case value.to_s
         
     | 
| 
       129 
     | 
    
         
            -
            						when TRUE_REGEXP # defined in environment.rb
         
     | 
| 
       130 
     | 
    
         
            -
            							value = true
         
     | 
| 
       131 
     | 
    
         
            -
            						when FALSE_REGEXP # defined in environment.rb
         
     | 
| 
       132 
     | 
    
         
            -
            							value = false
         
     | 
| 
       133 
     | 
    
         
            -
            						else
         
     | 
| 
       134 
     | 
    
         
            -
            							LOGGER.warn compound_uri + " has value '" + value.to_s + "' for feature " + feature_uri
         
     | 
| 
       135 
     | 
    
         
            -
            							value = nil
         
     | 
| 
       136 
     | 
    
         
            -
            						end
         
     | 
| 
       137 
     | 
    
         
            -
            						data[compound_uri] = {} unless data[compound_uri]
         
     | 
| 
       138 
     | 
    
         
            -
            						data[compound_uri][feature_uri] = [] unless data[compound_uri][feature_uri]
         
     | 
| 
       139 
     | 
    
         
            -
            						data[compound_uri][feature_uri] << value unless value.nil?
         
     | 
| 
       140 
     | 
    
         
            -
            					elsif type == OT['Tuple']
         
     | 
| 
       141 
     | 
    
         
            -
            						entry = {}
         
     | 
| 
       142 
     | 
    
         
            -
            						data[compound_uri] = {} unless data[compound_uri]
         
     | 
| 
       143 
     | 
    
         
            -
            						data[compound_uri][feature_uri] = [] unless data[compound_uri][feature_uri]
         
     | 
| 
       144 
     | 
    
         
            -
            						@model.find(values, OT['complexValue'],nil) do |s,p,complex_value|
         
     | 
| 
       145 
     | 
    
         
            -
            							name_node = @model.object complex_value, OT['feature']
         
     | 
| 
       146 
     | 
    
         
            -
            							name = @model.object(name_node, DC['title']).to_s
         
     | 
| 
       147 
     | 
    
         
            -
            							value = @model.object(complex_value, OT['value']).to_s
         
     | 
| 
       148 
     | 
    
         
            -
            							v = value.sub(/\^\^.*$/,'') # remove XML datatype
         
     | 
| 
       149 
     | 
    
         
            -
            							v = v.to_f if v.match(/^[\.|\d]+$/) # guess numeric datatype
         
     | 
| 
       150 
     | 
    
         
            -
            							entry[name] = v
         
     | 
| 
       151 
     | 
    
         
            -
            						end
         
     | 
| 
       152 
     | 
    
         
            -
            						data[compound_uri][feature_uri] << entry
         
     | 
| 
       153 
     | 
    
         
            -
            					end
         
     | 
| 
       154 
     | 
    
         
            -
            				end
         
     | 
| 
       155 
     | 
    
         
            -
            			end
         
     | 
| 
       156 
     | 
    
         
            -
            			data
         
     | 
| 
       157 
     | 
    
         
            -
            		end
         
     | 
| 
       158 
     | 
    
         
            -
             
     | 
| 
       159 
     | 
    
         
            -
            		def compounds
         
     | 
| 
       160 
     | 
    
         
            -
            			compounds = []
         
     | 
| 
       161 
     | 
    
         
            -
            			@model.subjects(RDF['type'], OT["Compound"]).each do |compound_node|
         
     | 
| 
       162 
     | 
    
         
            -
            				compounds << @model.object(compound_node,  DC["identifier"]).to_s
         
     | 
| 
       163 
     | 
    
         
            -
            			end
         
     | 
| 
       164 
     | 
    
         
            -
            			compounds
         
     | 
| 
       165 
     | 
    
         
            -
            		end
         
     | 
| 
       166 
     | 
    
         
            -
             
     | 
| 
       167 
     | 
    
         
            -
            		# Delete a dataset
         
     | 
| 
       168 
     | 
    
         
            -
            		def delete
         
     | 
| 
       169 
     | 
    
         
            -
              		resource = RestClient::Resource.new(@uri, :user => @@users[:users].keys[0], :password => @@users[:users].values[0])
         
     | 
| 
       170 
     | 
    
         
            -
                  resource.delete
         
     | 
| 
      
 179 
     | 
    
         
            +
                def init_dirty_features(owl)
         
     | 
| 
      
 180 
     | 
    
         
            +
                  @dirty_features = @features
         
     | 
| 
      
 181 
     | 
    
         
            +
                  @owl = owl
         
     | 
| 
       171 
182 
     | 
    
         
             
                end
         
     | 
| 
      
 183 
     | 
    
         
            +
              end
         
     | 
| 
       172 
184 
     | 
    
         | 
| 
       173 
     | 
    
         
            -
            		def to_owl
         
     | 
| 
       174 
     | 
    
         
            -
            		end
         
     | 
| 
       175 
     | 
    
         
            -
             
     | 
| 
       176 
     | 
    
         
            -
            		def from_owl
         
     | 
| 
       177 
     | 
    
         
            -
            		end
         
     | 
| 
       178 
     | 
    
         
            -
             
     | 
| 
       179 
     | 
    
         
            -
            =end
         
     | 
| 
       180 
     | 
    
         
            -
            	end
         
     | 
| 
       181 
185 
     | 
    
         | 
| 
       182 
186 
     | 
    
         
             
            end
         
     | 
    
        data/lib/environment.rb
    CHANGED
    
    | 
         @@ -40,10 +40,77 @@ if @@config[:database] 
     | 
|
| 
       40 
40 
     | 
    
         
             
            	end
         
     | 
| 
       41 
41 
     | 
    
         
             
            end
         
     | 
| 
       42 
42 
     | 
    
         | 
| 
      
 43 
     | 
    
         
            +
            # mail for error messages
         
     | 
| 
      
 44 
     | 
    
         
            +
            load File.join config_dir,"mail.rb" if File.exists?(File.join config_dir,"mail.rb")
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
            # hack: store sinatra in global var to make url_for and halt methods accessible
         
     | 
| 
      
 47 
     | 
    
         
            +
            before {$sinatra = self unless $sinatra}
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
            class Sinatra::Base
         
     | 
| 
      
 50 
     | 
    
         
            +
              # overwriting halt to log halts (!= 202)
         
     | 
| 
      
 51 
     | 
    
         
            +
              def halt(*response)
         
     | 
| 
      
 52 
     | 
    
         
            +
                LOGGER.error "halt "+response.first.to_s+" "+(response.size>1 ? response[1].to_s : "") if response and response.first and response.first >= 300
         
     | 
| 
      
 53 
     | 
    
         
            +
                # orig sinatra code:
         
     | 
| 
      
 54 
     | 
    
         
            +
                response = response.first if response.length == 1
         
     | 
| 
      
 55 
     | 
    
         
            +
                throw :halt, response
         
     | 
| 
      
 56 
     | 
    
         
            +
              end
         
     | 
| 
      
 57 
     | 
    
         
            +
            end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
       43 
59 
     | 
    
         
             
            # logging
         
     | 
| 
      
 60 
     | 
    
         
            +
            class MyLogger < Logger
         
     | 
| 
      
 61 
     | 
    
         
            +
              
         
     | 
| 
      
 62 
     | 
    
         
            +
              def pwd
         
     | 
| 
      
 63 
     | 
    
         
            +
                path = Dir.pwd.to_s
         
     | 
| 
      
 64 
     | 
    
         
            +
                index = path.rindex(/\//)
         
     | 
| 
      
 65 
     | 
    
         
            +
                return path if index==nil
         
     | 
| 
      
 66 
     | 
    
         
            +
                path[(index+1)..-1]
         
     | 
| 
      
 67 
     | 
    
         
            +
              end
         
     | 
| 
      
 68 
     | 
    
         
            +
              
         
     | 
| 
      
 69 
     | 
    
         
            +
              def trace()
         
     | 
| 
      
 70 
     | 
    
         
            +
                lines = caller(0)
         
     | 
| 
      
 71 
     | 
    
         
            +
                n = 2
         
     | 
| 
      
 72 
     | 
    
         
            +
                line = lines[n]
         
     | 
| 
      
 73 
     | 
    
         
            +
                
         
     | 
| 
      
 74 
     | 
    
         
            +
                while (line =~ /spork.rb/ or line =~ /as_task/ or line =~ /environment.rb/)
         
     | 
| 
      
 75 
     | 
    
         
            +
                  n += 1
         
     | 
| 
      
 76 
     | 
    
         
            +
                  line = lines[n]
         
     | 
| 
      
 77 
     | 
    
         
            +
                end
         
     | 
| 
      
 78 
     | 
    
         
            +
              
         
     | 
| 
      
 79 
     | 
    
         
            +
                index = line.rindex(/\/.*\.rb/)
         
     | 
| 
      
 80 
     | 
    
         
            +
                return line if index==nil
         
     | 
| 
      
 81 
     | 
    
         
            +
                line[index..-1]
         
     | 
| 
      
 82 
     | 
    
         
            +
              end
         
     | 
| 
      
 83 
     | 
    
         
            +
              
         
     | 
| 
      
 84 
     | 
    
         
            +
              def format(msg)
         
     | 
| 
      
 85 
     | 
    
         
            +
                pwd.ljust(18)+" :: "+msg.to_s+"           :: "+trace+" :: "+ENV['REMOTE_ADDR'].to_s
         
     | 
| 
      
 86 
     | 
    
         
            +
              end
         
     | 
| 
      
 87 
     | 
    
         
            +
              
         
     | 
| 
      
 88 
     | 
    
         
            +
              def debug(msg)
         
     | 
| 
      
 89 
     | 
    
         
            +
                super format(msg)
         
     | 
| 
      
 90 
     | 
    
         
            +
              end
         
     | 
| 
      
 91 
     | 
    
         
            +
              
         
     | 
| 
      
 92 
     | 
    
         
            +
              def info(msg)
         
     | 
| 
      
 93 
     | 
    
         
            +
                super format(msg)
         
     | 
| 
      
 94 
     | 
    
         
            +
              end
         
     | 
| 
      
 95 
     | 
    
         
            +
              
         
     | 
| 
      
 96 
     | 
    
         
            +
              def warn(msg)
         
     | 
| 
      
 97 
     | 
    
         
            +
                super format(msg)
         
     | 
| 
      
 98 
     | 
    
         
            +
              end
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
              def error(msg)
         
     | 
| 
      
 101 
     | 
    
         
            +
                super format(msg)
         
     | 
| 
      
 102 
     | 
    
         
            +
              end
         
     | 
| 
      
 103 
     | 
    
         
            +
             
     | 
| 
      
 104 
     | 
    
         
            +
            end
         
     | 
| 
      
 105 
     | 
    
         
            +
             
     | 
| 
      
 106 
     | 
    
         
            +
             
     | 
| 
       44 
107 
     | 
    
         
             
            logfile = "#{LOG_DIR}/#{ENV["RACK_ENV"]}.log"
         
     | 
| 
       45 
     | 
    
         
            -
            LOGGER =  
     | 
| 
       46 
     | 
    
         
            -
             
     | 
| 
      
 108 
     | 
    
         
            +
            LOGGER = MyLogger.new(logfile,'daily') # daily rotation
         
     | 
| 
      
 109 
     | 
    
         
            +
             
     | 
| 
      
 110 
     | 
    
         
            +
            #LOGGER = MyLogger.new(STDOUT)
         
     | 
| 
      
 111 
     | 
    
         
            +
            #LOGGER.datetime_format = "%Y-%m-%d %H:%M:%S "
         
     | 
| 
      
 112 
     | 
    
         
            +
             
     | 
| 
      
 113 
     | 
    
         
            +
            #LOGGER.level = Logger::DEBUG
         
     | 
| 
       47 
114 
     | 
    
         | 
| 
       48 
115 
     | 
    
         
             
            if File.exist?(user_file)
         
     | 
| 
       49 
116 
     | 
    
         
             
              @@users = YAML.load_file(user_file)
         
     | 
| 
         @@ -56,8 +123,7 @@ end 
     | 
|
| 
       56 
123 
     | 
    
         
             
            begin
         
     | 
| 
       57 
124 
     | 
    
         
             
              0 < @@users[:users].keys.length
         
     | 
| 
       58 
125 
     | 
    
         
             
            rescue
         
     | 
| 
       59 
     | 
    
         
            -
               
     | 
| 
       60 
     | 
    
         
            -
              exit
         
     | 
| 
      
 126 
     | 
    
         
            +
              raise "Please edit #{user_file} and restart your application. Create at least one user with password."
         
     | 
| 
       61 
127 
     | 
    
         
             
            end
         
     | 
| 
       62 
128 
     | 
    
         | 
| 
       63 
129 
     | 
    
         
             
            # RDF namespaces
         
     | 
| 
         @@ -65,7 +131,12 @@ RDF = Redland::Namespace.new 'http://www.w3.org/1999/02/22-rdf-syntax-ns#' 
     | 
|
| 
       65 
131 
     | 
    
         
             
            OWL = Redland::Namespace.new 'http://www.w3.org/2002/07/owl#'
         
     | 
| 
       66 
132 
     | 
    
         
             
            DC = Redland::Namespace.new 'http://purl.org/dc/elements/1.1/'
         
     | 
| 
       67 
133 
     | 
    
         
             
            OT = Redland::Namespace.new 'http://www.opentox.org/api/1.1#'
         
     | 
| 
      
 134 
     | 
    
         
            +
            XML = Redland::Namespace.new 'http://www.w3.org/2001/XMLSchema#'
         
     | 
| 
       68 
135 
     | 
    
         | 
| 
       69 
136 
     | 
    
         
             
            # Regular expressions for parsing classification data
         
     | 
| 
       70 
     | 
    
         
            -
            TRUE_REGEXP = /^(true|active 
     | 
| 
       71 
     | 
    
         
            -
            FALSE_REGEXP = /^(false|inactive 
     | 
| 
      
 137 
     | 
    
         
            +
            TRUE_REGEXP = /^(true|active|$1^)/
         
     | 
| 
      
 138 
     | 
    
         
            +
            FALSE_REGEXP = /^(false|inactive|$0^)/
         
     | 
| 
      
 139 
     | 
    
         
            +
             
     | 
| 
      
 140 
     | 
    
         
            +
            # Task durations
         
     | 
| 
      
 141 
     | 
    
         
            +
            DEFAULT_TASK_MAX_DURATION = @@config[:default_task_max_duration]
         
     | 
| 
      
 142 
     | 
    
         
            +
            EXTERNAL_TASK_MAX_DURATION = @@config[:external_task_max_duration]
         
     |