genevalidatorapp 1.4.13 → 1.5.0

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.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/Rakefile +5 -1
  4. data/bin/genevalidatorapp +227 -73
  5. data/config.ru +1 -1
  6. data/genevalidatorapp.gemspec +7 -6
  7. data/lib/genevalidatorapp.rb +247 -0
  8. data/lib/{GeneValidatorApp → genevalidatorapp}/config.rb +7 -6
  9. data/lib/{GeneValidatorApp → genevalidatorapp}/database.rb +8 -13
  10. data/lib/genevalidatorapp/exceptions.rb +162 -0
  11. data/lib/{GeneValidatorApp → genevalidatorapp}/genevalidator.rb +52 -58
  12. data/lib/{GeneValidatorApp → genevalidatorapp}/logger.rb +0 -0
  13. data/lib/genevalidatorapp/routes.rb +81 -0
  14. data/lib/genevalidatorapp/server.rb +63 -0
  15. data/lib/{GeneValidatorApp → genevalidatorapp}/version.rb +1 -1
  16. data/public/{web_files → src}/css/bootstrap1.min.css +0 -0
  17. data/public/{web_files → src}/css/custom.css +8 -13
  18. data/public/{web_files → src}/css/custom.min.css +0 -0
  19. data/public/{web_files → src}/css/font-awesome.min.css +0 -0
  20. data/public/{web_files → src}/js/bionode-seq.min.js +0 -0
  21. data/public/{web_files → src}/js/bootstrap.min.js +0 -0
  22. data/public/{web_files → src}/js/d3.v3.min.js +0 -0
  23. data/public/{web_files → src}/js/genevalidator.js +44 -49
  24. data/public/{web_files → src}/js/jquery.cookie.min.js +0 -0
  25. data/public/{web_files → src}/js/jquery.min.js +0 -0
  26. data/public/{web_files → src}/js/jquery.tablesorter.min.js +0 -0
  27. data/public/{web_files → src}/js/jquery.validate.min.js +0 -0
  28. data/public/src/js/plots.js +814 -0
  29. data/public/web_files/css/GV_compiled_css.min.css +15 -0
  30. data/public/web_files/js/GV_compiled_js.min.js +34 -0
  31. data/spec/app_spec.rb +1 -1
  32. data/spec/database_spec.rb +2 -2
  33. data/views/index.slim +1 -1
  34. data/views/layout.slim +15 -24
  35. data/views/results.slim +54 -0
  36. metadata +39 -35
  37. data/lib/GeneValidatorApp.rb +0 -321
  38. data/public/web_files/css/bootstrap.min.css +0 -7
  39. data/public/web_files/js/genevalidator.min.js +0 -1
  40. data/public/web_files/js/plots.js +0 -744
  41. data/public/web_files/js/plots.min.js +0 -1
