genevalidatorapp 1.4.13 → 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.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/Rakefile +5 -1
  4. data/bin/genevalidatorapp +227 -73
  5. data/config.ru +1 -1
  6. data/genevalidatorapp.gemspec +7 -6
  7. data/lib/genevalidatorapp.rb +247 -0
  8. data/lib/{GeneValidatorApp → genevalidatorapp}/config.rb +7 -6
  9. data/lib/{GeneValidatorApp → genevalidatorapp}/database.rb +8 -13
  10. data/lib/genevalidatorapp/exceptions.rb +162 -0
  11. data/lib/{GeneValidatorApp → genevalidatorapp}/genevalidator.rb +52 -58
  12. data/lib/{GeneValidatorApp → genevalidatorapp}/logger.rb +0 -0
  13. data/lib/genevalidatorapp/routes.rb +81 -0
  14. data/lib/genevalidatorapp/server.rb +63 -0
  15. data/lib/{GeneValidatorApp → genevalidatorapp}/version.rb +1 -1
  16. data/public/{web_files → src}/css/bootstrap1.min.css +0 -0
  17. data/public/{web_files → src}/css/custom.css +8 -13
  18. data/public/{web_files → src}/css/custom.min.css +0 -0
  19. data/public/{web_files → src}/css/font-awesome.min.css +0 -0
  20. data/public/{web_files → src}/js/bionode-seq.min.js +0 -0
  21. data/public/{web_files → src}/js/bootstrap.min.js +0 -0
  22. data/public/{web_files → src}/js/d3.v3.min.js +0 -0
  23. data/public/{web_files → src}/js/genevalidator.js +44 -49
  24. data/public/{web_files → src}/js/jquery.cookie.min.js +0 -0
  25. data/public/{web_files → src}/js/jquery.min.js +0 -0
  26. data/public/{web_files → src}/js/jquery.tablesorter.min.js +0 -0
  27. data/public/{web_files → src}/js/jquery.validate.min.js +0 -0
  28. data/public/src/js/plots.js +814 -0
  29. data/public/web_files/css/GV_compiled_css.min.css +15 -0
  30. data/public/web_files/js/GV_compiled_js.min.js +34 -0
  31. data/spec/app_spec.rb +1 -1
  32. data/spec/database_spec.rb +2 -2
  33. data/views/index.slim +1 -1
  34. data/views/layout.slim +15 -24
  35. data/views/results.slim +54 -0
  36. metadata +39 -35
  37. data/lib/GeneValidatorApp.rb +0 -321
  38. data/public/web_files/css/bootstrap.min.css +0 -7
  39. data/public/web_files/js/genevalidator.min.js +0 -1
  40. data/public/web_files/js/plots.js +0 -744
  41. data/public/web_files/js/plots.min.js +0 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 11532c47e62fd41b42b9c9ce29f1412fce64287a
4
- data.tar.gz: df79d9d63cb7c01e876fb25966033eb366aad0a3
3
+ metadata.gz: d5a4eadc8917e5ba9cd4a86f33e26c70f8b6669e
4
+ data.tar.gz: 955917782eaef7878239553f37824895cbf92eb3
5
5
  SHA512:
