genevalidatorapp 1.4.12
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +24 -0
- data/.travis.yml +7 -0
- data/Gemfile +4 -0
- data/GeneValidatorApp.gemspec +50 -0
- data/LICENSE.txt +661 -0
- data/README.md +101 -0
- data/Rakefile +14 -0
- data/bin/genevalidatorapp +122 -0
- data/config.ru +3 -0
- data/lib/GeneValidatorApp.rb +321 -0
- data/lib/GeneValidatorApp/config.rb +86 -0
- data/lib/GeneValidatorApp/database.rb +114 -0
- data/lib/GeneValidatorApp/genevalidator.rb +241 -0
- data/lib/GeneValidatorApp/logger.rb +24 -0
- data/lib/GeneValidatorApp/version.rb +3 -0
- data/public/GeneValidator/.gitkeep +0 -0
- data/public/web_files/css/bootstrap.min.css +7 -0
- data/public/web_files/css/bootstrap1.min.css +7 -0
- data/public/web_files/css/custom.css +521 -0
- data/public/web_files/css/custom.min.css +3 -0
- data/public/web_files/css/font-awesome.min.css +4 -0
- data/public/web_files/fonts/FontAwesome.otf +0 -0
- data/public/web_files/fonts/fontawesome-webfont.eot +0 -0
- data/public/web_files/fonts/fontawesome-webfont.svg +504 -0
- data/public/web_files/fonts/fontawesome-webfont.ttf +0 -0
- data/public/web_files/fonts/fontawesome-webfont.woff +0 -0
- data/public/web_files/img/gene.png +0 -0
- data/public/web_files/js/bionode-seq.min.js +1 -0
- data/public/web_files/js/bootstrap.min.js +6 -0
- data/public/web_files/js/d3.v3.min.js +5 -0
- data/public/web_files/js/genevalidator.js +282 -0
- data/public/web_files/js/genevalidator.min.js +1 -0
- data/public/web_files/js/jquery.cookie.min.js +1 -0
- data/public/web_files/js/jquery.min.js +4 -0
- data/public/web_files/js/jquery.tablesorter.min.js +5 -0
- data/public/web_files/js/jquery.validate.min.js +4 -0
- data/public/web_files/js/plots.js +744 -0
- data/public/web_files/js/plots.min.js +1 -0
- data/spec/app_spec.rb +107 -0
- data/spec/database/funky_ids/funky_ids.fa +10 -0
- data/spec/database/funky_ids/funky_ids.fa.nhr +0 -0
- data/spec/database/funky_ids/funky_ids.fa.nin +0 -0
- data/spec/database/funky_ids/funky_ids.fa.nog +0 -0
- data/spec/database/funky_ids/funky_ids.fa.nsd +9 -0
- data/spec/database/funky_ids/funky_ids.fa.nsi +0 -0
- data/spec/database/funky_ids/funky_ids.fa.nsq +0 -0
- data/spec/database/sample/proteins/Solenopsis_invicta/Sinvicta2-2-3.prot.subset.fasta +6449 -0
- data/spec/database/sample/proteins/Solenopsis_invicta/Sinvicta2-2-3.prot.subset.fasta.phr +0 -0
- data/spec/database/sample/proteins/Solenopsis_invicta/Sinvicta2-2-3.prot.subset.fasta.pin +0 -0
- data/spec/database/sample/proteins/Solenopsis_invicta/Sinvicta2-2-3.prot.subset.fasta.pog +0 -0
- data/spec/database/sample/proteins/Solenopsis_invicta/Sinvicta2-2-3.prot.subset.fasta.psd +2378 -0
- data/spec/database/sample/proteins/Solenopsis_invicta/Sinvicta2-2-3.prot.subset.fasta.psi +0 -0
- data/spec/database/sample/proteins/Solenopsis_invicta/Sinvicta2-2-3.prot.subset.fasta.psq +0 -0
- data/spec/database/sample/transcripts/Solenopsis_invicta/Sinvicta2-2-3.cdna.subset.fasta +5486 -0
- data/spec/database/sample/transcripts/Solenopsis_invicta/Sinvicta2-2-3.cdna.subset.fasta.nhr +0 -0
- data/spec/database/sample/transcripts/Solenopsis_invicta/Sinvicta2-2-3.cdna.subset.fasta.nin +0 -0
- data/spec/database/sample/transcripts/Solenopsis_invicta/Sinvicta2-2-3.cdna.subset.fasta.nog +0 -0
- data/spec/database/sample/transcripts/Solenopsis_invicta/Sinvicta2-2-3.cdna.subset.fasta.nsd +946 -0
- data/spec/database/sample/transcripts/Solenopsis_invicta/Sinvicta2-2-3.cdna.subset.fasta.nsi +0 -0
- data/spec/database/sample/transcripts/Solenopsis_invicta/Sinvicta2-2-3.cdna.subset.fasta.nsq +0 -0
- data/spec/database/unformatted/Cardiocondyla_obscurior/Cobs1.4.proteins.fa +148303 -0
- data/spec/database/without_parse_seqids/without_parse_seqids.fa +10 -0
- data/spec/database/without_parse_seqids/without_parse_seqids.fa.phr +0 -0
- data/spec/database/without_parse_seqids/without_parse_seqids.fa.pin +0 -0
- data/spec/database/without_parse_seqids/without_parse_seqids.fa.psq +0 -0
- data/spec/database_spec.rb +37 -0
- data/spec/empty_config.yml +0 -0
- data/views/500.slim +5 -0
- data/views/index.slim +66 -0
- data/views/layout.slim +85 -0
- metadata +337 -0
data/README.md
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
# GeneValidatorApp
|
2
|
+
[![Build Status](https://travis-ci.org/wurmlab/GeneValidatorApp.svg?branch=master)](https://travis-ci.org/wurmlab/GeneValidatorApp)
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/GeneValidatorApp.svg)](http://badge.fury.io/rb/GeneValidatorApp)
|
4
|
+
[![Dependency Status](https://gemnasium.com/wurmlab/GeneValidatorApp.svg)](https://gemnasium.com/wurmlab/GeneValidatorApp)
|
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)
|
6
|
+
|
7
|
+
This is a Sinatra based web wrapper for [GeneValidator](https://github.com/monicadragan/GeneValidator); a program that validates gene predictions. A working example can be seen at [genevalidator.sbcs.qmul.ac.uk](http://genevalidator.sbcs.qmul.ac.uk).
|
8
|
+
|
9
|
+
If you use this program in your research, please cite us as follows:
|
10
|
+
|
11
|
+
"Dragan M, Moghul MI, Priyam A & Wurm Y (<em>in prep</em>) GeneValidator: identify problematic gene predictions"
|
12
|
+
|
13
|
+
This program was developed at [Wurm Lab](http://yannick.poulet.org), [QMUL](http://sbcs.qmul.ac.uk) with the support of a BBSRC grant.
|
14
|
+
|
15
|
+
## Installation
|
16
|
+
|
17
|
+
1) Install all GeneValidator Prerequisites (ruby <=1.9.3, Mafft, BLAST+, GSL). You would also require a BLAST database.
|
18
|
+
* Please see [here](https://gist.github.com/IsmailM/b783e8a06565197084e6) for more information.
|
19
|
+
|
20
|
+
2) Install GeneValidatorApp
|
21
|
+
|
22
|
+
$ gem install genevalidatorapp
|
23
|
+
|
24
|
+
## Usage
|
25
|
+
|
26
|
+
After installing simply type in:
|
27
|
+
|
28
|
+
$ genevalidatorapp
|
29
|
+
|
30
|
+
and then go to [http://localhost:4567](http://localhost:4567) (if on a local server and using the default port: 4567)
|
31
|
+
|
32
|
+
See `$ genevalidator -h` for more information on how to run GeneValidatorApp.
|
33
|
+
|
34
|
+
USAGE
|
35
|
+
|
36
|
+
genevalidatorapp [options]
|
37
|
+
|
38
|
+
Example
|
39
|
+
|
40
|
+
# Launch GeneValidatorApp with the given config file
|
41
|
+
$ genevalidatorapp --config ~/.genevalidatorapp.conf
|
42
|
+
|
43
|
+
# Launch GeneValidatorApp with 8 threads at port 8888
|
44
|
+
$ genevalidatorapp --num_threads 8 --port 8888
|
45
|
+
|
46
|
+
# Create a config file with the other arguments
|
47
|
+
$ genevalidatorapp -s -d ~/database_dir
|
48
|
+
|
49
|
+
Compulsory (unless set in a config file)
|
50
|
+
-d, --database_dir Read BLAST database from this directory
|
51
|
+
|
52
|
+
Optional
|
53
|
+
-f, --default_db The Path to the the default database
|
54
|
+
-n, --num_threads Number of threads to use to run a BLAST search
|
55
|
+
-c, --config_file Use the given configuration file
|
56
|
+
-r, --require Load extension from this file
|
57
|
+
-p, --port Port to run GeneValidatorApp on
|
58
|
+
-s, --set Set configuration value in default or given config file
|
59
|
+
-l, --list_databases List BLAST databases
|
60
|
+
-b, --blast_bin Load BLAST+ binaries from this directory
|
61
|
+
-m, --mafft_bin Load Mafft binaries from this directory
|
62
|
+
-D, --devel Start GeneValidatorApp in development mode
|
63
|
+
-v, --version Print version number of GeneValidatorApp that will be loaded
|
64
|
+
-h, --help Display this help message.
|
65
|
+
|
66
|
+
|
67
|
+
## Setting up a Config File
|
68
|
+
|
69
|
+
GeneValidatorApp requires a number of arguments in order to work. You can either provide these variables to the app through a config file or through command line arguments.
|
70
|
+
|
71
|
+
In order to create a config file, run genevalidator with the `-s` or `--set` argument as follows.
|
72
|
+
|
73
|
+
$ genevalidator -s -d database_dir -f default_db -n num_threads -p port -b blast_bin -m mafft_bin
|
74
|
+
|
75
|
+
The `--set` argument create a config file at `~/.genevalidatorapp.conf` using all the other arguments used. Thereafter, GeneValidatorApp will read the config file before starting the app. This means that you are not required provide the same arguments again and again.
|
76
|
+
|
77
|
+
### Config file
|
78
|
+
|
79
|
+
A config file can also be set up manually. Below is an example:
|
80
|
+
|
81
|
+
:database_dir: "/Users/ismailm/blastdb"
|
82
|
+
:default_db: "/Users/ismailm/blastdb/SwissProt"
|
83
|
+
:web_dir: "/Users/ismailm/GV"
|
84
|
+
:num_threads: 8
|
85
|
+
:port: 4567
|
86
|
+
:host: localhost
|
87
|
+
:devel: true
|
88
|
+
:blast_bin: "/Users/ismailm/blast/bin"
|
89
|
+
:mafft_bin: "/Users/ismailm/mafft/bin"
|
90
|
+
|
91
|
+
## API
|
92
|
+
|
93
|
+
See [GeneValidatorApp-API](https://github.com/IsmailM/GeneValidatorApp-API) for more information.
|
94
|
+
|
95
|
+
## Contributing
|
96
|
+
|
97
|
+
1. Fork it ( https://github.com/wurmlab/GeneValidatorApp/fork )
|
98
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
99
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
100
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
101
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'rspec/core'
|
3
|
+
require 'rspec/core/rake_task'
|
4
|
+
|
5
|
+
task default: [:build]
|
6
|
+
desc 'Installs the ruby gem'
|
7
|
+
task :build do
|
8
|
+
exec("gem build GeneValidatorApp.gemspec && gem install ./GeneValidatorApp-#{GeneValidatorApp::VERSION}.gem")
|
9
|
+
end
|
10
|
+
|
11
|
+
task test: :spec
|
12
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
13
|
+
spec.pattern = FileList['spec/**/*_spec.rb']
|
14
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'slop'
|
3
|
+
|
4
|
+
ENV['RACK_ENV'] ||= 'production'
|
5
|
+
|
6
|
+
# display name for tools like `ps`
|
7
|
+
$PROGRAM_NAME = 'genevalidatorapp'
|
8
|
+
|
9
|
+
opts = Slop.parse do |o|
|
10
|
+
o.banner = <<BNR
|
11
|
+
|
12
|
+
SUMMARY:
|
13
|
+
GeneValidator - Identify problems with predicted genes
|
14
|
+
|
15
|
+
USAGE:
|
16
|
+
$ genevalidatorapp [options]
|
17
|
+
|
18
|
+
Examples:
|
19
|
+
# Launch GeneValidatorApp with the given config file
|
20
|
+
$ genevalidatorapp --config ~/.genevalidatorapp.conf
|
21
|
+
|
22
|
+
# Launch GeneValidatorApp with 8 threads at port 8888
|
23
|
+
$ genevalidatorapp --num_threads 8 --port 8888
|
24
|
+
|
25
|
+
# Create a config file with the other arguments
|
26
|
+
$ genevalidatorapp -s -d ~/database_dir
|
27
|
+
BNR
|
28
|
+
|
29
|
+
o.separator 'Compulsory Argument, unless set in a config file'
|
30
|
+
|
31
|
+
o.string '-d', '--database_dir',
|
32
|
+
'Read BLAST database from this directory'
|
33
|
+
|
34
|
+
o.separator ''
|
35
|
+
o.separator 'Optional Arguments'
|
36
|
+
|
37
|
+
o.string '-f', '--default_db',
|
38
|
+
'The Path to the the default database'
|
39
|
+
|
40
|
+
o.string '-n', '--num_threads',
|
41
|
+
'Number of threads to use to run a BLAST search'
|
42
|
+
|
43
|
+
o.string '-c', '--config_file',
|
44
|
+
'Use the given configuration file'
|
45
|
+
|
46
|
+
o.string '-r', '--require',
|
47
|
+
'Load extension from this file'
|
48
|
+
|
49
|
+
o.string '--host',
|
50
|
+
'Host to run GeneValidatorApp on'
|
51
|
+
|
52
|
+
o.string '-p', '--port',
|
53
|
+
'Port to run GeneValidatorApp on'
|
54
|
+
|
55
|
+
o.string '-s', '--set',
|
56
|
+
'Set configuration value in the config file'
|
57
|
+
|
58
|
+
o.string '-l', '--list_dbs',
|
59
|
+
'List BLAST databases'
|
60
|
+
|
61
|
+
o.string '-b', '--blast_bin',
|
62
|
+
'Load BLAST+ binaries from this directory'
|
63
|
+
|
64
|
+
o.string '-m', '--mafft_bin',
|
65
|
+
'Load Mafft binaries from this directory'
|
66
|
+
|
67
|
+
o.string '-w', '--web_dir',
|
68
|
+
'Path to the web directory (contains ' \
|
69
|
+
'supporting files utilised by the app).'
|
70
|
+
|
71
|
+
o.bool '-D', '--devel',
|
72
|
+
'Start GeneValidatorApp in development mode'
|
73
|
+
|
74
|
+
o.bool '-v', '--version',
|
75
|
+
'Print version number of GeneValidatorApp that will be loaded'
|
76
|
+
|
77
|
+
o.on '-h', '--help',
|
78
|
+
'Display this help message'
|
79
|
+
end
|
80
|
+
|
81
|
+
if opts.help?
|
82
|
+
puts opts
|
83
|
+
exit
|
84
|
+
end
|
85
|
+
|
86
|
+
if opts.version?
|
87
|
+
require 'GeneValidatorApp/version'
|
88
|
+
puts GeneValidatorApp::VERSION
|
89
|
+
exit
|
90
|
+
end
|
91
|
+
|
92
|
+
ENV['RACK_ENV'] = 'development' if opts.devel?
|
93
|
+
|
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
|
102
|
+
|
103
|
+
clean_opts = lambda do |hash|
|
104
|
+
hash.delete_if { |k, v| k == :set || k == :version || v.nil? }
|
105
|
+
hash
|
106
|
+
end
|
107
|
+
|
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
|
+
|
118
|
+
puts GeneValidatorApp::Database.all? if opts.list_databases?
|
119
|
+
|
120
|
+
GeneValidatorApp.send(:write_config_file) if opts.set?
|
121
|
+
|
122
|
+
GeneValidatorApp.run
|
data/config.ru
ADDED
@@ -0,0 +1,321 @@
|
|
1
|
+
require 'GeneValidatorApp/database'
|
2
|
+
require 'GeneValidatorApp/genevalidator'
|
3
|
+
require 'GeneValidatorApp/logger'
|
4
|
+
require 'GeneValidatorApp/config'
|
5
|
+
require 'GeneValidatorApp/version'
|
6
|
+
require 'genevalidator/version'
|
7
|
+
|
8
|
+
require 'pathname'
|
9
|
+
require 'yaml'
|
10
|
+
require 'sinatra/base'
|
11
|
+
require 'sinatra/cross_origin'
|
12
|
+
require 'slim'
|
13
|
+
require 'thin'
|
14
|
+
|
15
|
+
module GeneValidatorApp
|
16
|
+
# Use a fixed minimum version of BLAST+
|
17
|
+
MINIMUM_BLAST_VERSION = '2.2.30+'
|
18
|
+
|
19
|
+
class << self
|
20
|
+
attr_reader :public_dir, :tempdir, :config
|
21
|
+
|
22
|
+
# Returns the Rack Environment
|
23
|
+
def environment
|
24
|
+
ENV['RACK_ENV']
|
25
|
+
end
|
26
|
+
|
27
|
+
# Run by the logger method - sets the logger level to verbose if in
|
28
|
+
# development environment
|
29
|
+
def verbose?
|
30
|
+
@verbose ||= (environment == 'development')
|
31
|
+
end
|
32
|
+
|
33
|
+
# Root dir of the App
|
34
|
+
def root
|
35
|
+
Pathname.new(__FILE__).dirname.parent
|
36
|
+
end
|
37
|
+
|
38
|
+
def logger
|
39
|
+
@logger ||= Logger.new(STDERR, verbose?)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Setting up the environment before running the app...
|
43
|
+
def init(config = {})
|
44
|
+
@config = Config.new(config)
|
45
|
+
init_blast_and_mafft_binaries
|
46
|
+
init_database
|
47
|
+
load_extension
|
48
|
+
check_num_threads
|
49
|
+
check_max_characters
|
50
|
+
init_gv_tempdir
|
51
|
+
init_public_dir
|
52
|
+
self
|
53
|
+
end
|
54
|
+
|
55
|
+
# Starting the app manually using Thin
|
56
|
+
def run
|
57
|
+
check_host
|
58
|
+
url = "http://#{config[:host]}:#{config[:port]}"
|
59
|
+
server = Thin::Server.new(config[:host], config[:port], signals: false) do
|
60
|
+
use Rack::CommonLogger if GeneValidatorApp.environment == 'development'
|
61
|
+
run GeneValidatorApp
|
62
|
+
end
|
63
|
+
server.timeout = 2700 # 45 minutes
|
64
|
+
server.silent = true
|
65
|
+
server.backend.start do
|
66
|
+
puts '** GeneValidatorApp is ready.'
|
67
|
+
puts " Go to #{url} in your browser and start analysing Genes!"
|
68
|
+
puts ' Press CTRL+C to quit.'
|
69
|
+
puts
|
70
|
+
open_default_browser(url)
|
71
|
+
[:INT, :TERM].each do |sig|
|
72
|
+
trap sig do
|
73
|
+
server.stop!
|
74
|
+
puts
|
75
|
+
puts
|
76
|
+
puts '** Thank you for using GeneValidatorApp :).'
|
77
|
+
puts ' Please cite: '
|
78
|
+
puts ' Dragan M., Moghul M.I., Priyam A., Wurm Y (in prep).'
|
79
|
+
puts ' GeneValidator: identify problematic gene predictions.'
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
rescue
|
84
|
+
puts '** Oops! There was an error.'
|
85
|
+
puts " Is GeneValidatorApp already accessible at #{url}?"
|
86
|
+
puts ' Try running GeneValidatorApp on another port, like so:'
|
87
|
+
puts
|
88
|
+
puts ' genevalidatorapp -p 4570.'
|
89
|
+
end
|
90
|
+
|
91
|
+
# Set the max characters accepted from the app (for the app templates)
|
92
|
+
def max_characters
|
93
|
+
(config[:max_characters]) ? config[:max_characters] : 'undefined'
|
94
|
+
end
|
95
|
+
|
96
|
+
def [](key)
|
97
|
+
config[key]
|
98
|
+
end
|
99
|
+
|
100
|
+
# Rack-interface.
|
101
|
+
#
|
102
|
+
# Inject our logger in the env and dispatch request to our
|
103
|
+
# controller.
|
104
|
+
def call(env)
|
105
|
+
env['rack.logger'] = logger
|
106
|
+
App.call(env)
|
107
|
+
end
|
108
|
+
|
109
|
+
private
|
110
|
+
|
111
|
+
def open_default_browser(url)
|
112
|
+
return if using_ssh?
|
113
|
+
if RUBY_PLATFORM =~ /linux/
|
114
|
+
`xdg-open #{url}` unless command?('xdg-open') || ENV['DISPLAY']
|
115
|
+
elsif RUBY_PLATFORM =~ /darwin/
|
116
|
+
`open #{url}`
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def using_ssh?
|
121
|
+
true if ENV['SSH_CLIENT'] || ENV['SSH_TTY'] || ENV['SSH_CONNECTION']
|
122
|
+
end
|
123
|
+
|
124
|
+
def init_blast_and_mafft_binaries
|
125
|
+
init_binaries(config[:blast_bin], 'NCBI BLAST+')
|
126
|
+
assert_blast_installed_and_compatible
|
127
|
+
init_binaries(config[:mafft_bin], 'Mafft')
|
128
|
+
assert_mafft_installed
|
129
|
+
end
|
130
|
+
|
131
|
+
def init_binaries(bin_dir, type)
|
132
|
+
if bin_dir
|
133
|
+
bin_dir = File.expand_path bin_dir
|
134
|
+
unless File.exist?(bin_dir) && File.directory?(bin_dir)
|
135
|
+
fail BIN_DIR_NOT_FOUND, bin_dir
|
136
|
+
end
|
137
|
+
logger.debug("Will use #{type} at: #{config[:blast_bin]}")
|
138
|
+
export_bin_dir bin_dir
|
139
|
+
else
|
140
|
+
logger.debug("Will use #{type} at: $PATH")
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def init_database
|
145
|
+
fail DATABASE_DIR_NOT_SET unless config[:database_dir]
|
146
|
+
|
147
|
+
config[:database_dir] = File.expand_path(config[:database_dir])
|
148
|
+
unless File.exist?(config[:database_dir]) &&
|
149
|
+
File.directory?(config[:database_dir])
|
150
|
+
fail DATABASE_DIR_NOT_FOUND, config[:database_dir]
|
151
|
+
end
|
152
|
+
|
153
|
+
assert_blast_databases_present_in_database_dir
|
154
|
+
logger.debug("Will use BLAST+ databases at: #{config[:database_dir]}")
|
155
|
+
|
156
|
+
Database.scan_databases_dir
|
157
|
+
Database.each do |database|
|
158
|
+
logger.debug("Found #{database.type.chomp} database" \
|
159
|
+
" '#{database.title.chomp}' at '#{database.name.chomp}'")
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
def check_num_threads
|
164
|
+
num_threads = Integer(config[:num_threads])
|
165
|
+
fail NUM_THREADS_INCORRECT unless num_threads > 0
|
166
|
+
logger.debug "Will use #{num_threads} threads to run BLAST."
|
167
|
+
if num_threads > 256
|
168
|
+
logger.warn "Number of threads set at #{num_threads} is unusually high."
|
169
|
+
end
|
170
|
+
rescue
|
171
|
+
raise NUM_THREADS_INCORRECT
|
172
|
+
end
|
173
|
+
|
174
|
+
def check_max_characters
|
175
|
+
Integer(config[:max_characters]) if config[:max_characters]
|
176
|
+
rescue
|
177
|
+
raise MAX_CHARACTERS_INCORRECT
|
178
|
+
end
|
179
|
+
|
180
|
+
def load_extension
|
181
|
+
return unless config[:require]
|
182
|
+
|
183
|
+
config[:require] = File.expand_path config[:require]
|
184
|
+
unless File.exist?(config[:require]) && File.file?(config[:require])
|
185
|
+
fail EXTENSION_FILE_NOT_FOUND, config[:require]
|
186
|
+
end
|
187
|
+
|
188
|
+
logger.debug("Loading extension: #{config[:require]}")
|
189
|
+
require config[:require]
|
190
|
+
end
|
191
|
+
|
192
|
+
# Asserts whether mafft is installed.
|
193
|
+
def assert_mafft_installed
|
194
|
+
fail MAFFT_NOT_INSTALLED unless command? 'mafft'
|
195
|
+
end
|
196
|
+
|
197
|
+
def assert_blast_installed_and_compatible
|
198
|
+
fail BLAST_NOT_INSTALLED unless command? 'blastdbcmd'
|
199
|
+
version = `blastdbcmd -version`.split[1]
|
200
|
+
fail BLAST_NOT_COMPATIBLE, version unless version >= MINIMUM_BLAST_VERSION
|
201
|
+
end
|
202
|
+
|
203
|
+
def assert_blast_databases_present_in_database_dir
|
204
|
+
cmd = "blastdbcmd -recursive -list #{config[:database_dir]}"
|
205
|
+
out = `#{cmd}`
|
206
|
+
errpat = /BLAST Database error/
|
207
|
+
fail NO_BLAST_DATABASE_FOUND, config[:database_dir] if out.empty?
|
208
|
+
fail BLAST_DATABASE_ERROR, cmd, out if out.match(errpat) ||
|
209
|
+
!$?.success?
|
210
|
+
end
|
211
|
+
|
212
|
+
# Export bin dir to PATH environment variable.
|
213
|
+
def export_bin_dir(bin_dir)
|
214
|
+
return unless bin_dir
|
215
|
+
return if ENV['PATH'].split(':').include? bin_dir
|
216
|
+
ENV['PATH'] = "#{bin_dir}:#{ENV['PATH']}"
|
217
|
+
end
|
218
|
+
|
219
|
+
# Creates a Temp directory (starting with 'GeneValidator_') each time
|
220
|
+
# GVapp is started. Within this Temp folder, sub directories are created
|
221
|
+
# in which GeneValidator is run.
|
222
|
+
def init_gv_tempdir
|
223
|
+
@tempdir = Pathname.new(Dir.mktmpdir('GeneValidator_'))
|
224
|
+
end
|
225
|
+
|
226
|
+
# Copy the public folder (in the app root) to the web_dir location - this
|
227
|
+
# web_dir is then used by the app to serve all dependencies...
|
228
|
+
def init_public_dir
|
229
|
+
@public_dir = Pathname.new(config[:web_dir]) +
|
230
|
+
"GeneValidator_#{Time.now.strftime('%Y%m%d-%H%M%S')}"
|
231
|
+
root_public_dir = GeneValidatorApp.root + 'public'
|
232
|
+
FileUtils.cp_r(root_public_dir, @public_dir)
|
233
|
+
end
|
234
|
+
|
235
|
+
# Check and warn user if host is 0.0.0.0 (default).
|
236
|
+
def check_host
|
237
|
+
if config[:host] == '0.0.0.0'
|
238
|
+
logger.warn 'Will listen on all interfaces (0.0.0.0).' \
|
239
|
+
' Consider using 127.0.0.1 (--host option).'
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
# Return `true` if the given command exists and is executable.
|
244
|
+
def command?(command)
|
245
|
+
system("which #{command} > /dev/null 2>&1")
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
# The Actual App...
|
250
|
+
class App < Sinatra::Base
|
251
|
+
register Sinatra::CrossOrigin
|
252
|
+
|
253
|
+
configure do
|
254
|
+
# We don't need Rack::MethodOverride. Let's avoid the overhead.
|
255
|
+
disable :method_override
|
256
|
+
|
257
|
+
# Ensure exceptions never leak out of the app. Exceptions raised within
|
258
|
+
# the app must be handled by the app. We do this by attaching error
|
259
|
+
# blocks to exceptions we know how to handle and attaching to Exception
|
260
|
+
# as fallback.
|
261
|
+
disable :show_exceptions, :raise_errors
|
262
|
+
|
263
|
+
# Make it a policy to dump to 'rack.errors' any exception raised by the
|
264
|
+
# app so that error handlers don't have to do it themselves. But for it
|
265
|
+
# to always work, Exceptions defined by us should not respond to `code`
|
266
|
+
# or http_status` methods. Error blocks errors must explicitly set http
|
267
|
+
# status, if needed, by calling `status` method.
|
268
|
+
enable :dump_errors
|
269
|
+
|
270
|
+
# We don't want Sinatra do setup any loggers for us. We will use our own.
|
271
|
+
set :logging, nil
|
272
|
+
|
273
|
+
# This is the app root...
|
274
|
+
set :root, lambda { GeneValidatorApp.root }
|
275
|
+
|
276
|
+
# This is the full path to the public folder...
|
277
|
+
set :public_folder, lambda { GeneValidatorApp.public_dir }
|
278
|
+
end
|
279
|
+
|
280
|
+
# Set up global variables for the templates...
|
281
|
+
before '/' do
|
282
|
+
@default_db = Database.default_db
|
283
|
+
@non_default_dbs = Database.non_default_dbs
|
284
|
+
@max_characters = GeneValidatorApp.max_characters
|
285
|
+
@current_gv_version = GeneValidator::VERSION
|
286
|
+
end
|
287
|
+
|
288
|
+
get '/' do
|
289
|
+
slim :index
|
290
|
+
end
|
291
|
+
|
292
|
+
post '/' do
|
293
|
+
cross_origin # Required for the API to work...
|
294
|
+
RunGeneValidator.init(request.url, params)
|
295
|
+
RunGeneValidator.run
|
296
|
+
end
|
297
|
+
|
298
|
+
# This error block will only ever be hit if the user gives us a funny
|
299
|
+
# sequence or incorrect advanced parameter. Well, we could hit this block
|
300
|
+
# if someone is playing around with our HTTP API too.
|
301
|
+
error RunGeneValidator::ArgumentError do
|
302
|
+
status 400
|
303
|
+
slim :"500", layout: false
|
304
|
+
end
|
305
|
+
|
306
|
+
# This will catch any unhandled error and some very special errors. Ideally
|
307
|
+
# we will never hit this block. If we do, there's a bug in GeneValidatorApp
|
308
|
+
# or something really weird going on.
|
309
|
+
# TODO: If we hit this error block we show the stacktrace to the user
|
310
|
+
# requesting them to post the same to our Google Group.
|
311
|
+
error Exception, RunGeneValidator::RuntimeError do
|
312
|
+
status 500 # TODO Create another template...
|
313
|
+
slim :"500", layout: false
|
314
|
+
end
|
315
|
+
|
316
|
+
not_found do
|
317
|
+
status 404
|
318
|
+
slim :"500" # TODO: Create another Template
|
319
|
+
end
|
320
|
+
end
|
321
|
+
end
|