sequenceserver 2.1.0 → 3.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of sequenceserver might be problematic. Click here for more details.

Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/COPYRIGHT.txt +1 -1
  3. data/bin/sequenceserver +10 -3
  4. data/lib/sequenceserver/blast/error.rb +53 -0
  5. data/lib/sequenceserver/blast/formatter.rb +13 -4
  6. data/lib/sequenceserver/blast/job.rb +2 -43
  7. data/lib/sequenceserver/blast/report.rb +33 -3
  8. data/lib/sequenceserver/config.rb +4 -1
  9. data/lib/sequenceserver/job.rb +21 -11
  10. data/lib/sequenceserver/makeblastdb-modified-with-cache.rb +345 -0
  11. data/lib/sequenceserver/makeblastdb.rb +97 -75
  12. data/lib/sequenceserver/pool.rb +1 -1
  13. data/lib/sequenceserver/report.rb +1 -5
  14. data/lib/sequenceserver/routes.rb +52 -5
  15. data/lib/sequenceserver/server.rb +1 -1
  16. data/lib/sequenceserver/sys.rb +1 -1
  17. data/lib/sequenceserver/version.rb +1 -1
  18. data/lib/sequenceserver.rb +11 -2
  19. data/public/404.html +27 -0
  20. data/public/config.js +0 -6
  21. data/public/css/grapher.css +1 -1
  22. data/public/css/sequenceserver.css +22 -11
  23. data/public/css/sequenceserver.min.css +2 -2
  24. data/public/js/circos.js +7 -3
  25. data/public/js/dnd.js +3 -3
  26. data/public/js/fastq_to_fasta.js +35 -0
  27. data/public/js/form.js +30 -11
  28. data/public/js/grapher.js +123 -113
  29. data/public/js/hit.js +8 -2
  30. data/public/js/hits_overview.js +4 -1
  31. data/public/js/jquery_world.js +0 -1
  32. data/public/js/kablammo.js +4 -0
  33. data/public/js/length_distribution.js +5 -1
  34. data/public/js/null_plugins/download_links.js +7 -0
  35. data/public/js/null_plugins/hit_buttons.js +11 -0
  36. data/public/js/null_plugins/report_plugins.js +18 -0
  37. data/public/js/query.js +26 -6
  38. data/public/js/report.js +92 -22
  39. data/public/js/search.js +0 -8
  40. data/public/js/sidebar.js +11 -1
  41. data/public/js/tests/advanced_parameters.spec.js +36 -0
  42. data/public/js/tests/mock_data/sequences.js +49 -0
  43. data/public/js/tests/report.spec.js +62 -6
  44. data/public/js/tests/search_query.spec.js +45 -19
  45. data/public/js/visualisation_helpers.js +1 -1
  46. data/public/sequenceserver-report.min.js +76 -42
  47. data/public/sequenceserver-search.min.js +34 -33
  48. data/views/layout.erb +9 -12
  49. metadata +34 -23
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3cf703fae66ad96d285ed0556c387dabb0d69be120db5bdd3c3f9f8a03d3a814
4
- data.tar.gz: 503bb0b69cbf773ab536d99f6782f4fff19f4872c49e6377d49a9f7820861c3b
3
+ metadata.gz: 68dcb3dda53edae5d095423c164568484e786b927fcf733a4722eafde7c3a155
4
+ data.tar.gz: afb985fe5e762b8a1ab9e1dc4e8dd0bc6158f601a3cc95c0029f03a8587c1fa2
5
5
  SHA512:
6
- metadata.gz: 1896b2afddf6033c98747f7eba1dabbe15b270940bd19760ebef4ed75af267760d45d40215663173ccb2f964472b458179a459316b86ef72bc26aa75d62faad0
7
- data.tar.gz: 4ac1d9a5a205d299af4b1467521a9bc539e3833d0a571cfa90b490b19df958fc0f7ee2e1341e3d8d5e19fccbe2ee6874884fc7fbcbfbdc6abbe1e60df3c9a76e
6
+ metadata.gz: fb122a17858e6b7c567a418bda05358ae1a9b34ef1dfdcc11bb5f83097b47e427d7344e61e9f9102488f59f6448592b7d66e1e67ee213498e750dfea5e2e7c8f
7
+ data.tar.gz: b7b7504faf439acda18aafa0866e74f3645e431b4252bdb12ffd4896d7cf6ee065756db9e1bba027184794f306ce3b732c4911dce56d8b4a96e734dcf86c336c
data/COPYRIGHT.txt CHANGED
@@ -3,7 +3,7 @@ SequenceServer is copyright Anurag Priyam, Ben J Woodcroft and Yannick Wurm,
3
3
  version 3, the text of which can be found in LICENSE.txt.
4
4
 
