genevalidatorapp 1.4.13 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
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
+ };