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
@@ -28,6 +28,10 @@ module SequenceServer
28
28
 
29
29
  # We don't want Sinatra do setup any loggers for us. We will use our own.
30
30
  set :logging, nil
31
+
32
+ # Override in config.ru if the instance is served under a subpath
33
+ # e.g. for example.org/our-sequenceserver set to '/our-sequenceserver'
34
+ set :root_path_prefix, ''
31
35
  end
32
36
 
33
37
  # See
@@ -51,7 +55,9 @@ module SequenceServer
51
55
  frame_options = SequenceServer.config[:frame_options]
52
56
  frame_options && { frame_options: frame_options }
53
57
  }
58
+ end
54
59
 
60
+ unless ENV['SEQUENCE_SERVER_COMPRESS_RESPONSES'] == 'false'
55
61
  # Serve compressed responses.
56
62
  use Rack::Deflater
57
63
  end
@@ -105,16 +111,40 @@ module SequenceServer
105
111
  # an empty body if the job hasn't finished yet.
106
112
  get '/:jid.json' do |jid|
107
113
  job = Job.fetch(jid)
114
+ halt 404, { error: 'Job not found' }.to_json if job.nil?
108
115
  halt 202 unless job.done?
109
- Report.generate(job).to_json
116
+
117
+ report = Report.generate(job)
118
+ halt 202 unless report.done?
119
+
120
+ display_large_result_warning =
121
+ SequenceServer.config[:large_result_warning_threshold].to_i.positive? &&
122
+ params[:bypass_file_size_warning] != 'true' &&
123
+ report.xml_file_size > SequenceServer.config[:large_result_warning_threshold]
124
+
125
+ if display_large_result_warning
126
+ halt 200,
127
+ {
128
+ user_warning: 'LARGE_RESULT',
129
+ download_links: [
130
+ { name: 'Standard Tabular Report', url: "download/#{jid}.std_tsv" },
131
+ { name: 'Full Tabular Report', url: "/download/#{jid}.full_tsv" },
132
+ { name: 'Results in XML', url: "/download/#{jid}.xml" }
133
+ ]
134
+ }.to_json
135
+ end
136
+
137
+ report.to_json
110
138
  end
111
139
 
112
140
  # Returns base HTML. Rest happens client-side: polling for and rendering
113
141
  # the results.
114
- get '/:jid' do
142
+ get '/:jid' do |jid|
143
+ job = Job.fetch(jid)
144
+ halt 404, File.read(File.join(settings.root, 'public/404.html')) if job.nil?
145
+
115
146
  erb :report, layout: true
116
147
  end
117
-
118
148
  # @params sequence_ids: whitespace separated list of sequence ids to
119
149
  # retrieve
120
150
  # @params database_ids: whitespace separated list of database ids to
@@ -144,14 +174,17 @@ module SequenceServer
144
174
  # Download BLAST report in various formats.
145
175
  get '/download/:jid.:type' do |jid, type|
146
176
  job = Job.fetch(jid)
177
+ halt 404, { error: 'Job not found' }.to_json if job.nil?
147
178
  out = BLAST::Formatter.new(job, type)
148
- send_file out.file, filename: out.filename, type: out.mime
179
+ halt 404, { error: 'File not found"' }.to_json unless File.exist?(out.filepath)
180
+ send_file out.filepath, filename: out.filename, type: out.mime
149
181
  end
150
182
 
151
183
  post '/cloud_share' do
152
184
  content_type :json
153
185
  request_params = JSON.parse(request.body.read)
154
186
  job = Job.fetch(request_params['job_id'])
187
+ halt 404, { error: 'Job not found' }.to_json if job.nil?
155
188
 
156
189
  unless job.done?
157
190
  status 422
@@ -245,6 +278,7 @@ module SequenceServer
245
278
  end
246
279
 
247
280
  if request.env['HTTP_ACCEPT'].to_s.include?('application/json')
281
+ status 422
248
282
  content_type :json
249
283
  error_data.to_json
250
284
  else