@@ -0,0 +1,81 @@
1
+ require 'sinatra/base'
2
+ require 'sinatra/cross_origin'
3
+ require 'genevalidator/version'
4
+ require 'genevalidatorapp/version'
5
+ require 'slim'
6
+
7
+ module GeneValidatorApp
8
+ # The Sinatra Routes
9
+ class Routes < Sinatra::Base
10
+ register Sinatra::CrossOrigin
11
+
12
+ configure do
13
+ # We don't need Rack::MethodOverride. Let's avoid the overhead.
14
+ disable :method_override
15
+
16
+ # Ensure exceptions never leak out of the app. Exceptions raised within
17
+ # the app must be handled by the app. We do this by attaching error
18
+ # blocks to exceptions we know how to handle and attaching to Exception
19
+ # as fallback.
20
+ disable :show_exceptions, :raise_errors
21
+
22
+ # Make it a policy to dump to 'rack.errors' any exception raised by the
23
+ # app so that error handlers don't have to do it themselves. But for it
24
+ # to always work, Exceptions defined by us should not respond to `code`
25
+ # or http_status` methods. Error blocks errors must explicitly set http
26
+ # status, if needed, by calling `status` method.
27
+ enable :dump_errors
28
+
29
+ # We don't want Sinatra do setup any loggers for us. We will use our own.
30
+ set :logging, nil
31
+
32
+ # This is the app root...
33
+ set :root, lambda { GeneValidatorApp.root }
34
+
35
+ # This is the full path to the public folder...
36
+ set :public_folder, lambda { GeneValidatorApp.public_dir }
37
+ end
38
+
39
+ # Set up global variables for the templates...
40
+ before '/' do
41
+ @default_db = Database.default_db
42
+ @non_default_dbs = Database.non_default_dbs
43
+ @max_characters = GeneValidatorApp.config[:max_characters]
44
+ @current_gv_version = GeneValidator::VERSION
45
+ end
46
+
47
+ get '/' do
48
+ slim :index
49
+ end
50
+
51
+ post '/' do
52
+ cross_origin # Required for the API to work...
53
+ RunGeneValidator.init(request.url, params)
54
+ @json_results = RunGeneValidator.run
55
+ slim :results, layout: false
56
+ end
57
+
58
+ # This error block will only ever be hit if the user gives us a funny
59
+ # sequence or incorrect advanced parameter. Well, we could hit this block
60
+ # if someone is playing around with our HTTP API too.
61
+ error RunGeneValidator::ArgumentError do
62
+ status 400
63
+ slim :"500", layout: false
64
+ end
65
+
66
+ # This will catch any unhandled error and some very special errors. Ideally
67
+ # we will never hit this block. If we do, there's a bug in GeneValidatorApp
68
+ # or something really weird going on.
69
+ # TODO: If we hit this error block we show the stacktrace to the user
70
+ # requesting them to post the same to our Google Group.
71
+ error Exception, RunGeneValidator::RuntimeError do
72
+ status 500
73
+ slim :"500", layout: false
74
+ end
75
+
76
+ not_found do
77
+ status 404
78
+ slim :"500" # TODO: Create another Template
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,63 @@
1
+ require 'rack/handler/webrick'
2
+
3
+ module GeneValidatorApp
4
+ # Simple wrapper around WEBrick and Rack::Handler::WEBrick to host
5
+ # GeneValidatorApp standalone.
6
+ class Server
7
+ class << self
8
+ def run(*args)
9
+ new(*args).start
10
+ end
11
+ end
12
+
13
+ def initialize(app)
14
+ @app = app
15
+ end
16
+
17
+ attr_reader :app
18
+
19
+ # Start server. Raises Errno::EADDRINUSE if port is in use by another
20
+ # process. Raises Errno::EACCES if binding to the port requires root
21
+ # privilege.
22
+ def start
23
+ setup_signal_handlers
24
+ @server = WEBrick::HTTPServer.new(options)
25
+ @server.mount '/', Rack::Handler::WEBrick, app
26
+ @server.start
27
+ end
28
+
29
+ # Stop server.
30
+ def stop
31
+ @server.shutdown
32
+ end
33
+
34
+ # Options Hash passed to WEBrick::HTTPServer.
35
+ # rubocop:disable Metrics/AbcSize
36
+ def options
37
+ @options ||= {
38
+ :BindAddress => app.config[:host],
39
+ :Port => app.config[:port],
40
+ :StartCallback => proc { app.on_start },
41
+ :StopCallback => proc { app.on_stop },
42
+ :OutputBufferSize => 5,
43
+ :AccessLog => [[logdev, WEBrick::AccessLog::COMMON_LOG_FORMAT]],
44
+ :Logger => WEBrick::Log.new(logdev)
45
+ }
46
+ end
47
+ # rubocop:enable Metrics/AbcSize
48
+
49
+ private
50
+
51
+ def setup_signal_handlers
52
+ [:INT, :TERM].each do |sig|
53
+ trap sig do
54
+ stop
55
+ end
56
+ end
57
+ end
58
+
59
+ def logdev
60
+ @logdev ||= app.verbose? ? STDERR : '/dev/null'
61
+ end
62
+ end
63
+ end
@@ -1,3 +1,3 @@
1
1
  module GeneValidatorApp
2
- VERSION = '1.4.13'
2
+ VERSION = '1.5.0'
3
3
  end
@@ -6,7 +6,7 @@ html {
6
6
  }
7
7
 
8
8
  body {
9
- margin: 0;
9
+ margin: 0;
10
10
  margin-top: 60px;
11
11
  background-color:#F5F5F5;
12
12
  }
@@ -175,7 +175,7 @@ table .danger,
175
175
  .table .danger,
176
176
  table .info,
177
177
  .table .info {
178
- color: #333;
178
+ color: #333;
179
179
  }
