sequenceserver 1.1.0.beta3 → 1.1.0.beta4
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.
Potentially problematic release.
This version of sequenceserver might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/lib/sequenceserver/api_errors.rb +2 -0
- data/lib/sequenceserver/blast/formatter.rb +8 -11
- data/lib/sequenceserver/blast/job.rb +10 -2
- data/lib/sequenceserver/blast/report.rb +3 -22
- data/lib/sequenceserver/job.rb +23 -17
- data/lib/sequenceserver/job_remover.rb +1 -1
- data/lib/sequenceserver/routes.rb +26 -7
- data/lib/sequenceserver/version.rb +1 -1
- data/public/css/sequenceserver.css +2 -1
- data/public/css/sequenceserver.min.css +3 -3
- data/public/js/errormodal.js +22 -10
- data/public/js/search.js +7 -5
- data/public/sequenceserver-report.min.js +1 -1
- data/public/sequenceserver-search.min.js +2 -2
- data/views/layout.erb +3 -5
- data/views/report.erb +1 -1
- data/views/search.erb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a526ad89575f0b9118bf986359b9750a2a1ef894
|
4
|
+
data.tar.gz: 3fa16082e5bb2b99c16be95413ba0fbdf722baf4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2b95e0a703717cd2af830462624dcea36c10b103cffaa3fb4f80e811abe54625a070d94caefe8c05f26fc59fa41ebaa06c80091b8a0b88b0286f8597d5cea2fd
|
7
|
+
data.tar.gz: 5a4e459777fe4ecf68e1f80c0aee8aadb8b231e2dd11bbee79b51ef16f1907c2b6ff69751552daa7bca3c927b38d5f92b9b9123ae537862a016e7b368011c8f2
|
@@ -11,20 +11,20 @@ module SequenceServer
|
|
11
11
|
extend Forwardable
|
12
12
|
def_delegators SequenceServer, :config, :logger, :sys
|
13
13
|
|
14
|
-
def initialize(
|
15
|
-
@
|
14
|
+
def initialize(job, type)
|
15
|
+
@job = job
|
16
16
|
@format, @mime, @specifiers = OUTFMT[type]
|
17
17
|
@type = type
|
18
18
|
|
19
19
|
validate && run
|
20
20
|
end
|
21
21
|
|
22
|
-
attr_reader :
|
22
|
+
attr_reader :job, :type
|
23
23
|
|
24
24
|
attr_reader :format, :mime, :specifiers
|
25
25
|
|
26
26
|
def file
|
27
|
-
@file ||= File.join(
|
27
|
+
@file ||= File.join(job.dir, filename)
|
28
28
|
end
|
29
29
|
|
30
30
|
def filename
|
@@ -37,7 +37,7 @@ module SequenceServer
|
|
37
37
|
def run
|
38
38
|
return if File.exist?(file)
|
39
39
|
command =
|
40
|
-
"blast_formatter -archive '#{
|
40
|
+
"blast_formatter -archive '#{job.stdout}'" \
|
41
41
|
" -outfmt '#{format} #{specifiers}'" \
|
42
42
|
" -out '#{file}'"
|
43
43
|
sys(command, path: config[:bin], dir: DOTDIR)
|
@@ -46,12 +46,9 @@ module SequenceServer
|
|
46
46
|
end
|
47
47
|
|
48
48
|
def validate
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
Incorrect request parameters. Please ensure that requested file name is
|
53
|
-
correct and the file type is either xml or tsv.
|
54
|
-
MSG
|
49
|
+
fail SystemError if !File.exist?(job.stdout) ||
|
50
|
+
File.zero?(job.stdout)
|
51
|
+
true
|
55
52
|
end
|
56
53
|
end
|
57
54
|
end
|
@@ -33,8 +33,16 @@ module SequenceServer
|
|
33
33
|
|
34
34
|
# BLAST's exit status is not definitive of success or error, so we
|
35
35
|
# override success? to define custom criteria. :TODO:
|
36
|
-
def
|
37
|
-
|
36
|
+
def raise!
|
37
|
+
return true if exitstatus == 0
|
38
|
+
|
39
|
+
stderr = File.readlines(this.stderr)
|
40
|
+
if exitstatus == 1 # error in query sequence or options; see [1]
|
41
|
+
error = stderr.grep(ERROR_LINE)
|
42
|
+
error = stderr if error.empty?
|
43
|
+
fail InputError, error.join
|
44
|
+
end
|
45
|
+
fail SystemError, stderr.join
|
38
46
|
end
|
39
47
|
|
40
48
|
private
|
@@ -43,27 +43,15 @@ module SequenceServer
|
|
43
43
|
|
44
44
|
# Generate report.
|
45
45
|
def generate
|
46
|
-
|
47
|
-
xml_ir = parse_xml File.read(Formatter.run(job
|
48
|
-
tsv_ir = parse_tsv File.read(Formatter.run(job
|
46
|
+
job.raise!
|
47
|
+
xml_ir = parse_xml File.read(Formatter.run(job, 'xml').file)
|
48
|
+
tsv_ir = parse_tsv File.read(Formatter.run(job, 'custom_tsv').file)
|
49
49
|
extract_program_info xml_ir
|
50
50
|
extract_params xml_ir
|
51
51
|
extract_stats xml_ir
|
52
52
|
extract_queries xml_ir, tsv_ir
|
53
53
|
end
|
54
54
|
|
55
|
-
def assert_job_completed_successfully
|
56
|
-
return true if job.success?
|
57
|
-
|
58
|
-
stderr = File.readlines(job.stderr)
|
59
|
-
if job.exitstatus == 1 # error in query sequence or options; see [1]
|
60
|
-
error = stderr.grep(ERROR_LINE)
|
61
|
-
error = stderr if error.empty?
|
62
|
-
fail InputError, error.join
|
63
|
-
end
|
64
|
-
fail SystemError, stderr.join
|
65
|
-
end
|
66
|
-
|
67
55
|
# Make program name and program name + version available via `program`
|
68
56
|
# and `program_version` attributes.
|
69
57
|
def extract_program_info(ir)
|
@@ -107,10 +95,6 @@ module SequenceServer
|
|
107
95
|
xml_ir[8].each do |n|
|
108
96
|
query = Query.new(self, n[0], n[2], n[3], [])
|
109
97
|
extract_hits(n[4], tsv_ir[query.id], query)
|
110
|
-
query.hits = query.hits.sort_by do |h|
|
111
|
-
first_hsp = h.hsps.first # most significant hsp
|
112
|
-
[first_hsp.evalue, first_hsp.score]
|
113
|
-
end
|
114
98
|
queries << query
|
115
99
|
end
|
116
100
|
end
|
@@ -131,9 +115,6 @@ module SequenceServer
|
|
131
115
|
hit = Hit.new(query, n[0], n[1], n[3], n[2], n[4],
|
132
116
|
tsv_ir[n[1]][0], tsv_ir[n[1]][1],[])
|
133
117
|
extract_hsps(n[5], tsv_ir[n[1]][2], hit)
|
134
|
-
hit.hsps = hit.hsps.sort_by do |h|
|
135
|
-
[h.evalue, h.score]
|
136
|
-
end
|
137
118
|
query.hits << hit
|
138
119
|
end
|
139
120
|
end
|
data/lib/sequenceserver/job.rb
CHANGED
@@ -63,6 +63,10 @@ module SequenceServer
|
|
63
63
|
mkdir_p dir
|
64
64
|
yield if block_given?
|
65
65
|
save
|
66
|
+
rescue Errno::ENOSPC
|
67
|
+
raise SystemError
|
68
|
+
rescue Errno::EACCES
|
69
|
+
raise SystemError
|
66
70
|
rescue => e
|
67
71
|
rm_rf dir
|
68
72
|
raise e
|
@@ -70,6 +74,12 @@ module SequenceServer
|
|
70
74
|
|
71
75
|
attr_reader :id, :completed_at, :exitstatus
|
72
76
|
|
77
|
+
# Returns shell command that will be executed. Subclass needs to provide a
|
78
|
+
# concrete implementation.
|
79
|
+
def command
|
80
|
+
raise "Not implemented."
|
81
|
+
end
|
82
|
+
|
73
83
|
# Shell out and execute the job.
|
74
84
|
#
|
75
85
|
# NOTE: This method is called asynchronously by thread pool.
|
@@ -80,10 +90,16 @@ module SequenceServer
|
|
80
90
|
done! e.exitstatus
|
81
91
|
end
|
82
92
|
|
83
|
-
#
|
84
|
-
|
85
|
-
|
86
|
-
|
93
|
+
# Is exitstatus of the job available? If yes, it means the job is done.
|
94
|
+
def done?
|
95
|
+
!!@exitstatus
|
96
|
+
end
|
97
|
+
|
98
|
+
# Raise RuntimeError if job finished with non-zero exit status. This method
|
99
|
+
# should be called on a completed job before attempting to use the results.
|
100
|
+
# Subclasses should provide their own implementation.
|
101
|
+
def raise!
|
102
|
+
raise if done? && exitstatus != 0
|
87
103
|
end
|
88
104
|
|
89
105
|
# Where will the stdout be written to during execution and read from later.
|
@@ -96,14 +112,9 @@ module SequenceServer
|
|
96
112
|
File.join(dir, 'stderr')
|
97
113
|
end
|
98
114
|
|
99
|
-
#
|
100
|
-
def
|
101
|
-
|
102
|
-
end
|
103
|
-
|
104
|
-
# Is the job done? Yes if exitstatus of the job is available. No otherwise.
|
105
|
-
def done?
|
106
|
-
!!@exitstatus
|
115
|
+
# Where to save all kind of data for this job.
|
116
|
+
def dir
|
117
|
+
File.join(DOTDIR, id)
|
107
118
|
end
|
108
119
|
|
109
120
|
private
|
@@ -144,11 +155,6 @@ module SequenceServer
|
|
144
155
|
save
|
145
156
|
end
|
146
157
|
|
147
|
-
# Where to save all kind of data for this job.
|
148
|
-
def dir
|
149
|
-
File.join(DOTDIR, id)
|
150
|
-
end
|
151
|
-
|
152
158
|
# Where to write serialised job object.
|
153
159
|
def yfile
|
154
160
|
File.join(dir, 'job.yaml')
|
@@ -8,7 +8,7 @@ module SequenceServer
|
|
8
8
|
# be deleted as soon as they are done, or it can be Infinity in which case
|
9
9
|
# jobs will never be deleted. Default is to delete finished jobs after 7 days.
|
10
10
|
class JobRemover
|
11
|
-
DEFAULT_JOB_LIFETIME =
|
11
|
+
DEFAULT_JOB_LIFETIME = 43200 # minutes (i.e., 30 days)
|
12
12
|
|
13
13
|
def initialize(job_lifetime)
|
14
14
|
@job_lifetime = job_lifetime || DEFAULT_JOB_LIFETIME
|
@@ -122,19 +122,38 @@ module SequenceServer
|
|
122
122
|
# Download BLAST report in various formats.
|
123
123
|
get '/download/:jid.:type' do |jid, type|
|
124
124
|
job = Job.fetch(jid)
|
125
|
-
out = BLAST::Formatter.new(job
|
125
|
+
out = BLAST::Formatter.new(job, type)
|
126
126
|
send_file out.file, :filename => out.filename, :type => out.mime
|
127
127
|
end
|
128
128
|
|
129
|
-
# Catches any exception raised within the app and returns
|
130
|
-
#
|
131
|
-
#
|
132
|
-
#
|
129
|
+
# Catches any exception raised within the app and returns JSON
|
130
|
+
# representation of the error:
|
131
|
+
# {
|
132
|
+
# title: ..., // plain text
|
133
|
+
# message: ..., // plain or HTML text
|
134
|
+
# more_info: ..., // pre-formatted text
|
135
|
+
# }
|
136
|
+
#
|
137
|
+
# If the error class defines `http_status` instance method, its return
|
138
|
+
# value will be used to set HTTP status. HTTP status is set to 500
|
139
|
+
# otherwise.
|
140
|
+
#
|
141
|
+
# If the error class defines `title` instance method, its return value
|
142
|
+
# will be used as title. Otherwise name of the error class is used as
|
143
|
+
# title.
|
144
|
+
#
|
145
|
+
# If the error class defines `more_info` instance method, its return
|
146
|
+
# value will be used as more_info, otherwise `backtrace.join("\n")`
|
147
|
+
# is used as more_info. If an error class does not want to include
|
148
|
+
# more_info (like for NotFound), the error class must undefine
|
149
|
+
# `backtrace` method.
|
150
|
+
#
|
151
|
+
# All error classes should define `message` instance method.
|
133
152
|
error 400..500 do
|
134
153
|
error = env['sinatra.error']
|
135
154
|
|
136
155
|
# All errors will have a message.
|
137
|
-
error_data = {message: error.message}
|
156
|
+
error_data = { message: error.message }
|
138
157
|
|
139
158
|
# If error object has a title method, use that, or use error class for
|
140
159
|
# title.
|
@@ -149,7 +168,7 @@ module SequenceServer
|
|
149
168
|
# more_info.
|
150
169
|
if error.respond_to? :more_info
|
151
170
|
error_data[:more_info] = error.more_info
|
152
|
-
|
171
|
+
elsif error.respond_to? :backtrace
|
153
172
|
error_data[:more_info] = error.backtrace.join("\n")
|
154
173
|
end
|
155
174
|
|