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.

Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +16 -5
  3. data/README.md +3 -0
  4. data/lib/sequenceserver/api_errors.rb +67 -0
  5. data/lib/sequenceserver/blast/constants.rb +1 -1
  6. data/lib/sequenceserver/blast/formatter.rb +4 -2
  7. data/lib/sequenceserver/blast/job.rb +17 -62
  8. data/lib/sequenceserver/blast/report.rb +15 -2
  9. data/lib/sequenceserver/blast.rb +1 -0
  10. data/lib/sequenceserver/exceptions.rb +2 -3
  11. data/lib/sequenceserver/job.rb +72 -44
  12. data/lib/sequenceserver/routes.rb +29 -25
  13. data/lib/sequenceserver/version.rb +1 -1
  14. data/lib/sequenceserver.rb +32 -20
  15. data/public/js/errormodal.js +55 -0
  16. data/public/js/report.js +6 -2
  17. data/public/js/sequenceserver.js +0 -12
  18. data/public/sequenceserver-report.min.js +15 -15
  19. data/public/sequenceserver-search.min.js +3 -3
  20. data/sequenceserver.gemspec +2 -1
  21. data/spec/capybara_spec.rb +120 -21
  22. data/spec/database/sample/genome/Solenopsis_invicta/Solenopsis_invicta_gnG_subset.fasta.nhd +8 -0
  23. data/spec/database/sample/genome/Solenopsis_invicta/Solenopsis_invicta_gnG_subset.fasta.nhi +0 -0
  24. data/spec/database/sample/genome/Solenopsis_invicta/Solenopsis_invicta_gnG_subset.fasta.nhr +0 -0
  25. data/spec/database/sample/genome/Solenopsis_invicta/Solenopsis_invicta_gnG_subset.fasta.nin +0 -0
  26. data/spec/database/sample/genome/Solenopsis_invicta/Solenopsis_invicta_gnG_subset.fasta.nog +0 -0
  27. data/spec/database/sample/genome/Solenopsis_invicta/Solenopsis_invicta_gnG_subset.fasta.nsd +16 -0
  28. data/spec/database/sample/genome/Solenopsis_invicta/Solenopsis_invicta_gnG_subset.fasta.nsi +0 -0
  29. data/spec/database/sample/genome/Solenopsis_invicta/Solenopsis_invicta_gnG_subset.fasta.nsq +0 -0
  30. data/spec/database/sample/genome/Solenopsis_invicta/Solenopsis_invicta_gnG_subset.txt +8 -0
  31. data/spec/database/sample/proteins/uniprot/2018-04-Swiss-Prot_insecta.fasta.phd +9140 -0
  32. data/spec/database/sample/proteins/uniprot/2018-04-Swiss-Prot_insecta.fasta.phi +0 -0
  33. data/spec/database/sample/proteins/uniprot/2018-04-Swiss-Prot_insecta.fasta.phr +0 -0
  34. data/spec/database/sample/proteins/uniprot/2018-04-Swiss-Prot_insecta.fasta.pin +0 -0
  35. data/spec/database/sample/proteins/uniprot/2018-04-Swiss-Prot_insecta.fasta.pog +0 -0
  36. data/spec/database/sample/proteins/uniprot/2018-04-Swiss-Prot_insecta.fasta.psd +18280 -0
  37. data/spec/database/sample/proteins/uniprot/2018-04-Swiss-Prot_insecta.fasta.psi +0 -0
  38. data/spec/database/sample/proteins/uniprot/2018-04-Swiss-Prot_insecta.fasta.psq +0 -0
  39. data/spec/database/sample/proteins/uniprot/URL +1 -0
  40. data/spec/nucleotide_query.fa +21 -0
  41. data/spec/protein_query.fa +21 -0
  42. data/spec/routes_spec.rb +2 -0
  43. data/spec/sample_reports/blastn_sample/job.yaml +1 -0
  44. data/spec/sample_reports/blastn_sample/{rfile → stdout} +0 -0
  45. data/spec/sample_reports/blastp_sample/job.yaml +1 -0
  46. data/spec/sample_reports/blastp_sample/{rfile → stdout} +0 -0
  47. data/spec/sample_reports/blastx_sample/job.yaml +1 -0
  48. data/spec/sample_reports/blastx_sample/{rfile → stdout} +0 -0
  49. data/spec/sample_reports/no_hits_sample/job.yaml +1 -0
  50. data/spec/sample_reports/no_hits_sample/{rfile → stdout} +0 -0
  51. data/spec/sample_reports/tblastn_sample/job.yaml +1 -0
  52. data/spec/sample_reports/tblastn_sample/{rfile → stdout} +0 -0
  53. data/spec/sample_reports/tblastx_sample/job.yaml +1 -0
  54. data/spec/sample_reports/tblastx_sample/{rfile → stdout} +0 -0
  55. data/spec/sample_reports/with_hits_sample/job.yaml +1 -0
  56. data/spec/sample_reports/with_hits_sample/{rfile → stdout} +0 -0
  57. data/spec/sequenceserver_spec.rb +1 -1
  58. data/spec/spec_helper.rb +2 -16
  59. data/views/layout.erb +0 -45
  60. metadata +55 -16
  61. data/lib/sequenceserver/blast/exceptions.rb +0 -27
  62. data/views/400.erb +0 -29
  63. data/views/500.erb +0 -41
@@ -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
- temp_stdout_file = Tempfile.new 'sequenceserver-sys'
97
- temp_stderr_file = Tempfile.new 'sequenceserver-sys'
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>#{temp_stdout_file.path} 2>#{temp_stderr_file.path}")
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
- unless status == 0
121
- raise CommandFailed.new(temp_stdout_file.read, temp_stderr_file.read, status)
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
- # Store stdout and/or stderr in files, if paths for the files were given.
125
- # If a full path was given for an output file, move the temporary file
126
- # to this path. If the path given does not exist, create it.
127
- [options[:stdout], options[:stderr]].each_with_index do |filename, index|
128
- if filename
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
- # If paths to write stdout and stderr to were not given, return the
138
- # contents of stdout and/or stderr. Otherwise, return nil.
139
- return temp_stdout_file.read, temp_stderr_file.read unless options[:stdout] || options[:stderr]
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
- SequenceServer.showErrorModal(jqXHR, function () {
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
- SequenceServer.showErrorModal(jqXHR, function () {});
997
+ showErrorModal(jqXHR.responseJSON);
994
998
  break;
995
999
  }
996
1000
  }, this));
@@ -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
  };