180
180
 
181
181
  .table-bordered {
@@ -245,11 +245,11 @@ table .info,
245
245
  .table-bordered>tbody>tr>td,
246
246
  .table-bordered>tfoot>tr>td {
247
247
  border:none;
248
- }
248
+ }
249
249
 
250
250
  .table-bordered>tbody>tr {
251
251
  border-bottom: 2px solid #DDD;
252
- }
252
+ }
253
253
 
254
254
  .error_header {
255
255
  margin-top: 10px;
@@ -291,11 +291,6 @@ tr {
291
291
  text-align: center;
292
292
  }
293
293
 
294
- /* table striped backgrounds ___________*/
295
-
296
- /*tbody > tr:nth-child(4n+1), tbody > tr:nth-child(4n+2) {
297
- }
298
- */
299
294
  /* table sorter ___________*/
300
295
 
301
296
 
@@ -337,7 +332,7 @@ tr {
337
332
  .table tbody td.success,
338
333
  .table tbody td.danger,
339
334
  .table tbody td.warning {
340
- padding-left:30px !important;
335
+ padding-left:30px !important;
341
336
  position:relative;
342
337
  }
343
338
 
@@ -390,7 +385,7 @@ ___________________________*/
390
385
  border-right:5px solid transparent;
391
386
  border-top:5px solid #CCC
392
387
  }
393
-
388
+
394
389
  /* D3Js & Axis
395
390
  ___________________________*/
396
391
  .axis path,
@@ -490,7 +485,7 @@ ___________________________*/
490
485
  float:right !important;
491
486
  margin-top: -43px;
492
487
  }
493
-
488
+
494
489
  .show_examples_text {
495
490
  text-align: left;
496
491
  }
@@ -501,7 +496,7 @@ ___________________________*/
501
496
  }
502
497
 
503
498
 
504
- /* Browser Specific
499
+ /* Browser Specific
505
500
  ___________________________*/
506
501
 
507
502
  /* Border on Stars ________*/
