sequenceserver 1.1.0.beta2 → 1.1.0.beta3
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/.travis.yml +16 -5
- data/README.md +3 -0
- data/lib/sequenceserver/api_errors.rb +67 -0
- data/lib/sequenceserver/blast/constants.rb +1 -1
- data/lib/sequenceserver/blast/formatter.rb +4 -2
- data/lib/sequenceserver/blast/job.rb +17 -62
- data/lib/sequenceserver/blast/report.rb +15 -2
- data/lib/sequenceserver/blast.rb +1 -0
- data/lib/sequenceserver/exceptions.rb +2 -3
- data/lib/sequenceserver/job.rb +72 -44
- data/lib/sequenceserver/routes.rb +29 -25
- data/lib/sequenceserver/version.rb +1 -1
- data/lib/sequenceserver.rb +32 -20
- data/public/js/errormodal.js +55 -0
- data/public/js/report.js +6 -2
- data/public/js/sequenceserver.js +0 -12
- data/public/sequenceserver-report.min.js +15 -15
- data/public/sequenceserver-search.min.js +3 -3
- data/sequenceserver.gemspec +2 -1
- data/spec/capybara_spec.rb +120 -21
- data/spec/database/sample/genome/Solenopsis_invicta/Solenopsis_invicta_gnG_subset.fasta.nhd +8 -0
- data/spec/database/sample/genome/Solenopsis_invicta/Solenopsis_invicta_gnG_subset.fasta.nhi +0 -0
- data/spec/database/sample/genome/Solenopsis_invicta/Solenopsis_invicta_gnG_subset.fasta.nhr +0 -0
- data/spec/database/sample/genome/Solenopsis_invicta/Solenopsis_invicta_gnG_subset.fasta.nin +0 -0
- data/spec/database/sample/genome/Solenopsis_invicta/Solenopsis_invicta_gnG_subset.fasta.nog +0 -0
- data/spec/database/sample/genome/Solenopsis_invicta/Solenopsis_invicta_gnG_subset.fasta.nsd +16 -0
- data/spec/database/sample/genome/Solenopsis_invicta/Solenopsis_invicta_gnG_subset.fasta.nsi +0 -0
- data/spec/database/sample/genome/Solenopsis_invicta/Solenopsis_invicta_gnG_subset.fasta.nsq +0 -0
- data/spec/database/sample/genome/Solenopsis_invicta/Solenopsis_invicta_gnG_subset.txt +8 -0
- data/spec/database/sample/proteins/uniprot/2018-04-Swiss-Prot_insecta.fasta.phd +9140 -0
- data/spec/database/sample/proteins/uniprot/2018-04-Swiss-Prot_insecta.fasta.phi +0 -0
- data/spec/database/sample/proteins/uniprot/2018-04-Swiss-Prot_insecta.fasta.phr +0 -0
- data/spec/database/sample/proteins/uniprot/2018-04-Swiss-Prot_insecta.fasta.pin +0 -0
- data/spec/database/sample/proteins/uniprot/2018-04-Swiss-Prot_insecta.fasta.pog +0 -0
- data/spec/database/sample/proteins/uniprot/2018-04-Swiss-Prot_insecta.fasta.psd +18280 -0
- data/spec/database/sample/proteins/uniprot/2018-04-Swiss-Prot_insecta.fasta.psi +0 -0
- data/spec/database/sample/proteins/uniprot/2018-04-Swiss-Prot_insecta.fasta.psq +0 -0
- data/spec/database/sample/proteins/uniprot/URL +1 -0
- data/spec/nucleotide_query.fa +21 -0
- data/spec/protein_query.fa +21 -0
- data/spec/routes_spec.rb +2 -0
- data/spec/sample_reports/blastn_sample/job.yaml +1 -0
- data/spec/sample_reports/blastn_sample/{rfile → stdout} +0 -0
- data/spec/sample_reports/blastp_sample/job.yaml +1 -0
- data/spec/sample_reports/blastp_sample/{rfile → stdout} +0 -0
- data/spec/sample_reports/blastx_sample/job.yaml +1 -0
- data/spec/sample_reports/blastx_sample/{rfile → stdout} +0 -0
- data/spec/sample_reports/no_hits_sample/job.yaml +1 -0
- data/spec/sample_reports/no_hits_sample/{rfile → stdout} +0 -0
- data/spec/sample_reports/tblastn_sample/job.yaml +1 -0
- data/spec/sample_reports/tblastn_sample/{rfile → stdout} +0 -0
- data/spec/sample_reports/tblastx_sample/job.yaml +1 -0
- data/spec/sample_reports/tblastx_sample/{rfile → stdout} +0 -0
- data/spec/sample_reports/with_hits_sample/job.yaml +1 -0
- data/spec/sample_reports/with_hits_sample/{rfile → stdout} +0 -0
- data/spec/sequenceserver_spec.rb +1 -1
- data/spec/spec_helper.rb +2 -16
- data/views/layout.erb +0 -45
- metadata +55 -16
- data/lib/sequenceserver/blast/exceptions.rb +0 -27
- data/views/400.erb +0 -29
- data/views/500.erb +0 -41
data/lib/sequenceserver.rb
CHANGED
@@ -90,11 +90,15 @@ module SequenceServer
|
|
90
90
|
# sys(command, :dir => '/path/to/directory',
|
91
91
|
# :path => '/path/to/directory', :stdout => '/path/to/stdout_file',
|
92
92
|
# :stderr => '/path/to/stderr_file')
|
93
|
-
|
94
93
|
def sys(command, options = {})
|
94
|
+
# Available output channels
|
95
|
+
channels = [:stdout, :stderr]
|
96
|
+
|
95
97
|
# Make temporary files to store output from stdout and stderr.
|
96
|
-
|
97
|
-
|
98
|
+
temp_files = {
|
99
|
+
stdout: Tempfile.new('sequenceserver-sys'),
|
100
|
+
stderr: Tempfile.new('sequenceserver-sys')
|
101
|
+
}
|
98
102
|
|
99
103
|
# Log the command we are going to run - use -D option to view.
|
100
104
|
logger.debug("Executing: #{command}")
|
@@ -111,32 +115,40 @@ module SequenceServer
|
|
111
115
|
|
112
116
|
# Execute the shell command, redirect stdout and stderr to the
|
113
117
|
# temporary files.
|
114
|
-
exec("#{command} 1>#{
|
118
|
+
exec("#{command} 1>#{temp_files[:stdout].path}" \
|
119
|
+
" 2>#{temp_files[:stderr].path}")
|
115
120
|
end
|
116
121
|
|
117
122
|
# Wait for the termination of the child process.
|
118
123
|
_, status = Process.wait2(child_pid)
|
119
124
|
|
120
|
-
|
121
|
-
|
125
|
+
# If a full path was given for stdout and stderr files, move the
|
126
|
+
# temporary files to this path. If the path given does not exist,
|
127
|
+
# create it.
|
128
|
+
channels.each do |channel|
|
129
|
+
filename = options[channel]
|
130
|
+
break unless filename
|
131
|
+
|
132
|
+
# If the given path has a directory component, ensure it exists.
|
133
|
+
file_dir = File.dirname(filename)
|
134
|
+
FileUtils.mkdir_p(file_dir) unless File.directory?(file_dir)
|
135
|
+
|
136
|
+
# Now move the temporary file to the given path.
|
137
|
+
# TODO: don't we need to explicitly close the temp file here?
|
138
|
+
FileUtils.mv(temp_files.delete(channel), filename)
|
122
139
|
end
|
123
140
|
|
124
|
-
#
|
125
|
-
#
|
126
|
-
#
|
127
|
-
|
128
|
-
|
129
|
-
file_dir = File.dirname(filename)
|
130
|
-
unless File.directory?(file_dir)
|
131
|
-
FileUtils.mkdir_p(file_dir)
|
132
|
-
end
|
133
|
-
FileUtils.mv([temp_stdout_file, temp_stderr_file][index], filename)
|
134
|
-
end
|
141
|
+
# Read the remaining temp files into memory. For large outputs,
|
142
|
+
# the caller should supply a file path to prevent loading the
|
143
|
+
# output in memory.
|
144
|
+
temp_files.each do |channel, tempfile|
|
145
|
+
temp_files[channel] = tempfile.read
|
135
146
|
end
|
136
147
|
|
137
|
-
#
|
138
|
-
#
|
139
|
-
return
|
148
|
+
# Finally, return contents of the remaining temp files if the
|
149
|
+
# command completed successfully or raise CommandFailed error.
|
150
|
+
return temp_files.values if status.success?
|
151
|
+
raise CommandFailed.new(status.exitstatus, **temp_files)
|
140
152
|
end
|
141
153
|
|
142
154
|
# Run SequenceServer as a self-hosted server using Thin webserver.
|
@@ -0,0 +1,55 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
|
3
|
+
class ErrorModal extends React.Component {
|
4
|
+
|
5
|
+
constructor(props) {
|
6
|
+
super(props);
|
7
|
+
}
|
8
|
+
|
9
|
+
render() {
|
10
|
+
return (
|
11
|
+
<div
|
12
|
+
id="error" ref="errorModal" className="modal fade"
|
13
|
+
data-keyboard="false" data-backdrop="static">
|
14
|
+
<div
|
15
|
+
className="modal-dialog modal-lg">
|
16
|
+
<div
|
17
|
+
className="modal-content">
|
18
|
+
<div
|
19
|
+
className="modal-header">
|
20
|
+
<h3>{this.props.errorData.title}</h3>
|
21
|
+
</div>
|
22
|
+
|
23
|
+
<div
|
24
|
+
className="modal-body">
|
25
|
+
<p dangerouslySetInnerHTML={{ __html: this.props.errorData.message}}></p>
|
26
|
+
|
27
|
+
{
|
28
|
+
this.props.errorData.more_info &&
|
29
|
+
<pre className="pre-scrollable">
|
30
|
+
{this.props.errorData.more_info}
|
31
|
+
</pre>
|
32
|
+
}
|
33
|
+
</div>
|
34
|
+
</div>
|
35
|
+
</div>
|
36
|
+
</div>
|
37
|
+
);
|
38
|
+
}
|
39
|
+
|
40
|
+
componentDidMount() {
|
41
|
+
$(React.findDOMNode(this.refs.errorModal)).modal('show');
|
42
|
+
}
|
43
|
+
}
|
44
|
+
|
45
|
+
export default function showErrorModal (errorData, beforeShow) {
|
46
|
+
if (!beforeShow) {
|
47
|
+
beforeShow = function () {};
|
48
|
+
}
|
49
|
+
|
50
|
+
setTimeout(function () {
|
51
|
+
beforeShow();
|
52
|
+
React.render(<ErrorModal errorData={errorData}/>,
|
53
|
+
document.getElementById('view'));
|
54
|
+
}, 500);
|
55
|
+
}
|
data/public/js/report.js
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
import SequenceServer from './sequenceserver';
|
2
|
+
import showErrorModal from './errormodal';
|
3
|
+
|
2
4
|
import _ from 'underscore';
|
3
5
|
import React from 'react';
|
4
6
|
import d3 from 'd3';
|
@@ -272,7 +274,7 @@ var SequenceViewer = (function () {
|
|
272
274
|
})
|
273
275
|
}, this))
|
274
276
|
.fail(function (jqXHR, status, error) {
|
275
|
-
|
277
|
+
showErrorModal(jqXHR, function () {
|
276
278
|
this.hide();
|
277
279
|
});
|
278
280
|
});
|
@@ -989,8 +991,10 @@ var Report = React.createClass({
|
|
989
991
|
case 200:
|
990
992
|
this.setState(jqXHR.responseJSON);
|
991
993
|
break;
|
994
|
+
case 404:
|
995
|
+
case 400:
|
992
996
|
case 500:
|
993
|
-
|
997
|
+
showErrorModal(jqXHR.responseJSON);
|
994
998
|
break;
|
995
999
|
}
|
996
1000
|
}, this));
|
data/public/js/sequenceserver.js
CHANGED
@@ -107,16 +107,4 @@ export default {
|
|
107
107
|
$(this).tooltip();
|
108
108
|
});
|
109
109
|
},
|
110
|
-
|
111
|
-
showErrorModal: function (jqXHR, beforeShow) {
|
112
|
-
setTimeout(function () {
|
113
|
-
beforeShow();
|
114
|
-
if (jqXHR.responseText) {
|
115
|
-
$("#error").html(jqXHR.responseText).modal();
|
116
|
-
}
|
117
|
-
else {
|
118
|
-
$("#error-no-response").modal();
|
119
|
-
}
|
120
|
-
}, 500);
|
121
|
-
}
|
122
110
|
};
|