5
5
  Components of SequenceServer, including Sinatra, Ox, Slop, html5shiv,
6
- Underscore, jQuery, jQuery UI, Bootstrap and Webshim, are licensed under
6
+ Underscore, jQuery, jQuery UI and Bootstrap, are licensed under
7
7
  the MIT license. D3.js is licensed under BSD license. biojs-vis-sequence
8
8
  is licensed under Apache license. Thin and JSON are licensed under Ruby
9
9
  license. All unmodified files from these and other sources retain their
data/bin/sequenceserver CHANGED
@@ -119,6 +119,11 @@ begin
119
119
  'Port to run SequenceServer on',
120
120
  argument: true
121
121
 
122
+ on 'o', 'optimistic=',
123
+ 'Optimistic mode does not perform database compatibility checks, which can be faster. ' \
124
+ 'Only use this if you format FASTAs with "sequenceserver -make-blast-databases"',
125
+ argument: true
126
+
122
127
  on 's', 'set',
123
128
  'Set configuration value in default or given config file'
124
129
 
@@ -296,7 +301,7 @@ begin
296
301
  unless response =~ /^[n]$/i
297
302
  puts
298
303
  puts 'Searching ...'
299
- if SequenceServer.makeblastdb.any_unformatted?
304
+ if SequenceServer.makeblastdb.any_to_format?
300
305
  formatted = SequenceServer.makeblastdb.format
301
306
  exit! if formatted.empty? && !set?
302
307
  redo unless set?
@@ -353,7 +358,9 @@ begin
353
358
  end
354
359
 
355
360
  if make_blast_databases?
356
- if SequenceServer.makeblastdb.scan
361
+ if SequenceServer.makeblastdb.no_fastas?
362
+ puts "Couldn't find any FASTA files in #{SequenceServer.config[:database_dir]}."
363
+ elsif SequenceServer.makeblastdb.any_to_format_or_reformat?
357
364
  puts
358
365
  puts <<~MSG
359
366
  SequenceServer has scanned your databases directory and will now offer
@@ -375,7 +382,7 @@ begin
375
382
  print '>> '
376
383
  response = STDIN.gets.to_s.strip
377
384
  SequenceServer.makeblastdb.run unless response =~ /^[n]$/i
378
- else
385
+ else
379
386
  puts "All FASTA files in #{SequenceServer.config[:database_dir]} " \
380
387
  'are formatted.'
381
388
  end
@@ -0,0 +1,53 @@
1
+ # http://www.ncbi.nlm.nih.gov/books/NBK1763/ (Appendices)
2
+
3
+ module SequenceServer
4
+ module BLAST
5
+ class Error
6
+ attr_reader :exitstatus, :stdout, :stderr
7
+
8
+ def initialize(exitstatus:, stdout:, stderr:)
9
+ @exitstatus = exitstatus
10
+ @stdout = stdout
11
+ @stderr = stderr
12
+ end
13
+
14
+ def raise!
15
+ return true if exitstatus.zero? && !File.zero?(stdout)
16
+
17
+ case exitstatus
18
+ when 1..2
19
+ # 1: Error in query sequences or options.
20
+ # 2: Error in BLAST databases.
21
+ error = IO.foreach(stderr).grep(ERROR_LINE).join
22
+ error = File.read(stderr) if error.empty?
23
+ fail InputError, "(#{exitstatus}) #{error}"
24
+ when 4
25
+ # Out of memory. User can retry with a shorter search, so raising
26
+ # InputError here instead of SystemError.
27
+ fail InputError, <<~MSG
28
+ Ran out of memory. Please try a smaller query, fewer and smaller
29
+ databases, or limiting the output by using advanced options.
30
+ MSG
31
+ when 6
32
+ # Error creating output files. It can't be a permission issue as that
33
+ # would have been caught while creating job directory. But we can run
34
+ # out of storage after creating the job directory and while running
35
+ # the job. This is a SystemError.
36
+ fail SystemError, 'Ran out of disk space.'
37
+ else
38
+ # I am not sure what the exit codes 3 means and we should not
39
+ # encounter exit code 5. The only other error that I know can happen
40
+ # but is not yet handled is when BLAST+ binaries break such as after
41
+ # macOS updates. So raise SystemError, include the exit status in the
42
+ # message, and say that that the "most likely" reason is broken BLAST+
43
+ # binaries.
44
+
45
+ error = File.read(stderr)
46
+ error = 'Most likely there is a problem with the BLAST+ binaries.' if error.empty?
47
+
48
+ fail SystemError, "BLAST failed abruptly (exit status: #{exitstatus}). #{error}"
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -25,23 +25,32 @@ module SequenceServer
25
25
 
26
26
  attr_reader :format, :mime, :specifiers
27
27
 