@@ -4,6 +4,7 @@ $(document).ready(function() {
4
4
  keepFooterFixedToBottom();
5
5
  addSeqValidation();
6
6
  inputValidation();
7
+ bindTdClicks();
7
8
 
8
9
  $(document).bind('keydown', function (e) {
9
10
  if (e.ctrlKey && e.keyCode === 13 ) {
@@ -12,9 +13,9 @@ $(document).ready(function() {
12
13
  });
13
14
  });
14
15
 
15
- // Looks for a cookie (called 'GeneValidator_adv_params_status') to check the state of the adv_params box when it was last closed.
16
- // This function is called upon as soon as the website is loaded;
17
- function checkCollapseState() {
16
+ // Looks for a cookie (called 'GeneValidator_adv_params_status') to check the state of the adv_params box when it was last closed.
17
+ // This function is called upon as soon as the website is loaded;
18
+ var checkCollapseState = function () {
18
19
  'use strict';
19
20
  if ($.cookie('GeneValidator_adv_params_status')){
20
21
  var adv_params_status = $.cookie('GeneValidator_adv_params_status');
@@ -24,25 +25,26 @@ function checkCollapseState() {
24
25
  $('#adv_params').addClass('in');
25
26
  }
26
27
  }
27
- }
28
+ };
28
29
 
29
30
  // This function simply ensures that the footer stays to fixed to the bottom of the window
30
- function keepFooterFixedToBottom() {
31
+ var keepFooterFixedToBottom = function () {
31
32
  'use strict';
32
33
  $('#mainbody').css({'margin-bottom': (($('#footer').height()) + 15)+'px'});
33
34
  $(window).resize(function(){
34
35
  $('#mainbody').css({'margin-bottom': (($('#footer').height()) + 15)+'px'});
35
36
  });
36
- }
37
+ };
37
38
 
38
39
  // Creates a custom Validation for Jquery Validation plugin...
39
40
  // It ensures that sequences are either protein or DNA data...
40
41
  // If there are multiple sequences, ensures that they are of the same type
41
42
  // It utilises the checkType function (further below)...
42
- function addSeqValidation() {
43
+ var addSeqValidation = function () {
43
44
  'use strict';
44
45
  jQuery.validator.addMethod('checkInputType', function(value, element) {
45
- var types = [];
46
+ var types = [],
47
+ type = '';
46
48
  if (value.charAt(0) === '>') {
47
49
  var seqs_array = value.split('>');
48
50
  for (var i = 1; i < seqs_array.length; i++) {
@@ -52,13 +54,13 @@ function addSeqValidation() {
52
54
  if (clean_lines.length !== 0){
53
55
  clean_lines.shift();
54
56
  var seq = clean_lines.join('');
55
- var type = checkType(seq, 0.9);
57
+ type = checkType(seq, 0.9);
56
58
  types.push(type);
57
59
  if ((type !== 'protein') && (type !== 'dna') && (type !== 'rna')) {
58
60
  return false;
59
61
  }
60
62
  }
61
- }
63
+ }
62
64
  }
63
65
  var firstType = types[0];
64
66
  for (var j = 0; j < types.length; j++) {
@@ -68,7 +70,7 @@ function addSeqValidation() {
68
70
  }
69
71
  return true;
70
72
  } else {
71
- var type = checkType(value, 0.9);
73
+ type = checkType(value, 0.9);
72
74
  if ((type !== 'protein') && (type !== 'dna') && (type !== 'rna')) {
73
75
  return false;
74
76
  } else {
@@ -76,11 +78,11 @@ function addSeqValidation() {
76
78
  }
77
79
  }
78
80
  }, '* The Input must be either DNA or protein sequence(s). Please ensure that your sequences do not contains any non-letter character(s). If there are multiple sequences, ensure that they are all of one type. ');
79
- }
81
+ };
80
82
 
81
83
 
82
84
  // A function that validates the input - Utilises Jquery.Validator.js
83
- function inputValidation() {
85
+ var inputValidation = function () {
84
86
  'use strict';
85
87
  var maxCharacters = $('#seq').attr('data-maxCharacters'); // returns a number or undefined
86
88
  $('#input').validate({
@@ -123,10 +125,22 @@ function inputValidation() {
123
125
  ajaxFunction();
124
126
  }
125
127
  });
126
- }
128
+ };
129
+
130
+ var bindTdClicks = function () {
131
+ $( document ).on( "click", "td, .plot_btn", function( event ) {
132
+ if ($(this).hasClass('success') || $(this).hasClass('danger')){
133
+ var title = $(this).attr('title');
134
+ var val = title.replace(/[ \/]/g, '');
135
+ GV.addData(this, val);
136
+ } else if ($(this).hasClass('plot_btn')){
137
+ GV.addData(this, 'all');
138
+ }
139
+ });
140
+ };
127
141
 
128
142
  // Sends the data within the form to the Server
129
- function ajaxFunction() {
143
+ var ajaxFunction = function () {
130
144
  'use strict';
131
145
  $.ajax({
132
146
  type: 'POST',
@@ -135,15 +149,15 @@ function ajaxFunction() {
135
149
  success: function(response){
136
150
  $('#results_box').show();
137
151
  $('#output').html(response);
152
+ GV.toggleOverviewBtn(); // add overview info from JSON
138
153
  initTableSorter(); // initiate the table sorter
139
154
  $("[data-toggle='tooltip']").tooltip(); // Initiate the tooltips
140
- removeEmptyColumns(); // Remove Unwanted Columns
141
155
 
142
156
  $('#mainbody').css({'background-color': '#fff'});
143
157
  $('#search').css({'background-color': '#F5F5F5'});
144
158
  $('#results').css({'border-top': '3px solid #DBDBDB'});
145
159
  $('#search').css({'margin-bottom': '0'});
146
-
160
+
147
161
  $('#spinner').modal('hide'); // remove progress notification
148
162
  },
149
163
  error: function (e, status) {
@@ -161,11 +175,11 @@ function ajaxFunction() {
161
175
  }
162
176
  }
163
177
  });
164
- }
178
+ };
165
179
 
166
- // Table sortert Initialiser
167
- // Contains a custom parser that allows the Stars to be sorted.
168
- function initTableSorter() {
180
+ // Table sortert Initialiser
181
+ // Contains a custom parser that allows the Stars to be sorted.
182
+ var initTableSorter = function () {
169
183
  'use strict';
170
184
  $.tablesorter.addParser({
171
185
  id: 'star_scores',
@@ -174,7 +188,7 @@ function initTableSorter() {
174
188
  var $cell = $(cell);
175
189
  if (cellIndex === 1) {
176
190
  return $cell.attr('data-score') || s;
177
- }
191
+ }
178
192
  return s;
179
193
  },
180
194
  parsed: false,
@@ -187,29 +201,10 @@ function initTableSorter() {
187
201
  },
188
202
  sortList: [[0,0]],
189
203
  });
190
- }
191
-
192
- // Remove empty colums that are not used for that type of input data...
193
- function removeEmptyColumns() {
194
- 'use strict';
195
- $('#sortable_table tr th').each(function(i) {
196
- var tds = $(this).parents('table') // Select all tds in column
197
- .find('tr td:nth-child(' + (i + 1) + ')');
198
- // Check if all cells in the column are empty
199
- if ($(this).hasClass( 'chart-column' )) {
200
- } else {
201
- if ($(this).text().trim() == '') {
202
- //hide header
203
- $(this).hide();
204
- //hide cells
205
- tds.hide();
206
- }
207
- }
208
- });
209
- }
204
+ };
210
205
 
211
206
  // Function is called each time the Adv. Params button is pressed...
212
- function changeAdvParamsBtnText() {
207
+ var changeAdvParamsBtnText = function () {
213
208
  'use strict';
214
209
  var btn = document.getElementById('adv_params_btn');
215
210
  if (btn.innerHTML === '<i class="fa fa-pencil-square-o"></i>&nbsp;&nbsp;Show Advanced Parameters') {
@@ -222,10 +217,10 @@ function changeAdvParamsBtnText() {
222
217
  $('#adv_params').collapse('hide');
223
218
  $.cookie('GeneValidator_adv_params_status', 'closed');
224
219
  }
225
- }
220
+ };
226
221
 
227
222
  // Changes the input to an examplar dna or protein sequence...
228
- function examplarSequence(type){
223
+ var examplarSequence = function (type){
229
224
  'use strict';
230
225
  var dna = '>Insulin\n' +
231
226
  'ATGGCTCTCTGGATCCGGTCGCTGCCTCTCCTGGCCCTTCTTGCTCTTTCTGGCCCTGGGATCAGCCACGCAGCTGCCAACCAGCACCTCTGTGGCTCCCACTTGGTTGAGGCTCTCTACCTGGTGTGTGGGGAGCGGGGTTTCTTCTACTCCCCCAAAACACGGCGGGACGTTGAGCAGCCTCTAGTGAACGGTCCCCTGCATGGCGAGGTGGGAGAGCTGCCGTTCCAGCATGAGGAATACCAGAAAGTCAAGCGAGGCATCGTTGAGCAATGCTGTGAAAACCCGTGCTCCCTCTACCAACTGGAAAACTACTGCAACTAG\n' +
@@ -241,11 +236,11 @@ function examplarSequence(type){
241
236
  } else if (type === 'protein') {
242
237
  document.getElementById('seq').value = protein;
243
238
  }
244
- }
239
+ };
245
240
 
246
241
  // FROM BIONODE-Seq - See https://github.com/bionode/bionode-seq
247
242
  // Checks whether a sequence is a protein or dna sequence...
248
- function checkType(sequence, threshold, length, index) {
243
+ var checkType = function (sequence, threshold, length, index) {
249
244
  'use strict';
250
245
  if (threshold === undefined) {
251
246
  threshold = 0.9;
@@ -263,7 +258,7 @@ function checkType(sequence, threshold, length, index) {
263
258
  var acgMatch = ((dnaSeq.match(/[ACG]/gi) || []).length) / dnaTotal;
264
259
  var tMatch = ((dnaSeq.match(/[T]/gi) || []).length) / dnaTotal;
265
260
  var uMatch = ((dnaSeq.match(/[U]/gi) || []).length) / dnaTotal;
266
-
261
+
267
262
  var proteinSeq = seq.replace(/X/gi,'');
268
263
  var proteinTotal = proteinSeq.length;
269
264
  var proteinMatch = ((seq.match(/[ARNDCQEGHILKMFPSTWYV\*]/gi) || []).length) / proteinTotal;
@@ -279,4 +274,4 @@ function checkType(sequence, threshold, length, index) {
279
274
  } else if (proteinMatch >= threshold) {
280
275
  return 'protein';
281
276
  }
282
- }
277
+ };