genevalidatorapp 1.4.13 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
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