28
- def file
29
- @file ||= File.join(job.dir, filename)
28
+ def filepath
29
+ @filepath ||= File.join(job.dir, filename)
30
+ end
31
+
32
+ def size
33
+ File.size(filepath)
30
34
  end
31
35
 
32
36
  def filename
33
37
  @filename ||= "sequenceserver-#{type}_report.#{mime}"
34
38
  end
35
39
 
40
+ def read_file
41
+ File.read(filepath)
42
+ end
43
+
36
44
  private
37
45
 
38
46
  attr_reader :job, :type
39
47
 
40
48
  def run
41
- return if File.exist?(file)
49
+ return if File.exist?(filepath)
50
+
42
51
  command = "blast_formatter -archive '#{job.stdout}'" \
43
52
  " -outfmt '#{format} #{specifiers}'"
44
- sys(command, path: config[:bin], dir: DOTDIR, stdout: file)
53
+ sys(command, path: config[:bin], dir: DOTDIR, stdout: filepath)
45
54
  rescue CommandFailed => e
46
55
  # Mostly we will never get here: empty archive file,
47
56
  # file permissions, broken BLAST binaries, etc. will
@@ -1,5 +1,6 @@
1
1
  require 'sequenceserver/job'
2
2
  require 'sequenceserver/zip_file_generator'
3
+ require 'sequenceserver/blast/error'
3
4
 
4
5
  module SequenceServer
5
6
  # BLAST module.
@@ -56,46 +57,8 @@ module SequenceServer
56
57
  " -query '#{qfile}' #{options}"
57
58
  end
58
59
 
59
- # Override Job#raise! to raise specific API errors based on exitstatus
60
- # and using contents of stderr to provide context about the error.
61
- #
62
60
  def raise!
63
- # Return true exit status is 0 and stdout is not empty.
64
- return true if exitstatus.zero? && !File.zero?(stdout)
65
-
66
- # Handle error. See [1].
67
- case exitstatus
68
- when 1..2
69
- # 1: Error in query sequences or options.
70
- # 2: Error in BLAST databases.
71
- error = IO.foreach(stderr).grep(ERROR_LINE).join
72
- error = File.read(stderr) if error.empty?
73
- fail InputError, "(#{exitstatus}) #{error}"
74
- when 4
75
- # Out of memory. User can retry with a shorter search, so raising
76
- # InputError here instead of SystemError.
77
- fail InputError, <<~MSG
78
- Ran out of memory. Please try a smaller query, fewer and smaller
79
- databases, or limiting the output by using advanced options.
80
- MSG
81
- when 6
82
- # Error creating output files. It can't be a permission issue as that
83
- # would have been caught while creating job directory. But we can run
84
- # out of storage after creating the job directory and while running
85
- # the job. This is a SystemError.
86
- fail SystemError, 'Ran out of disk space.'
87
- else
88
- # I am not sure what the exit codes 3 means and we should not
89
- # encounter exit code 5. The only other error that I know can happen
90
- # but is not yet handled is when BLAST+ binaries break such as after
91
- # macOS updates. So raise SystemError, include the exit status in the
92
- # message, and say that that the "most likely" reason is broken BLAST+
93
- # binaries.
94
- fail SystemError, <<~MSG
95
- BLAST failed abruptly (exit status: #{exitstatus}). Most likely there is a
96
- problem with the BLAST+ binaries.
97
- MSG
98
- end
61
+ SequenceServer::BLAST::Error.new(exitstatus: exitstatus, stdout: stdout, stderr: stderr).raise!
99
62
  end
100
63
 
101
64
  # Use it with a block to get a self-cleaning temporary archive file
@@ -189,7 +152,3 @@ module SequenceServer
189
152
  end
190
153
  end
191
154
  end
192
-
193
- # References
194
- # ----------
195
- # [1]: http://www.ncbi.nlm.nih.gov/books/NBK1763/ (Appendices)
@@ -36,6 +36,8 @@ module SequenceServer
36
36
  attr_reader :querydb, :dbtype, :params
37
37
 
38
38
  def to_json(*_args)
39
+ generate
40
+
39
41
  %i[querydb program program_version params stats
40
42
  queries].inject({}) do |h, k|
41
43
  h[k] = send(k)
@@ -48,10 +50,18 @@ module SequenceServer
48
50
  non_parse_seqids: !!job.databases&.any?(&:non_parse_seqids?)).to_json
49
51
  end
50
52
 
51
- private
53
+ def xml_file_size
54
+ return File.size(job.imported_xml_file) if job.imported_xml_file
55
+
56
+ generate
57
+
58
+ xml_formatter.size
59
+ end
52
60
 
53
61
  # Generate report.
54
62
  def generate
63
+ return self if @_generated
64
+
55
65
  job.raise!