@@ -255,7 +289,8 @@ module SequenceServer
255
289
 
256
290
  # Get the query sequences, selected databases, and advanced params used.
257
291
  def update_searchdata_from_job(searchdata)
258
- job = Job.fetch(params[:job_id])
292
+ job = fetch_job(params[:job_id])
293
+ return { error: 'Job not found' }.to_json if job.nil?
259
294
  return if job.imported_xml_file
260
295
 
261
296
  # Only read job.qfile if we are not going to use Database.retrieve.
@@ -277,5 +312,17 @@ module SequenceServer
277
312
  searchdata[:options][method]['last search'] = [job.advanced]
278
313
  end
279
314
  end
315
+
316
+ helpers do
317
+ def root_path_prefix
318
+ settings.root_path_prefix.to_s
319
+ end
320
+ end
321
+
322
+ private
323
+
324
+ def fetch_job(job_id)
325
+ Job.fetch(job_id)
326
+ end
280
327
  end
281
328
  end
@@ -1,4 +1,4 @@
1
- require 'rack/handler/webrick'
1
+ require 'rackup/handler/webrick'
2
2
 
3
3
  module SequenceServer
4
4
  # Simple wrapper around WEBrick and Rack::Handler::WEBrick to host
@@ -67,7 +67,7 @@ module SequenceServer
67
67
 
68
68
  # Now move the temporary file to the given path.
69
69
  # TODO: don't we need to explicitly close the temp file here?
70
- FileUtils.mv(temp_files.delete(channel), filename)
70
+ FileUtils.cp(temp_files[channel], filename)
71
71
  end
72
72
 
73
73
  # Read the remaining temp files into memory. For large outputs,
@@ -1,4 +1,4 @@
1
1
  # Define version number.
2
2
  module SequenceServer
3
- VERSION = '2.1.0'.freeze
3
+ VERSION = '3.0'.freeze
4
4
  end
@@ -2,6 +2,9 @@ require 'English'
2
2
  require 'socket'
3
3
  require 'resolv'
4
4
 
5
+ Encoding.default_external = 'UTF-8'
6
+ Encoding.default_internal = 'UTF-8'
7
+
5
8
  # Top level module / namespace.
6
9
  module SequenceServer
7
10
  # The default version of BLAST that will be downloaded and configured for use.
@@ -62,6 +65,9 @@ module SequenceServer
62
65
 
63
66
  # SequenceServer initialisation routine.
64
67
  def init(config = {})
68
+ # Reset makeblastdb cache, because configuration may have changed.
69
+ @makeblastdb = nil
70
+
65
71
  # Use default config file if caller didn't specify one.
66
72
  config[:config_file] ||= DEFAULT_CONFIG_FILE
67
73
 
@@ -201,10 +207,13 @@ module SequenceServer
201
207
 
202
208
  logger.debug("Will look for BLAST+ databases in: #{config[:database_dir]}")
203
209
 
204
- makeblastdb.scan
205
- fail NO_BLAST_DATABASE_FOUND, config[:database_dir] if !makeblastdb.any_formatted?
210
+ fail NO_BLAST_DATABASE_FOUND, config[:database_dir] unless makeblastdb.any_formatted?
206
211
 
207
212
  Database.collection = makeblastdb.formatted_fastas
213
+ check_database_compatibility unless config[:optimistic].to_s == 'true'
214
+ end
215
+
216
+ def check_database_compatibility
208
217
  Database.each do |database|
209
218
  logger.debug "Found #{database.type} database '#{database.title}' at '#{database.path}'"
210
219
  if database.non_parse_seqids?