6
- metadata.gz: 01b1631e391d51d2c0dc127cf840d12e5bd63a647e1659f95dfde57854529f8394e8a529490f0cb0739999c902d3f7aaeec0285a2cd4fc155a77bda36aa4f542
7
- data.tar.gz: 9b3b9970a7a20483efecea122baa35b0bf2e135b434f8085ad0b2b70a1403fa1ceff384b0e6917284d6286d94425733126bd5d35bb2780e74867313b3a329f0c
6
+ metadata.gz: b55edc8bcd0f93f1061b1aec961f73d5614c676a6f92656a2af12776a6a0daf6aac315f9daefc79773740cbf914c8a34503db7683d0895ae3188f6d8bf418ba3
7
+ data.tar.gz: d748fcf3753c9025ca278782ec7a9fe42286010593e97b6703d40c500e0d40710dc7c437dccc8c517c2e0eb18f7621e37bbbfd42703fbb6d0948928ca51086ba
data/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  # GeneValidatorApp
2
- [![Build Status](https://travis-ci.org/wurmlab/GeneValidatorApp.svg?branch=master)](https://travis-ci.org/wurmlab/GeneValidatorApp)
2
+ [![Build Status](https://travis-ci.org/wurmlab/genevalidatorapp.svg?branch=master)](https://travis-ci.org/wurmlab/genevalidatorapp)
3
3
  [![Gem Version](https://badge.fury.io/rb/GeneValidatorApp.svg)](http://badge.fury.io/rb/GeneValidatorApp)
4
4
  [![Dependency Status](https://gemnasium.com/wurmlab/GeneValidatorApp.svg)](https://gemnasium.com/wurmlab/GeneValidatorApp)
5
5
  [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/wurmlab/GeneValidatorApp/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/wurmlab/GeneValidatorApp/?branch=master)
data/Rakefile CHANGED
@@ -5,7 +5,11 @@ require 'rspec/core/rake_task'
5
5
  task default: [:build]
6
6
  desc 'Installs the ruby gem'
7
7
  task :build do
8
- exec("gem build genevalidatorapp.gemspec && gem install ./genevalidatorapp-#{GeneValidatorApp::VERSION}.gem")
8
+ lib = File.expand_path('../lib', __FILE__)
9
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
10
+ require 'genevalidatorapp/version'
11
+ exec('gem build genevalidatorapp.gemspec &&'\
12
+ " gem install ./genevalidatorapp-#{GeneValidatorApp::VERSION}.gem")
9
13
  end
10
14
 
11
15
  task test: :spec
@@ -1,4 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
+ require 'readline'
3
+ require 'English'
2
4
  require 'slop'
3
5
 
4
6
  ENV['RACK_ENV'] ||= 'production'
@@ -6,9 +8,9 @@ ENV['RACK_ENV'] ||= 'production'
6
8
  # display name for tools like `ps`
7
9
  $PROGRAM_NAME = 'genevalidatorapp'
8
10
 
9
- opts = Slop.parse do |o|
10
- o.banner = <<BNR
11
-
11
+ begin
12
+ Slop.parse!(strict: true, help: true) do
13
+ banner <<BANNER
12
14
  SUMMARY:
13
15
  GeneValidator - Identify problems with predicted genes
14
16
 
@@ -24,99 +26,251 @@ Examples:
24
26
 
25
27
  # Create a config file with the other arguments
26
28
  $ genevalidatorapp -s -d ~/database_dir
27
- BNR
28
29
 
29
- o.separator 'Compulsory Argument, unless set in a config file'
30
+ BANNER
31
+ # - Add Web_dir ? or simply default to ~/.genevalidatorapp/runs/
30
32
 
31
- o.string '-d', '--database_dir',
32
- 'Read BLAST database from this directory'
33
+ on 'c', 'config_file=',
34
+ 'Use the given configuration file',
35
+ argument: true
33
36
 
34
- o.separator ''
35
- o.separator 'Optional Arguments'
37
+ on 'b', 'bin=',
38
+ 'Load BLAST+ and/or BLAST binaries from this directory',
39
+ argument: true,
40
+ as: Array
36
41
 
37
- o.string '-f', '--default_db',
38
- 'The Path to the the default database'
42
+ on 'd', 'database_dir=',
43
+ 'Read BLAST database from this directory',
44
+ argument: true
39
45
 
40
- o.string '-n', '--num_threads',
41
- 'Number of threads to use to run a BLAST search'
46
+ on 'f', 'default_database_path=',
47
+ 'The path to the default BLAST database',
48
+ argument: true
42
49
 
43
- o.string '-c', '--config_file',
44
- 'Use the given configuration file'
50
+ on 'n', 'num_threads=',
51
+ 'Number of threads to use to run a BLAST search',
52
+ argument: true
45
53
 
46
- o.string '-r', '--require',
47
- 'Load extension from this file'
54
+ on 'r', 'require=',
55
+ 'Load extension from this file',
56
+ argument: true
48
57
 
49
- o.string '--host',
50
- 'Host to run GeneValidatorApp on'
58
+ on 'H', 'host=',
59
+ 'Host to run GeneValidatorApp on',
60
+ argument: true
51
61
 
52
- o.string '-p', '--port',
53
- 'Port to run GeneValidatorApp on'
62
+ on 'p', 'port=',
63
+ 'Port to run GeneValidatorApp on',
64
+ argument: true
54
65
 
55
- o.string '-s', '--set',
56
- 'Set configuration value in the config file'
66
+ on 's', 'set',
67
+ 'Set configuration value in default or given config file'
57
68
 
58
- o.string '-l', '--list_dbs',
59
- 'List BLAST databases'
69
+ on 'l', 'list_databases',
70
+ 'List BLAST databases'
60
71
 
61
- o.string '-b', '--blast_bin',
62
- 'Load BLAST+ binaries from this directory'
72
+ on 'D', 'devel',
73
+ 'Start GeneValidatorApp in development mode'
63
74
 
64
- o.string '-m', '--mafft_bin',
65
- 'Load Mafft binaries from this directory'
75
+ on '-v', '--version',
76
+ 'Print version number of GeneValidatorApp that will be loaded'
66
77
 
67
- o.string '-w', '--web_dir',
68
- 'Path to the web directory (contains ' \
69
- 'supporting files utilised by the app).'
78
+ on '-h', '--help',
79
+ 'Display this help message'
70
80
 
71
- o.bool '-D', '--devel',
72
- 'Start GeneValidatorApp in development mode'
81
+ clean_opts = lambda do |hash|
82
+ hash.delete_if { |k, v| k == :set || v.nil? }
83
+ hash
84
+ end
73
85
 
74
- o.bool '-v', '--version',
75
- 'Print version number of GeneValidatorApp that will be loaded'
86
+ run do
87
+ if version?
88
+ require 'genevalidatorapp/version'
89
+ puts GeneValidatorApp::VERSION
90
+ exit
91
+ end
76
92
 
77
- o.on '-h', '--help',
78
- 'Display this help message'
79
- end
93
+ ENV['RACK_ENV'] = 'development' if devel?
80
94
 
81
- if opts.help?
82
- puts opts
83
- exit
84
- end
95
+ # Exit gracefully on SIGINT.
96
+ stty = `stty -g`.chomp
97
+ trap('INT') do
98
+ puts ''
99
+ puts 'Aborted.'
100
+ system('stty', stty)
101
+ exit
102
+ end
85
103
 
86
- if opts.version?
87
- require 'GeneValidatorApp/version'
88
- puts GeneValidatorApp::VERSION
89
- exit
90
- end
104
+ require 'genevalidatorapp'
91
105
 
92
- ENV['RACK_ENV'] = 'development' if opts.devel?
106
+ begin
107
+ GeneValidatorApp.init clean_opts[to_h]
93
108
 
94
- # Exit gracefully on SIGINT.
95
- stty = `stty -g`.chomp
96
- trap('INT') do
97
- puts ''
98
- puts 'Aborted.'
99
- system('stty', stty)
100
- exit
101
- end
109
+ # The aim of following error recovery scenarios is to guide user to a
110
+ # working GeneValidatorApp installation. We expect to land following
111
+ # error scenarios either when creating a new GeneValidatorApp (first
112
+ # time or later), or updating config values using -s CLI option.
102
113
 
103
- clean_opts = lambda do |hash|
104
- hash.delete_if { |k, v| k == :set || k == :version || v.nil? }
105
- hash
106
- end
114
+ rescue GeneValidatorApp::CONFIG_FILE_ERROR,
115
+ GeneValidatorApp::BLAST_DATABASE_ERROR => e
107
116
 
108
- require 'GeneValidatorApp'
109
- begin
110
- GeneValidatorApp.init clean_opts[opts.to_hash]
111
- rescue SystemExit => e
112
- puts '*** Error: GeneValidator failed to initialise properly.'
113
- puts ' Please check all paramaters and try again.'
114
- puts ' See https://github.com/IsmailM/GeneValidatorApp for more help'
115
- exit e.status
116
- end
117
+ puts e
118
+ exit!
117
119
 
118
- puts GeneValidatorApp::Database.all? if opts.list_databases?
120
+ rescue GeneValidatorApp::BIN_DIR_NOT_FOUND => e
119
121
 
120
- GeneValidatorApp.send(:write_config_file) if opts.set?
122
+ puts e
121
123
 
122
- GeneValidatorApp.run
124
+ unless bin?
125
+ puts 'You can set the correct value by running:'
126
+ puts
127
+ puts ' genevalidatorapp -s -b <value>'
128
+ puts
129
+ end
130
+
131
+ exit!
132
+
133
+ rescue GeneValidatorApp::DATABASE_DIR_NOT_FOUND => e
134
+
135
+ puts e
136
+
137
+ unless database_dir?
138
+ puts 'You can set the correct value by running:'
139
+ puts
140
+ puts ' genevalidatorapp -s -d <value>'
141
+ puts
142
+ end
143
+
144
+ exit!
145
+
146
+ rescue GeneValidatorApp::NUM_THREADS_INCORRECT => e
147
+
148
+ puts e
149
+
150
+ unless num_threads?
151
+ puts 'You can set the correct value by running:'
152
+ puts
153
+ puts ' genevalidatorapp -s -n <value>'
154
+ puts
155
+ end
156
+
157
+ exit!
158
+
159
+ rescue GeneValidatorApp::EXTENSION_FILE_NOT_FOUND => e
160
+
161
+ puts e
162
+
163
+ unless require?
164
+ puts 'You can set the correct value by running:'
165
+ puts
166
+ puts ' genevalidatorapp -s -r <value>'
167
+ puts
168
+ end
169
+
170
+ exit!
171
+
172
+ rescue GeneValidatorApp::BLAST_NOT_INSTALLED,
173
+ GeneValidatorApp::BLAST_NOT_EXECUTABLE,
174
+ GeneValidatorApp::BLAST_NOT_COMPATIBLE => e
175
+
176
+ # Show original error message first.
177
+ puts
178
+ puts e
179
+
180
+ # Set a flag so that if we recovered from error resulting config can be
181
+ # saved. Config will be saved unless invoked with -b option.
182
+ fetch_option(:set).value = !bin?
183
+
184
+ # Ask user if she already has BLAST+ downloaded.
185
+ puts
186
+ puts <<MSG
187
+ GeneValidatorApp can use NCBI BLAST+ that you may have on your system already,
188
+ or download the correct package for itself.
189
+ Please enter the path to NCBI BLAST+.
190
+
191
+ Press Ctrl+C to quit.
192
+ MSG
193
+ puts
194
+ response = Readline.readline('>> ').to_s.strip
195
+ unless response.empty?
196
+ unless File.basename(response) == 'bin'
197
+ response = File.join(response, 'bin')
198
+ end
199
+ fetch_option(:bin).value = File.join(response)
200
+ puts
201
+ redo
202
+ end
203
+
204
+ rescue GeneValidatorApp::DATABASE_DIR_NOT_SET => e
205
+
206
+ # Show original error message.
207
+ puts
208
+ puts e
209
+
210
+ # Set a flag so that if we recovered from error resulting config can be
211
+ # saved. Config will be saved unless invoked with -d option.
212
+ fetch_option(:set).value = !database_dir?
213
+
214
+ # Ask user for the directory containing sequences or BLAST+
215
+ # databases.
216
+ puts
217
+ puts <<MSG
218
+ GeneValidatorApp needs to know where your BLAST+ databases are.
219
+ Please enter the path to the relevant directory.
220
+
221
+ Press Ctrl+C to quit.
222
+ MSG
223
+
224
+ puts
225
+ response = Readline.readline('>> ').to_s.strip
226
+ fetch_option(:database_dir).value = response
227
+ redo
228
+
229
+ rescue GeneValidatorApp::NO_BLAST_DATABASE_FOUND => e
230
+ unless list_databases?
231
+
232
+ # Print error raised.
233
+ puts
234
+ puts e
235
+
236
+ end
237
+
238
+ rescue => e
239
+ # This will catch any unhandled error and some very special errors.
240
+ # Ideally we will never hit this block. If we do, there's a bug in
241
+ # GeneValidatorApp or something really weird going on. If we hit this
242
+ # error block we show the stacktrace to the user requesting them to
243
+ # post the same to our Google Group.
244
+ puts <<MSG
245
+ Something went wonky
246
+
247
+ Looks like you have encountered a bug in GeneValidatorApp. Please could you
248
+ report this incident here -
249
+ https://github.com/wurmlab/genevalidatorapp/issues
250
+
251
+ Error:
252
+ #{e.backtrace.unshift(e.message).join("\n")}
253
+ MSG
254
+ exit
255
+ end
256
+
257
+ if list_databases?
258
+ puts GeneValidatorApp::Database.all
259
+ exit
260
+ end
261
+
262
+ if set?
263
+ GeneValidatorApp.config.write_config_file
264
+ exit
265
+ end
266
+
267
+ GeneValidatorApp.config.write_config_file if fetch_option(:set).value
268
+
269
+ GeneValidatorApp.run
270
+ end
271
+ end
272
+ rescue Slop::Error => e
273
+ puts e
274
+ puts "Run '#{$PROGRAM_NAME} -h' for help with command line options."
275
+ exit
276
+ end
data/config.ru CHANGED
@@ -1,3 +1,3 @@
1
- require 'GeneValidatorApp'
1
+ require 'genevalidatorapp'
2
2
  GeneValidatorApp.init
3
3
  run GeneValidatorApp
@@ -1,7 +1,7 @@
1
1
  # coding: utf-8
2
2
  lib = File.expand_path('../lib', __FILE__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'GeneValidatorApp/version'
4
+ require 'genevalidatorapp/version'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = 'genevalidatorapp'
@@ -9,8 +9,9 @@ Gem::Specification.new do |spec|
9
9
  spec.authors = ['Ismail Moghul']
10
10
  spec.email = ['Ismail.Moghul@gmail.com']
11
11
  spec.summary = 'A Web App wrapper for GeneValidator.'
12
- spec.description = 'A Web App wrapper for GeneValidator, a program for validating gene predictions.'
13
- spec.homepage = 'https://github.com/wurmlab/GeneValidatorApp'
12
+ spec.description = 'A Web App wrapper for GeneValidator, a program for' \
13
+ ' validating gene predictions.'
14
+ spec.homepage = 'https://github.com/wurmlab/genevalidatorapp'
14
15
  spec.license = 'AGPL'
15
16
 
16
17
  spec.files = `git ls-files -z`.split("\x0")
@@ -25,13 +26,13 @@ Gem::Specification.new do |spec|
25
26
  spec.add_development_dependency 'rspec', '~> 3.2'
26
27
  spec.add_development_dependency 'rack-test', '~> 0.6'
27
28
 
29
+ spec.add_dependency 'genevalidator', '~>1.6'
28
30
  spec.add_dependency 'bio', '~>1.4'
29
- spec.add_dependency 'genevalidator', '~>1.5'
30
31
  spec.add_dependency 'sinatra', '~>1.4'
31
32
  spec.add_dependency 'sinatra-contrib', '~>1.4'
32
33
  spec.add_dependency 'sinatra-cross_origin', '~> 0.3'
33
34
  spec.add_dependency 'slim', '~>3.0'
34
- spec.add_dependency 'slop', '~>4.0'
35
+ spec.add_dependency 'slop', '~>3.6'
35
36
  spec.add_dependency 'thin', '~>1.6'
36
37
  spec.add_dependency 'w3c_validators', '~>1.1'
37
38
  spec.post_install_message = <<INFO
@@ -43,7 +44,7 @@ Gem::Specification.new do |spec|
43
44
 
44
45
  $ genevalidatorapp [options]
45
46
 
46
- Visit https://github.com/wurmlab/GeneValidatorApp for more information.
47
+ Visit https://github.com/wurmlab/genevalidatorapp for more information.
47
48
  ------------------------------------------------------------------------
48
49
 
49
50
  INFO
@@ -0,0 +1,247 @@
1
+ require 'yaml'
2
+ require 'fileutils'
3
+
4
+ require 'genevalidatorapp/config'
5
+ require 'genevalidatorapp/database'
6
+ require 'genevalidatorapp/exceptions'
7
+ require 'genevalidatorapp/genevalidator'
8
+ require 'genevalidatorapp/logger'
9
+ require 'genevalidatorapp/routes'
10
+ require 'genevalidatorapp/server'
11
+ require 'genevalidatorapp/version'
12
+
13
+ module GeneValidatorApp
14
+ # Use a fixed minimum version of BLAST+
15
+ MINIMUM_BLAST_VERSION = '2.2.30+'
16
+
17
+ class << self
18
+ def environment
19
+ ENV['RACK_ENV']
20
+ end
21
+
22
+ def verbose?
23
+ @verbose ||= (environment == 'development')
24
+ end
25
+
26
+ def root
27
+ File.dirname(File.dirname(__FILE__))
28
+ end
29
+
30
+ def logger
31
+ @logger ||= Logger.new(STDERR, verbose?)
32
+ end
33
+
34
+ # Setting up the environment before running the app...
35
+ def init(config = {})
36
+ @config = Config.new(config)
37
+
38
+ init_binaries
39
+ init_database
40
+
41
+ check_dirs
42
+ init_gv_tempdir
43
+ init_public_dir
44
+
45
+ load_extension
46
+ check_num_threads
47
+ check_max_characters
48
+ self
49
+ end
50
+
51
+ attr_reader :config, :temp_dir, :public_dir
52
+
53
+ # Starting the app manually
54
+ def run
55
+ check_host
56
+ Server.run(self)
57
+ rescue Errno::EADDRINUSE
58
+ puts "** Could not bind to port #{config[:port]}."
59
+ puts " Is GeneValidator already accessible at #{server_url}?"
60
+ puts ' No? Try running GeneValidator on another port, like so:'
61
+ puts
62
+ puts ' genevalidatorapp -p 4570.'
63
+ rescue Errno::EACCES
64
+ puts "** Need root privilege to bind to port #{config[:port]}."
65
+ puts ' It is not advisable to run GeneValidator as root.'
66
+ puts ' Please use Apache/Nginx to bind to a privileged port.'
67
+ end
68
+
69
+ def on_start
70
+ puts '** GeneValidator is ready.'
71
+ puts " Go to #{server_url} in your browser and start analysing genes!"
72
+ puts ' Press CTRL+C to quit.'
73
+ open_in_browser(server_url)
74
+ end
75
+
76
+ def on_stop
77
+ puts
78
+ puts '** Thank you for using GeneValidatorApp :).'
79
+ puts ' Please cite: '
80
+ puts ' Dragan M., Moghul M.I., Priyam A., Wurm Y (in prep).'
81
+ puts ' GeneValidator: identify problematic gene predictions.'
82
+ end
83
+
84
+ # Rack-interface.
85
+ #
86
+ # Inject our logger in the env and dispatch request to our controller.
87
+ def call(env)
88
+ env['rack.logger'] = logger
89
+ Routes.call(env)
90
+ end
91
+
92
+ private
93
+
94
+ def check_dirs
95
+ config[:gv_app_dir] = File.expand_path(config[:gv_app_dir])
96
+ unique_run_id = 'GV_' + "#{Time.now.strftime('%Y%m%d-%H-%M-%S')}"
97
+ @public_dir = File.join(config[:gv_app_dir], unique_run_id)
98
+ FileUtils.mkdir_p(File.join(@public_dir, 'GeneValidator'))
99
+ end
100
+
101
+ # Creates a Temp directory (starting with 'GeneValidator_') each time
102
+ # GVapp is started. Within this Temp folder, sub directories are created
103
+ # in which GeneValidator is run.
104
+ def init_gv_tempdir
105
+ @temp_dir = Dir.mktmpdir('GeneValidator_')
106
+ end
107
+
108
+ # Copy the public folder (in the app root) to the gv_app_dir location - this
109
+ # gv_app_dir is then used by the app to serve all dependencies...
110
+ def init_public_dir
111
+ root_web_files_dir = File.join(GeneValidatorApp.root, 'public/web_files')
112
+ FileUtils.cp_r(root_web_files_dir, @public_dir)
113
+ end
114
+
115
+ def init_binaries
116
+ config[:bin] = init_bins if config[:bin]
117
+ assert_blast_installed_and_compatible
118
+ assert_mafft_installed
119
+ end
120
+
121
+ def init_database
122
+ fail DATABASE_DIR_NOT_SET unless config[:database_dir]
123
+
124
+ config[:database_dir] = File.expand_path(config[:database_dir])
125
+ unless File.exist?(config[:database_dir]) &&
126
+ File.directory?(config[:database_dir])
127
+ fail DATABASE_DIR_NOT_FOUND, config[:database_dir]
128
+ end
129
+
130
+ assert_blast_databases_present_in_database_dir
131
+ logger.debug("Will use BLAST+ databases at: #{config[:database_dir]}")
132
+
133
+ Database.scan_databases_dir
134
+ Database.each do |database|
135
+ logger.debug("Found #{database.type.chomp} database" \
136
+ " '#{database.title.chomp}' at '#{database.name.chomp}'")
137
+ end
138
+ end
139
+
140
+ def load_extension
141
+ return unless config[:require]
142
+ config[:require] = File.expand_path config[:require]
143
+ unless File.exist?(config[:require]) && File.file?(config[:require])
144
+ fail EXTENSION_FILE_NOT_FOUND, config[:require]
145
+ end
146
+
147
+ logger.debug("Loading extension: #{config[:require]}")
148
+ require config[:require]
149
+ end
150
+
151
+ def assert_blast_databases_present_in_database_dir
152
+ cmd = "blastdbcmd -recursive -list #{config[:database_dir]}"
153
+ out = `#{cmd}`
154
+ errpat = /BLAST Database error/
155
+ fail NO_BLAST_DATABASE_FOUND, config[:database_dir] if out.empty?
156
+ fail BLAST_DATABASE_ERROR, cmd, out if out.match(errpat) ||
157
+ !$CHILD_STATUS.success?
158
+ end
159
+
160
+ def check_num_threads
161
+ num_threads = Integer(config[:num_threads])
162
+ fail NUM_THREADS_INCORRECT unless num_threads > 0
163
+
164
+ logger.debug "Will use #{num_threads} threads to run BLAST."
165
+ if num_threads > 256
166
+ logger.warn "Number of threads set at #{num_threads} is unusually high."
167
+ end
168
+ rescue
169
+ raise NUM_THREADS_INCORRECT
170
+ end
171
+
172
+ def check_max_characters
173
+ if config[:max_characters] != 'undefined'
174
+ config[:max_characters] = Integer(config[:max_characters])
175
+ end
176
+ rescue
177
+ raise MAX_CHARACTERS_INCORRECT
178
+ end
179
+
180
+ def init_bins
181
+ bins = []
182
+ config[:bin].each do |bin|
183
+ bins << File.expand_path(bin)
184
+ unless File.exist?(bin) && File.directory?(bin)
185
+ fail BIN_DIR_NOT_FOUND, config[:bin]
186
+ end
187
+ export_bin_dir(bin)
188
+ end
189
+ bins
190
+ end
191
+
192
+ ## Checks if dir is in $PATH and if not, it adds the dir to the $PATH.
193
+ def export_bin_dir(bin_dir)
194
+ return unless bin_dir
195
+ return if ENV['PATH'].split(':').include?(bin_dir)
196
+ ENV['PATH'] = "#{bin_dir}:#{ENV['PATH']}"
197
+ end
198
+
199
+ def assert_blast_installed_and_compatible
200
+ fail BLAST_NOT_INSTALLED unless command? 'blastdbcmd'
201
+ version = `blastdbcmd -version`.split[1]
202
+ fail BLAST_NOT_COMPATIBLE, version unless version >= MINIMUM_BLAST_VERSION
203
+ end
204
+
205
+ def assert_mafft_installed
206
+ fail MAFFT_NOT_INSTALLED unless command? 'mafft'
207
+ end
208
+
209
+ # Check and warn user if host is 0.0.0.0 (default).
210
+ def check_host
211
+ # rubocop:disable Style/GuardClause
212
+ if config[:host] == '0.0.0.0'
213
+ logger.warn 'Will listen on all interfaces (0.0.0.0).' \
214
+ ' Consider using 127.0.0.1 (--host option).'
215
+ end
216
+ # rubocop:enable Style/GuardClause
217
+ end
218
+
219
+ def server_url
220
+ host = config[:host]
221
+ host = 'localhost' if host == '127.0.0.1' || host == '0.0.0.0'
222
+ "http://#{host}:#{config[:port]}"
223
+ end
224
+
225
+ def open_in_browser(server_url)
226
+ return if using_ssh? || verbose?
227
+ if RUBY_PLATFORM =~ /linux/ && xdg?
228
+ `xdg-open #{server_url}`
229
+ elsif RUBY_PLATFORM =~ /darwin/
230
+ `open #{server_url}`
231
+ end
232
+ end
233
+
234
+ def using_ssh?
235
+ true if ENV['SSH_CLIENT'] || ENV['SSH_TTY'] || ENV['SSH_CONNECTION']
236
+ end
237
+
238
+ def xdg?
239
+ true if ENV['DISPLAY'] && command?('xdg-open')
240
+ end
241
+
242
+ # Return `true` if the given command exists and is executable.
243
+ def command?(command)
244
+ system("which #{command} > /dev/null 2>&1")
245
+ end
246
+ end
247
+ end