56
66
  xml_ir = nil
57
67
  tsv_ir = nil
@@ -63,14 +73,34 @@ module SequenceServer
63
73
  end
64
74
  end
65
75
  else
66
- xml_ir = parse_xml File.read(Formatter.run(job, 'xml').file)
67
- tsv_ir = parse_tsv File.read(Formatter.run(job, 'custom_tsv').file)
76
+ xml_ir = parse_xml(xml_formatter.read_file)
77
+ tsv_ir = parse_tsv(tsv_formatter.read_file)
68
78
  end
69
79
  extract_program_info xml_ir
70
80
  extract_db_info xml_ir
71
81
  extract_params xml_ir
72
82
  extract_stats xml_ir
73
83
  extract_queries xml_ir, tsv_ir
84
+
85
+ @_generated = true
86
+
87
+ self
88
+ end
89
+
90
+ def done?
91
+ return true if job.imported_xml_file
92
+
93
+ File.exist?(xml_formatter.filepath) && File.exist?(tsv_formatter.filepath)
94
+ end
95
+
96
+ private
97
+
98
+ def xml_formatter
99
+ @xml_formatter ||= Formatter.run(job, 'xml')
100
+ end
101
+
102
+ def tsv_formatter
103
+ @tsv_formatter ||= Formatter.run(job, 'custom_tsv')
74
104
  end
75
105
 
76
106
  # Make program name and program name + version available via `program`
@@ -131,7 +131,10 @@ module SequenceServer
131
131
  num_jobs: 1,
132
132
  job_lifetime: 43_200,
133
133
  # Set cloud_share_url to 'disabled' to disable the cloud sharing feature
134
- cloud_share_url: 'https://share.sequenceserver.com/api/v1/shared-job'
134
+ cloud_share_url: 'https://share.sequenceserver.com/api/v1/shared-job',
135
+ # Warn in the UI before rendering results larger than this value
136
+ large_result_warning_threshold: 250 * 1024 * 1024,
137
+ optimistic: false # Faster, but does not perform DB compatibility checks
135
138
  }
136
139
  end
137
140
  end
@@ -28,16 +28,25 @@ module SequenceServer
28
28
  enqueue(job)
29
29
  end
30
30
 
31
+ def serializable_classes
32
+ [
33
+ Time,
34
+ Symbol,
35
+ SequenceServer::Job,
36
+ SequenceServer::BLAST::Job,
37
+ SequenceServer::Database
38
+ ]
39
+ end
40
+
31
41
  # Fetches job with the given id.
32
42
  def fetch(id)
33
43
  job_file = File.join(DOTDIR, id, 'job.yaml')
34
- fail NotFound unless File.exist?(job_file)
35
- if RUBY_VERSION < '3.1.0'
36
- YAML.load_file(job_file)
37
- else
38
- YAML.load_file(job_file, permitted_classes: [Time, Symbol, SequenceServer::BLAST::Job, \
39
- SequenceServer::Database, SequenceServer::Job])
40
- end
44
+ return nil unless File.exist?(job_file)
45
+
46
+ YAML.safe_load_file(
47
+ job_file,
48
+ permitted_classes: serializable_classes
49
+ )
41
50
  end
42
51
 
43
52
  # Deletes job with the given id.
@@ -75,8 +84,8 @@ module SequenceServer
75
84
  # of job data will be held, yields (if block given) and saves the job.
76
85
  #
77
86
  # Subclasses should extend `initialize` as per requirement.
78
- def initialize(*)
79
- @id = SecureRandom.uuid
87
+ def initialize(params = {})
88
+ @id = params.fetch(:id, SecureRandom.uuid)
80
89
  @submitted_at = Time.now
81
90
  mkdir_p dir
82
91
  yield if block_given?
@@ -85,7 +94,7 @@ module SequenceServer
85
94
  raise SystemError, 'Not enough disk space to start a new job'
86
95
  rescue Errno::EACCES
87
96
  raise SystemError, "Permission denied to write to #{DOTDIR}"
88
- rescue => e
97
+ rescue StandardError => e
89
98
  rm_rf dir
90
99
  raise e
91
100
  end
@@ -117,7 +126,7 @@ module SequenceServer
117
126
  # should be called on a completed job before attempting to use the results.
118
127
  # Subclasses should provide their own implementation.
119
128
  def raise!
120
- raise if done? && exitstatus != 0
129
+ fail if done? && exitstatus != 0
121
130
  end
122
131
 
123
132
  # Where will the stdout be written to during execution and read from later.
@@ -163,6 +172,7 @@ module SequenceServer
163
172
  def fetch(key)
164
173
  filename = File.join(dir, key)
165
174
  fail unless File.exist? filename
175
+
166
176
  filename
167
177
  end
168
178