data/public/404.html ADDED
@@ -0,0 +1,27 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="utf-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1">
7
+
8
+ <title>SequenceServer: Not Found</title>
9
+
10
+ <!-- Bootstrap CSS -->
11
+ <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet"
12
+ integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
13
+ </head>
14
+
15
+ <body class="bg-light text-dark text-center">
16
+
17
+ <img src="SequenceServer_logo.png" alt="SequenceServer Logo" class="mt-5 mb-3" style="max-width: 200px;">
18
+
19
+ <div class="container" style="margin-top: 10%;">
20
+ <h1 class="display-4">404 Not Found</h1>
21
+ <p class="lead">Sorry, the page you are looking for could not be found.</p>
22
+ <a href="/" class="btn btn-primary mt-3">Start over</a>
23
+ </div>
24
+
25
+ </body>
26
+
27
+ </html>
data/public/config.js CHANGED
@@ -29,7 +29,6 @@ System.config({
29
29
  "react-dom": "npm:react-dom@18.0.0",
30
30
  "underscore": "npm:underscore@1.8.3",
31
31
  "vakata/jstree": "github:vakata/jstree@3.3.8",
32
- "webshim": "npm:webshim@1.15.8",
33
32
  "github:components/jqueryui@1.11.4": {
34
33
  "jquery": "github:components/jquery@2.1.4"
35
34
  },
@@ -143,11 +142,6 @@ System.config({
143
142
  },
144
143
  "npm:vm-browserify@0.0.4": {
145
144
  "indexof": "npm:indexof@0.0.1"
146
- },
147
- "npm:webshim@1.15.8": {
148
- "fs": "github:jspm/nodelibs-fs@0.1.2",
149
- "path": "github:jspm/nodelibs-path@0.1.0",
150
- "process": "github:jspm/nodelibs-process@0.1.2"
151
145
  }
152
146
  }
153
147
  });
@@ -44,7 +44,7 @@ svg .axis path,
44
44
  font-weight: bold;
45
45
  }
46
46
 
47
- /* Graphical overview of hits */
47
+ /* Graphical overview of aligning hit sequences to the query */
48
48
  .alignment-overview.svg-container {
49
49
  text-align: center;
50
50
  }
@@ -84,6 +84,8 @@ h4 > .fa {
84
84
  */
85
85
  .disabled {
86
86
  color: #ccc !important;
87
+ cursor: not-allowed;
88
+ pointer-events: none; /* This prevents the click from happening */
87
89
  }
88
90
 
89
91
  a.disabled:hover,
@@ -219,6 +221,15 @@ a.disabled:hover,
219
221
  color: #5f5f5f;
220
222
  }
221
223
 
224
+ .clamped-paragraph {
225
+ -webkit-line-clamp: 2;
226
+ -webkit-box-orient: vertical;
227
+ display: -webkit-box;
228
+ overflow: hidden;
229
+ text-overflow: ellipsis;
230
+ overflow-wrap: break-word;
231
+ }
232
+
222
233
  /**
223
234
  * Set max-width and font-family on tooltips.
224
235
  */
@@ -363,24 +374,22 @@ td.nowrap-ellipsis {
363
374
 
364
375
  .query-container {
365
376
  margin-top: 35px;
366
- margin-bottom: 0;
377
+ margin-bottom: 35px;
378
+ position: relative;
367
379
  }
368
380
 
369
381
  .notifications {
370
- position: relative;
382
+ position: fixed;
383
+ top: 0;
384
+ left: 0;
385
+ width: 100%;
371
386
  height: 32px;
372
-
373
- /**
374
- * Notifications should appear over the bottom border of the textarea, high
375
- * enough that they do not interfere with the database listing below and
376
- * narrow enough not to cover the textarea resize handle on the right. */
377
- top: -16px;
378
- margin-right: 35px;
379
- margin-left: 35px;
387
+ padding-right: 35px;
388
+ padding-left: 35px;
380
389
  }
381
390
 
382
391
  .notification {
383
- height: 32px !important;
392
+ margin-top: 6px;
384
393
  }
385
394
 
386
395
  .notification .alert-info,
@@ -413,6 +422,8 @@ label[for="advanced"] {
413
422
  white-space: nowrap;
414
423
  vertical-align: middle;
415
424
  padding: 5px 12px 5px 0;
425
+ cursor: default;
426
+ pointer-events: none;
416
427
  }
417
428
 
418
429
  input[name="advanced"] {