sequenceserver 1.0.0.pre.2 → 1.0.0.pre.3
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.
- checksums.yaml +4 -4
- data/Gemfile +1 -1
- data/README.md +18 -4
- data/bin/sequenceserver +219 -124
- data/lib/sequenceserver.rb +156 -153
- data/lib/sequenceserver/blast.rb +163 -432
- data/lib/sequenceserver/blast/exceptions.rb +27 -0
- data/lib/sequenceserver/blast/hit.rb +32 -0
- data/lib/sequenceserver/blast/hsp.rb +260 -0
- data/lib/sequenceserver/blast/query.rb +28 -0
- data/lib/sequenceserver/blast/report.rb +123 -0
- data/lib/sequenceserver/config.rb +94 -0
- data/lib/sequenceserver/database.rb +89 -49
- data/lib/sequenceserver/exceptions.rb +154 -0
- data/lib/sequenceserver/links.rb +1 -1
- data/lib/sequenceserver/logger.rb +5 -7
- data/lib/sequenceserver/sequence.rb +40 -39
- data/public/css/bootstrap.min.css +5 -7
- data/public/css/custom.css +28 -27
- data/public/dist/css/sequenceserver.min.css +1 -0
- data/public/dist/css/sequenceserver.min.css.gz +0 -0
- data/public/dist/fonts/FontAwesome.otf +0 -0
- data/public/dist/fonts/fontawesome-webfont.eot +0 -0
- data/public/dist/fonts/fontawesome-webfont.svg +565 -0
- data/public/dist/fonts/fontawesome-webfont.ttf +0 -0
- data/public/dist/fonts/fontawesome-webfont.woff +0 -0
- data/public/dist/fonts/fontawesome-webfont.woff2 +0 -0
- data/public/dist/js/sequenceserver.min.js +12 -0
- data/public/dist/js/sequenceserver.min.js.gz +0 -0
- data/public/dist/js/shims/FlashCanvas/canvas2png.js +1 -0
- data/public/dist/js/shims/FlashCanvas/flashcanvas.js +1 -0
- data/public/dist/js/shims/FlashCanvas/flashcanvas.swf +0 -0
- data/public/dist/js/shims/FlashCanvasPro/canvas2png.js +1 -0
- data/public/dist/js/shims/FlashCanvasPro/flash10canvas.swf +0 -0
- data/public/dist/js/shims/FlashCanvasPro/flash9canvas.swf +0 -0
- data/public/dist/js/shims/FlashCanvasPro/flashcanvas.js +1 -0
- data/public/dist/js/shims/canvas-blob.js +1 -0
- data/public/dist/js/shims/color-picker.js +2 -0
- data/public/dist/js/shims/combos/1.js +6 -0
- data/public/dist/js/shims/combos/10.js +2 -0
- data/public/dist/js/shims/combos/11.js +2 -0
- data/public/dist/js/shims/combos/12.js +6 -0
- data/public/dist/js/shims/combos/13.js +1 -0
- data/public/dist/js/shims/combos/14.js +1 -0
- data/public/dist/js/shims/combos/15.js +2 -0
- data/public/dist/js/shims/combos/16.js +7 -0
- data/public/dist/js/shims/combos/17.js +2 -0
- data/public/dist/js/shims/combos/18.js +3 -0
- data/public/dist/js/shims/combos/2.js +7 -0
- data/public/dist/js/shims/combos/21.js +2 -0
- data/public/dist/js/shims/combos/22.js +1 -0
- data/public/dist/js/shims/combos/23.js +6 -0
- data/public/dist/js/shims/combos/25.js +2 -0
- data/public/dist/js/shims/combos/27.js +1 -0
- data/public/dist/js/shims/combos/28.js +1 -0
- data/public/dist/js/shims/combos/29.js +1 -0
- data/public/dist/js/shims/combos/3.js +1 -0
- data/public/dist/js/shims/combos/30.js +2 -0
- data/public/dist/js/shims/combos/31.js +1 -0
- data/public/dist/js/shims/combos/33.js +1 -0
- data/public/dist/js/shims/combos/34.js +1 -0
- data/public/dist/js/shims/combos/4.js +1 -0
- data/public/dist/js/shims/combos/5.js +2 -0
- data/public/dist/js/shims/combos/6.js +2 -0
- data/public/dist/js/shims/combos/7.js +7 -0
- data/public/dist/js/shims/combos/8.js +7 -0
- data/public/dist/js/shims/combos/9.js +2 -0
- data/public/dist/js/shims/combos/97.js +1 -0
- data/public/dist/js/shims/combos/98.js +1 -0
- data/public/dist/js/shims/combos/99.js +1 -0
- data/public/dist/js/shims/details.js +1 -0
- data/public/dist/js/shims/dom-extend.js +1 -0
- data/public/dist/js/shims/es5.js +1 -0
- data/public/dist/js/shims/es6.js +1 -0
- data/public/dist/js/shims/excanvas.js +1 -0
- data/public/dist/js/shims/filereader-xhr.js +1 -0
- data/public/dist/js/shims/form-combat.js +1 -0
- data/public/dist/js/shims/form-core.js +1 -0
- data/public/dist/js/shims/form-datalist-lazy.js +1 -0
- data/public/dist/js/shims/form-datalist.js +1 -0
- data/public/dist/js/shims/form-fixrangechange.js +1 -0
- data/public/dist/js/shims/form-inputmode.js +1 -0
- data/public/dist/js/shims/form-message.js +1 -0
- data/public/dist/js/shims/form-native-extend.js +1 -0
- data/public/dist/js/shims/form-number-date-api.js +1 -0
- data/public/dist/js/shims/form-number-date-ui.js +1 -0
- data/public/dist/js/shims/form-shim-extend.js +1 -0
- data/public/dist/js/shims/form-shim-extend2.js +1 -0
- data/public/dist/js/shims/form-validation.js +1 -0
- data/public/dist/js/shims/form-validators.js +1 -0
- data/public/dist/js/shims/forms-picker.js +1 -0
- data/public/dist/js/shims/geolocation.js +1 -0
- data/public/dist/js/shims/i18n/formcfg-ar.js +1 -0
- data/public/dist/js/shims/i18n/formcfg-ch-CN.js +1 -0
- data/public/dist/js/shims/i18n/formcfg-cs.js +1 -0
- data/public/dist/js/shims/i18n/formcfg-de.js +1 -0
- data/public/dist/js/shims/i18n/formcfg-el.js +1 -0
- data/public/dist/js/shims/i18n/formcfg-en.js +1 -0
- data/public/dist/js/shims/i18n/formcfg-es.js +1 -0
- data/public/dist/js/shims/i18n/formcfg-fa.js +1 -0
- data/public/dist/js/shims/i18n/formcfg-fr.js +1 -0
- data/public/dist/js/shims/i18n/formcfg-he.js +1 -0
- data/public/dist/js/shims/i18n/formcfg-hi.js +1 -0
- data/public/dist/js/shims/i18n/formcfg-hu.js +1 -0
- data/public/dist/js/shims/i18n/formcfg-it.js +1 -0
- data/public/dist/js/shims/i18n/formcfg-ja.js +1 -0
- data/public/dist/js/shims/i18n/formcfg-lt.js +1 -0
- data/public/dist/js/shims/i18n/formcfg-nl.js +1 -0
- data/public/dist/js/shims/i18n/formcfg-pl.js +1 -0
- data/public/dist/js/shims/i18n/formcfg-pt-BR.js +1 -0
- data/public/dist/js/shims/i18n/formcfg-pt-PT.js +1 -0
- data/public/dist/js/shims/i18n/formcfg-pt.js +1 -0
- data/public/dist/js/shims/i18n/formcfg-ru.js +1 -0
- data/public/dist/js/shims/i18n/formcfg-sv.js +1 -0
- data/public/dist/js/shims/i18n/formcfg-zh-CN.js +1 -0
- data/public/dist/js/shims/i18n/formcfg-zh-TW.js +1 -0
- data/public/dist/js/shims/jme/alternate-media.js +1 -0
- data/public/dist/js/shims/jme/base.js +1 -0
- data/public/dist/js/shims/jme/controls.css +1 -0
- data/public/dist/js/shims/jme/jme.eot +0 -0
- data/public/dist/js/shims/jme/jme.svg +36 -0
- data/public/dist/js/shims/jme/jme.ttf +0 -0
- data/public/dist/js/shims/jme/jme.woff +0 -0
- data/public/dist/js/shims/jme/mediacontrols-lazy.js +1 -0
- data/public/dist/js/shims/jme/mediacontrols.js +1 -0
- data/public/dist/js/shims/jme/playlist.js +1 -0
- data/public/dist/js/shims/jpicker/images/AlphaBar.png +0 -0
- data/public/dist/js/shims/jpicker/images/Bars.png +0 -0
- data/public/dist/js/shims/jpicker/images/Maps.png +0 -0
- data/public/dist/js/shims/jpicker/images/NoColor.png +0 -0
- data/public/dist/js/shims/jpicker/images/bar-opacity.png +0 -0
- data/public/dist/js/shims/jpicker/images/map-opacity.png +0 -0
- data/public/dist/js/shims/jpicker/images/mappoint.gif +0 -0
- data/public/dist/js/shims/jpicker/images/picker.gif +0 -0
- data/public/dist/js/shims/jpicker/images/preview-opacity.png +0 -0
- data/public/dist/js/shims/jpicker/images/rangearrows.gif +0 -0
- data/public/dist/js/shims/jpicker/jpicker.css +1 -0
- data/public/dist/js/shims/matchMedia.js +3 -0
- data/public/dist/js/shims/mediacapture-picker.js +1 -0
- data/public/dist/js/shims/mediacapture.js +1 -0
- data/public/dist/js/shims/mediaelement-core.js +1 -0
- data/public/dist/js/shims/mediaelement-debug.js +1 -0
- data/public/dist/js/shims/mediaelement-jaris.js +1 -0
- data/public/dist/js/shims/mediaelement-native-fix.js +1 -0
- data/public/dist/js/shims/mediaelement-yt.js +1 -0
- data/public/dist/js/shims/moxie/flash/Moxie.cdn.swf +0 -0
- data/public/dist/js/shims/moxie/flash/Moxie.min.swf +0 -0
- data/public/dist/js/shims/moxie/js/moxie-html4.js +3 -0
- data/public/dist/js/shims/moxie/js/moxie-swf.js +2 -0
- data/public/dist/js/shims/picture.js +1 -0
- data/public/dist/js/shims/plugins/jquery.ui.position.js +11 -0
- data/public/dist/js/shims/range-ui.js +1 -0
- data/public/dist/js/shims/sizzle.js +11 -0
- data/public/dist/js/shims/sticky.js +1 -0
- data/public/dist/js/shims/styles/color-picker.png +0 -0
- data/public/dist/js/shims/styles/forms-ext.css +1 -0
- data/public/dist/js/shims/styles/forms-picker.css +1 -0
- data/public/dist/js/shims/styles/progress.gif +0 -0
- data/public/dist/js/shims/styles/progress.png +0 -0
- data/public/dist/js/shims/styles/shim-ext.css +1 -0
- data/public/dist/js/shims/styles/shim.css +1 -0
- data/public/dist/js/shims/styles/transparent.png +0 -0
- data/public/dist/js/shims/styles/widget.eot +0 -0
- data/public/dist/js/shims/styles/widget.svg +12 -0
- data/public/dist/js/shims/styles/widget.ttf +0 -0
- data/public/dist/js/shims/styles/widget.woff +0 -0
- data/public/dist/js/shims/swf/JarisFLVPlayer.swf +0 -0
- data/public/dist/js/shims/swfmini-embed.js +1 -0
- data/public/dist/js/shims/swfmini.js +6 -0
- data/public/dist/js/shims/track-ui.js +1 -0
- data/public/dist/js/shims/track.js +1 -0
- data/public/dist/js/shims/url.js +1 -0
- data/public/dist/js/shims/usermedia-core.js +1 -0
- data/public/dist/js/shims/usermedia-shim.js +1 -0
- data/public/dist/js/webshims/shims/FlashCanvas/canvas2png.js +1 -0
- data/public/dist/js/webshims/shims/FlashCanvas/flashcanvas.js +1 -0
- data/public/dist/js/webshims/shims/FlashCanvas/flashcanvas.swf +0 -0
- data/public/dist/js/webshims/shims/FlashCanvasPro/canvas2png.js +1 -0
- data/public/dist/js/webshims/shims/FlashCanvasPro/flash10canvas.swf +0 -0
- data/public/dist/js/webshims/shims/FlashCanvasPro/flash9canvas.swf +0 -0
- data/public/dist/js/webshims/shims/FlashCanvasPro/flashcanvas.js +1 -0
- data/public/dist/js/webshims/shims/canvas-blob.js +1 -0
- data/public/dist/js/webshims/shims/color-picker.js +2 -0
- data/public/dist/js/webshims/shims/combos/1.js +6 -0
- data/public/dist/js/webshims/shims/combos/10.js +2 -0
- data/public/dist/js/webshims/shims/combos/11.js +2 -0
- data/public/dist/js/webshims/shims/combos/12.js +6 -0
- data/public/dist/js/webshims/shims/combos/13.js +1 -0
- data/public/dist/js/webshims/shims/combos/14.js +1 -0
- data/public/dist/js/webshims/shims/combos/15.js +2 -0
- data/public/dist/js/webshims/shims/combos/16.js +7 -0
- data/public/dist/js/webshims/shims/combos/17.js +2 -0
- data/public/dist/js/webshims/shims/combos/18.js +3 -0
- data/public/dist/js/webshims/shims/combos/2.js +7 -0
- data/public/dist/js/webshims/shims/combos/21.js +2 -0
- data/public/dist/js/webshims/shims/combos/22.js +1 -0
- data/public/dist/js/webshims/shims/combos/23.js +6 -0
- data/public/dist/js/webshims/shims/combos/25.js +2 -0
- data/public/dist/js/webshims/shims/combos/27.js +1 -0
- data/public/dist/js/webshims/shims/combos/28.js +1 -0
- data/public/dist/js/webshims/shims/combos/29.js +1 -0
- data/public/dist/js/webshims/shims/combos/3.js +1 -0
- data/public/dist/js/webshims/shims/combos/30.js +2 -0
- data/public/dist/js/webshims/shims/combos/31.js +1 -0
- data/public/dist/js/webshims/shims/combos/33.js +1 -0
- data/public/dist/js/webshims/shims/combos/34.js +1 -0
- data/public/dist/js/webshims/shims/combos/4.js +1 -0
- data/public/dist/js/webshims/shims/combos/5.js +2 -0
- data/public/dist/js/webshims/shims/combos/6.js +2 -0
- data/public/dist/js/webshims/shims/combos/7.js +7 -0
- data/public/dist/js/webshims/shims/combos/8.js +7 -0
- data/public/dist/js/webshims/shims/combos/9.js +2 -0
- data/public/dist/js/webshims/shims/combos/97.js +1 -0
- data/public/dist/js/webshims/shims/combos/98.js +1 -0
- data/public/dist/js/webshims/shims/combos/99.js +1 -0
- data/public/dist/js/webshims/shims/details.js +1 -0
- data/public/dist/js/webshims/shims/dom-extend.js +1 -0
- data/public/dist/js/webshims/shims/es5.js +1 -0
- data/public/dist/js/webshims/shims/es6.js +1 -0
- data/public/dist/js/webshims/shims/excanvas.js +1 -0
- data/public/dist/js/webshims/shims/filereader-xhr.js +1 -0
- data/public/dist/js/webshims/shims/form-combat.js +1 -0
- data/public/dist/js/webshims/shims/form-core.js +1 -0
- data/public/dist/js/webshims/shims/form-datalist-lazy.js +1 -0
- data/public/dist/js/webshims/shims/form-datalist.js +1 -0
- data/public/dist/js/webshims/shims/form-fixrangechange.js +1 -0
- data/public/dist/js/webshims/shims/form-inputmode.js +1 -0
- data/public/dist/js/webshims/shims/form-message.js +1 -0
- data/public/dist/js/webshims/shims/form-native-extend.js +1 -0
- data/public/dist/js/webshims/shims/form-number-date-api.js +1 -0
- data/public/dist/js/webshims/shims/form-number-date-ui.js +1 -0
- data/public/dist/js/webshims/shims/form-shim-extend.js +1 -0
- data/public/dist/js/webshims/shims/form-shim-extend2.js +1 -0
- data/public/dist/js/webshims/shims/form-validation.js +1 -0
- data/public/dist/js/webshims/shims/form-validators.js +1 -0
- data/public/dist/js/webshims/shims/forms-picker.js +1 -0
- data/public/dist/js/webshims/shims/geolocation.js +1 -0
- data/public/dist/js/webshims/shims/i18n/formcfg-ar.js +1 -0
- data/public/dist/js/webshims/shims/i18n/formcfg-ch-CN.js +1 -0
- data/public/dist/js/webshims/shims/i18n/formcfg-cs.js +1 -0
- data/public/dist/js/webshims/shims/i18n/formcfg-de.js +1 -0
- data/public/dist/js/webshims/shims/i18n/formcfg-el.js +1 -0
- data/public/dist/js/webshims/shims/i18n/formcfg-en.js +1 -0
- data/public/dist/js/webshims/shims/i18n/formcfg-es.js +1 -0
- data/public/dist/js/webshims/shims/i18n/formcfg-fa.js +1 -0
- data/public/dist/js/webshims/shims/i18n/formcfg-fr.js +1 -0
- data/public/dist/js/webshims/shims/i18n/formcfg-he.js +1 -0
- data/public/dist/js/webshims/shims/i18n/formcfg-hi.js +1 -0
- data/public/dist/js/webshims/shims/i18n/formcfg-hu.js +1 -0
- data/public/dist/js/webshims/shims/i18n/formcfg-it.js +1 -0
- data/public/dist/js/webshims/shims/i18n/formcfg-ja.js +1 -0
- data/public/dist/js/webshims/shims/i18n/formcfg-lt.js +1 -0
- data/public/dist/js/webshims/shims/i18n/formcfg-nl.js +1 -0
- data/public/dist/js/webshims/shims/i18n/formcfg-pl.js +1 -0
- data/public/dist/js/webshims/shims/i18n/formcfg-pt-BR.js +1 -0
- data/public/dist/js/webshims/shims/i18n/formcfg-pt-PT.js +1 -0
- data/public/dist/js/webshims/shims/i18n/formcfg-pt.js +1 -0
- data/public/dist/js/webshims/shims/i18n/formcfg-ru.js +1 -0
- data/public/dist/js/webshims/shims/i18n/formcfg-sv.js +1 -0
- data/public/dist/js/webshims/shims/i18n/formcfg-zh-CN.js +1 -0
- data/public/dist/js/webshims/shims/i18n/formcfg-zh-TW.js +1 -0
- data/public/dist/js/webshims/shims/jme/alternate-media.js +1 -0
- data/public/dist/js/webshims/shims/jme/base.js +1 -0
- data/public/dist/js/webshims/shims/jme/controls.css +1 -0
- data/public/dist/js/webshims/shims/jme/jme.eot +0 -0
- data/public/dist/js/webshims/shims/jme/jme.svg +36 -0
- data/public/dist/js/webshims/shims/jme/jme.ttf +0 -0
- data/public/dist/js/webshims/shims/jme/jme.woff +0 -0
- data/public/dist/js/webshims/shims/jme/mediacontrols-lazy.js +1 -0
- data/public/dist/js/webshims/shims/jme/mediacontrols.js +1 -0
- data/public/dist/js/webshims/shims/jme/playlist.js +1 -0
- data/public/dist/js/webshims/shims/jpicker/images/AlphaBar.png +0 -0
- data/public/dist/js/webshims/shims/jpicker/images/Bars.png +0 -0
- data/public/dist/js/webshims/shims/jpicker/images/Maps.png +0 -0
- data/public/dist/js/webshims/shims/jpicker/images/NoColor.png +0 -0
- data/public/dist/js/webshims/shims/jpicker/images/bar-opacity.png +0 -0
- data/public/dist/js/webshims/shims/jpicker/images/map-opacity.png +0 -0
- data/public/dist/js/webshims/shims/jpicker/images/mappoint.gif +0 -0
- data/public/dist/js/webshims/shims/jpicker/images/picker.gif +0 -0
- data/public/dist/js/webshims/shims/jpicker/images/preview-opacity.png +0 -0
- data/public/dist/js/webshims/shims/jpicker/images/rangearrows.gif +0 -0
- data/public/dist/js/webshims/shims/jpicker/jpicker.css +1 -0
- data/public/dist/js/webshims/shims/matchMedia.js +3 -0
- data/public/dist/js/webshims/shims/mediacapture-picker.js +1 -0
- data/public/dist/js/webshims/shims/mediacapture.js +1 -0
- data/public/dist/js/webshims/shims/mediaelement-core.js +1 -0
- data/public/dist/js/webshims/shims/mediaelement-debug.js +1 -0
- data/public/dist/js/webshims/shims/mediaelement-jaris.js +1 -0
- data/public/dist/js/webshims/shims/mediaelement-native-fix.js +1 -0
- data/public/dist/js/webshims/shims/mediaelement-yt.js +1 -0
- data/public/dist/js/webshims/shims/moxie/flash/Moxie.cdn.swf +0 -0
- data/public/dist/js/webshims/shims/moxie/flash/Moxie.min.swf +0 -0
- data/public/dist/js/webshims/shims/moxie/js/moxie-html4.js +3 -0
- data/public/dist/js/webshims/shims/moxie/js/moxie-swf.js +2 -0
- data/public/dist/js/webshims/shims/picture.js +1 -0
- data/public/dist/js/webshims/shims/plugins/jquery.ui.position.js +11 -0
- data/public/dist/js/webshims/shims/range-ui.js +1 -0
- data/public/dist/js/webshims/shims/sizzle.js +11 -0
- data/public/dist/js/webshims/shims/sticky.js +1 -0
- data/public/dist/js/webshims/shims/styles/color-picker.png +0 -0
- data/public/dist/js/webshims/shims/styles/forms-ext.css +1 -0
- data/public/dist/js/webshims/shims/styles/forms-picker.css +1 -0
- data/public/dist/js/webshims/shims/styles/progress.gif +0 -0
- data/public/dist/js/webshims/shims/styles/progress.png +0 -0
- data/public/dist/js/webshims/shims/styles/shim-ext.css +1 -0
- data/public/dist/js/webshims/shims/styles/shim.css +1 -0
- data/public/dist/js/webshims/shims/styles/transparent.png +0 -0
- data/public/dist/js/webshims/shims/styles/widget.eot +0 -0
- data/public/dist/js/webshims/shims/styles/widget.svg +12 -0
- data/public/dist/js/webshims/shims/styles/widget.ttf +0 -0
- data/public/dist/js/webshims/shims/styles/widget.woff +0 -0
- data/public/dist/js/webshims/shims/swf/JarisFLVPlayer.swf +0 -0
- data/public/dist/js/webshims/shims/swfmini-embed.js +1 -0
- data/public/dist/js/webshims/shims/swfmini.js +6 -0
- data/public/dist/js/webshims/shims/track-ui.js +1 -0
- data/public/dist/js/webshims/shims/track.js +1 -0
- data/public/dist/js/webshims/shims/url.js +1 -0
- data/public/dist/js/webshims/shims/usermedia-core.js +1 -0
- data/public/dist/js/webshims/shims/usermedia-shim.js +1 -0
- data/public/js/bootstrap.min.js +3 -8
- data/public/js/jquery-ui.min.js +6 -0
- data/public/js/jquery.min.js +4 -0
- data/public/js/jquery.t.js +4 -4
- data/public/js/sequenceserver.blast.js +20 -18
- data/public/js/sequenceserver.js +116 -74
- data/sequenceserver.gemspec +20 -16
- data/views/400.erb +2 -1
- data/views/500.erb +6 -1
- data/views/result.erb +38 -18
- data/views/search.erb +49 -32
- metadata +389 -11
- data/public/img/glyphicons-halflings-white.png +0 -0
- data/public/img/glyphicons-halflings.png +0 -0
- data/public/js/jquery-ui.js +0 -14987
- data/public/js/jquery.js +0 -5
- data/public/js/jquery.scrollspy.js +0 -74
- data/public/sequence.min.js +0 -1
data/lib/sequenceserver.rb
CHANGED
@@ -1,27 +1,22 @@
|
|
1
1
|
require 'yaml'
|
2
|
+
require 'English'
|
2
3
|
require 'fileutils'
|
3
4
|
require 'sinatra/base'
|
4
5
|
require 'thin'
|
5
6
|
require 'json'
|
6
7
|
|
8
|
+
require 'sequenceserver/exceptions'
|
9
|
+
require 'sequenceserver/config'
|
7
10
|
require 'sequenceserver/logger'
|
8
11
|
require 'sequenceserver/sequence'
|
9
12
|
require 'sequenceserver/database'
|
10
13
|
require 'sequenceserver/blast'
|
11
14
|
|
15
|
+
# Top level module / namespace.
|
12
16
|
module SequenceServer
|
13
|
-
|
14
17
|
# Use a fixed minimum version of BLAST+
|
15
18
|
MINIMUM_BLAST_VERSION = '2.2.30+'
|
16
19
|
|
17
|
-
# Use the following exit codes, or 1.
|
18
|
-
EXIT_BLAST_NOT_INSTALLED = 2
|
19
|
-
EXIT_BLAST_NOT_COMPATIBLE = 3
|
20
|
-
EXIT_NO_BLAST_DATABASE = 4
|
21
|
-
EXIT_BLAST_INSTALLATION_FAILED = 5
|
22
|
-
EXIT_CONFIG_FILE_NOT_FOUND = 6
|
23
|
-
EXIT_NO_SEQUENCE_DIR = 7
|
24
|
-
|
25
20
|
class << self
|
26
21
|
def environment
|
27
22
|
ENV['RACK_ENV']
|
@@ -40,80 +35,53 @@ module SequenceServer
|
|
40
35
|
end
|
41
36
|
|
42
37
|
def init(config = {})
|
43
|
-
@
|
44
|
-
@config_file = File.expand_path(config_file)
|
45
|
-
assert_file_present('config file', config_file, EXIT_CONFIG_FILE_NOT_FOUND)
|
46
|
-
|
47
|
-
@config = {
|
48
|
-
:num_threads => 1,
|
49
|
-
:port => 4567,
|
50
|
-
:host => 'localhost'
|
51
|
-
}.update(parse_config_file.merge(config))
|
52
|
-
|
53
|
-
if @config[:bin]
|
54
|
-
@config[:bin] = File.expand_path @config[:bin]
|
55
|
-
assert_dir_present 'bin dir', @config[:bin]
|
56
|
-
export_bin_dir
|
57
|
-
end
|
58
|
-
|
59
|
-
assert_blast_installed_and_compatible
|
60
|
-
|
61
|
-
assert_dir_present 'database dir', @config[:database_dir], EXIT_NO_SEQUENCE_DIR
|
62
|
-
@config[:database_dir] = File.expand_path(@config[:database_dir])
|
63
|
-
assert_blast_databases_present_in_database_dir
|
38
|
+
@config = Config.new(config)
|
64
39
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
if @config[:require]
|
72
|
-
@config[:require] = File.expand_path @config[:require]
|
73
|
-
assert_file_present 'extension file', @config[:require]
|
74
|
-
require @config[:require]
|
75
|
-
end
|
40
|
+
init_binaries
|
41
|
+
init_database
|
42
|
+
load_extension
|
43
|
+
check_num_threads
|
44
|
+
self
|
76
45
|
|
77
46
|
# We don't validate port and host settings. If SequenceServer is run
|
78
47
|
# self-hosted, bind will fail on incorrect values. If SequenceServer
|
79
48
|
# is run via Apache+Passenger, we don't need to worry.
|
80
|
-
|
81
|
-
self
|
82
49
|
end
|
83
50
|
|
84
|
-
attr_reader :
|
85
|
-
|
86
|
-
def [](key)
|
87
|
-
config[key]
|
88
|
-
end
|
51
|
+
attr_reader :config
|
89
52
|
|
90
53
|
# Run SequenceServer as a self-hosted server using Thin webserver.
|
91
54
|
def run
|
55
|
+
check_host
|
92
56
|
url = "http://#{config[:host]}:#{config[:port]}"
|
93
|
-
server = Thin::Server.new(config[:host],
|
57
|
+
server = Thin::Server.new(config[:host],
|
58
|
+
config[:port],
|
59
|
+
:signals => false) do
|
94
60
|
use Rack::CommonLogger
|
95
61
|
run SequenceServer
|
96
62
|
end
|
97
63
|
server.silent = true
|
98
64
|
server.backend.start do
|
99
|
-
puts
|
65
|
+
puts '** SequenceServer is ready.'
|
100
66
|
puts " Go to #{url} in your browser and start BLASTing!"
|
101
|
-
puts
|
67
|
+
puts ' Press CTRL+C to quit.'
|
102
68
|
[:INT, :TERM].each do |sig|
|
103
69
|
trap sig do
|
104
70
|
server.stop!
|
105
71
|
puts
|
106
|
-
puts
|
107
|
-
puts
|
108
|
-
puts
|
109
|
-
puts
|
72
|
+
puts '** Thank you for using SequenceServer :).'
|
73
|
+
puts ' Please cite: '
|
74
|
+
puts ' Priyam, Woodcroft, Rai & Wurm,'
|
75
|
+
puts ' SequenceServer (in prep).'
|
110
76
|
end
|
111
77
|
end
|
112
78
|
end
|
113
79
|
rescue
|
114
|
-
puts
|
80
|
+
puts '** Oops! There was an error.'
|
115
81
|
puts " Is SequenceServer already accessible at #{url}?"
|
116
|
-
puts
|
82
|
+
puts ' Try running SequenceServer on another port, like so:'
|
83
|
+
puts
|
84
|
+
puts ' sequenceserver -p 4570.'
|
117
85
|
end
|
118
86
|
|
119
87
|
# Rack-interface.
|
@@ -137,105 +105,105 @@ module SequenceServer
|
|
137
105
|
|
138
106
|
private
|
139
107
|
|
140
|
-
def
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
puts "*** Error in config file: #{error}."
|
154
|
-
puts " YAML is white space sensitive. Is your config file properly indented?"
|
155
|
-
exit 1
|
108
|
+
def init_binaries
|
109
|
+
if config[:bin]
|
110
|
+
config[:bin] = File.expand_path config[:bin]
|
111
|
+
unless File.exist?(config[:bin]) && File.directory?(config[:bin])
|
112
|
+
fail BIN_DIR_NOT_FOUND, config[:bin]
|
113
|
+
end
|
114
|
+
logger.debug("Will use NCBI BLAST+ at: #{config[:bin]}")
|
115
|
+
export_bin_dir
|
116
|
+
else
|
117
|
+
logger.debug('Will use NCBI BLAST+ at: $PATH')
|
118
|
+
end
|
119
|
+
|
120
|
+
assert_blast_installed_and_compatible
|
156
121
|
end
|
157
122
|
|
158
|
-
def
|
159
|
-
|
160
|
-
|
123
|
+
def init_database
|
124
|
+
fail DATABASE_DIR_NOT_SET unless config[:database_dir]
|
125
|
+
|
126
|
+
config[:database_dir] = File.expand_path(config[:database_dir])
|
127
|
+
unless File.exist?(config[:database_dir]) &&
|
128
|
+
File.directory?(config[:database_dir])
|
129
|
+
fail DATABASE_DIR_NOT_FOUND, config[:database_dir]
|
130
|
+
end
|
131
|
+
|
132
|
+
assert_blast_databases_present_in_database_dir
|
133
|
+
logger.debug("Will use BLAST+ databases at: #{config[:database_dir]}")
|
134
|
+
|
135
|
+
Database.scan_databases_dir
|
136
|
+
Database.each do |database|
|
137
|
+
logger.debug("Found #{database.type} database '#{database.title}'" \
|
138
|
+
" at '#{database.name}'")
|
161
139
|
end
|
162
140
|
end
|
163
141
|
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
142
|
+
def check_num_threads
|
143
|
+
num_threads = Integer(config[:num_threads])
|
144
|
+
fail NUM_THREADS_INCORRECT unless num_threads > 0
|
145
|
+
|
146
|
+
logger.debug "Will use #{num_threads} threads to run BLAST."
|
147
|
+
if num_threads > 256
|
148
|
+
logger.warn "Number of threads set at #{num_threads} is unusually high."
|
171
149
|
end
|
150
|
+
rescue
|
151
|
+
raise NUM_THREADS_INCORRECT
|
172
152
|
end
|
173
153
|
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
154
|
+
# Check and warn user if host is 0.0.0.0 (default).
|
155
|
+
def check_host
|
156
|
+
# rubocop:disable Style/GuardClause
|
157
|
+
if config[:host] == '0.0.0.0'
|
158
|
+
logger.warn 'Will listen on all interfaces (0.0.0.0).' \
|
159
|
+
' Consider using 127.0.0.1 (--host option).'
|
178
160
|
end
|
161
|
+
# rubocop:enable Style/GuardClause
|
179
162
|
end
|
180
163
|
|
181
|
-
|
164
|
+
def load_extension
|
165
|
+
return unless config[:require]
|
182
166
|
|
183
|
-
|
184
|
-
unless
|
185
|
-
|
186
|
-
exit EXIT_BLAST_NOT_INSTALLED
|
187
|
-
end
|
188
|
-
version = %x|blastdbcmd -version|.split[1]
|
189
|
-
unless version >= MINIMUM_BLAST_VERSION
|
190
|
-
puts "*** Your BLAST+ version #{version} is outdated."
|
191
|
-
puts " SequenceServer needs NCBI BLAST+ version #{MINIMUM_BLAST_VERSION} or higher."
|
192
|
-
exit EXIT_BLAST_NOT_COMPATIBLE
|
167
|
+
config[:require] = File.expand_path config[:require]
|
168
|
+
unless File.exist?(config[:require]) && File.file?(config[:require])
|
169
|
+
fail EXTENSION_FILE_NOT_FOUND, config[:require]
|
193
170
|
end
|
171
|
+
|
172
|
+
logger.debug("Loading extension: #{config[:require]}")
|
173
|
+
require config[:require]
|
194
174
|
end
|
195
175
|
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
elsif out.match(/BLAST Database error/) or not $?.success?
|
203
|
-
puts "*** Error obtaining BLAST databases."
|
204
|
-
puts " Tried: #{find_dbs_command}"
|
205
|
-
puts " Error:"
|
206
|
-
out.strip.split("\n").each do |l|
|
207
|
-
puts " #{l}"
|
208
|
-
end
|
209
|
-
puts " Please could you report this to 'https://groups.google.com/forum/#!forum/sequenceserver'?"
|
210
|
-
exit EXIT_BLAST_DATABASE_ERROR
|
211
|
-
end
|
176
|
+
# Export NCBI BLAST+ bin dir to PATH environment variable.
|
177
|
+
def export_bin_dir
|
178
|
+
bin_dir = config[:bin]
|
179
|
+
return unless bin_dir
|
180
|
+
return if ENV['PATH'].split(':').include? bin_dir
|
181
|
+
ENV['PATH'] = "#{bin_dir}:#{ENV['PATH']}"
|
212
182
|
end
|
213
183
|
|
214
|
-
def
|
215
|
-
unless
|
216
|
-
|
217
|
-
|
218
|
-
exit 1
|
219
|
-
end
|
220
|
-
if num_threads > 256
|
221
|
-
logger.warn "*** Number of threads set at #{num_threads} is unusually high."
|
222
|
-
end
|
223
|
-
rescue
|
224
|
-
puts "*** Number of threads should be a number."
|
225
|
-
exit 1
|
184
|
+
def assert_blast_installed_and_compatible
|
185
|
+
fail BLAST_NOT_INSTALLED unless command? 'blastdbcmd'
|
186
|
+
version = `blastdbcmd -version`.split[1]
|
187
|
+
fail BLAST_NOT_COMPATIBLE, version unless version >= MINIMUM_BLAST_VERSION
|
226
188
|
end
|
227
189
|
|
190
|
+
def assert_blast_databases_present_in_database_dir
|
191
|
+
cmd = "blastdbcmd -recursive -list #{config[:database_dir]}"
|
192
|
+
out = `#{cmd}`
|
193
|
+
errpat = /BLAST Database error/
|
194
|
+
fail NO_BLAST_DATABASE_FOUND, config[:database_dir] if out.empty?
|
195
|
+
fail BLAST_DATABASE_ERROR, cmd, out if out.match(errpat) ||
|
196
|
+
!$CHILD_STATUS.success?
|
197
|
+
end
|
228
198
|
|
229
199
|
# Return `true` if the given command exists and is executable.
|
230
200
|
def command?(command)
|
231
201
|
system("which #{command} > /dev/null 2>&1")
|
232
202
|
end
|
233
|
-
|
234
203
|
end
|
235
204
|
|
236
205
|
# Controller.
|
237
206
|
class App < Sinatra::Base
|
238
|
-
|
239
207
|
# See
|
240
208
|
# http://www.sinatrarb.com/configuration.html
|
241
209
|
configure do
|
@@ -254,7 +222,7 @@ module SequenceServer
|
|
254
222
|
# or http_status` methods. Error blocks errors must explicitly set http
|
255
223
|
# status, if needed, by calling `status` method.
|
256
224
|
# method.
|
257
|
-
enable
|
225
|
+
enable :dump_errors
|
258
226
|
|
259
227
|
# We don't want Sinatra do setup any loggers for us. We will use our own.
|
260
228
|
set :logging, nil
|
@@ -267,6 +235,13 @@ module SequenceServer
|
|
267
235
|
# http://www.sinatrarb.com/intro.html#Mime%20Types
|
268
236
|
configure do
|
269
237
|
mime_type :fasta, 'text/fasta'
|
238
|
+
mime_type :xml, 'text/xml'
|
239
|
+
mime_type :tsv, 'text/tsv'
|
240
|
+
end
|
241
|
+
|
242
|
+
configure :production do
|
243
|
+
set :public_folder,
|
244
|
+
lambda { File.join SequenceServer.root, 'public', 'dist' }
|
270
245
|
end
|
271
246
|
|
272
247
|
helpers do
|
@@ -274,16 +249,16 @@ module SequenceServer
|
|
274
249
|
#
|
275
250
|
# See links.rb for example of a Hash object that will be rendered.
|
276
251
|
def a(link)
|
277
|
-
return unless link[:title]
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
252
|
+
return unless link[:title] && link[:url]
|
253
|
+
a = ['<a']
|
254
|
+
a << "href=#{link[:url]}"
|
255
|
+
a << "class=\"#{link[:class]}\"" if link[:class]
|
256
|
+
a << "target=\"_blank\"" if absolute? link[:url]
|
257
|
+
a << '>'
|
258
|
+
a << "<i class=\"fa #{link[:icon]}\"></i>" if link[:icon]
|
259
|
+
a << link[:title]
|
260
|
+
a << '</a>'
|
261
|
+
a.join("\n")
|
287
262
|
end
|
288
263
|
|
289
264
|
# Is the given URI absolute? (or relative?)
|
@@ -291,19 +266,34 @@ module SequenceServer
|
|
291
266
|
URI.parse(uri).absolute?
|
292
267
|
end
|
293
268
|
|
294
|
-
#
|
295
|
-
def
|
296
|
-
|
269
|
+
# Prettify given data.
|
270
|
+
def prettify(data)
|
271
|
+
return prettify_tuple(data) if tuple? data
|
272
|
+
return prettify_float(data) if data.is_a? Float
|
273
|
+
data
|
297
274
|
end
|
298
275
|
|
299
|
-
# Formats
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
276
|
+
# Formats float as "a.bcd" or "a x b^c". The latter if float is
|
277
|
+
# scientific notation. Former otherwise.
|
278
|
+
def prettify_float(float)
|
279
|
+
float.to_s.sub(/(\d*\.\d*)e?([+-]\d*)?/) do
|
280
|
+
base = Regexp.last_match[1]
|
281
|
+
power = Regexp.last_match[2]
|
282
|
+
s = format '%.2f', base
|
283
|
+
s << " × 10<sup>#{power}</sup>" if power
|
304
284
|
s
|
305
285
|
end
|
306
286
|
end
|
287
|
+
|
288
|
+
# Formats an array of two elements as "first (last)".
|
289
|
+
def prettify_tuple(tuple)
|
290
|
+
"#{tuple.first} (#{tuple.last})"
|
291
|
+
end
|
292
|
+
|
293
|
+
# Is the given value a tuple? (array of length two).
|
294
|
+
def tuple?(data)
|
295
|
+
return true if data.is_a?(Array) && data.length == 2
|
296
|
+
end
|
307
297
|
end
|
308
298
|
|
309
299
|
# For any request that hits the app in development mode, log incoming
|
@@ -314,15 +304,20 @@ module SequenceServer
|
|
314
304
|
|
315
305
|
# Render the search form.
|
316
306
|
get '/' do
|
317
|
-
erb :search, :locals => {:databases => Database.group_by(&:type)}
|
307
|
+
erb :search, :locals => { :databases => Database.group_by(&:type) }
|
318
308
|
end
|
319
309
|
|
320
310
|
# BLAST search!
|
321
311
|
post '/' do
|
322
|
-
erb :result, :locals => {:report => BLAST.run(params)}
|
312
|
+
erb :result, :locals => { :report => BLAST.run(params) }
|
323
313
|
end
|
324
314
|
|
325
|
-
#
|
315
|
+
# @params sequence_ids: whitespace separated list of sequence ids to
|
316
|
+
# retrieve
|
317
|
+
# @params database_ids: whitespace separated list of database ids to
|
318
|
+
# retrieve the sequence from.
|
319
|
+
# @params download: whether to return raw response or initiate file
|
320
|
+
# download
|
326
321
|
#
|
327
322
|
# Use whitespace to separate entries in sequence_ids (all other chars exist
|
328
323
|
# in identifiers) and retreival_databases (we don't allow whitespace in a
|
@@ -345,18 +340,26 @@ module SequenceServer
|
|
345
340
|
{
|
346
341
|
:sequence_ids => sequence_ids,
|
347
342
|
:databases => Database[database_ids].map(&:title),
|
348
|
-
:sequences => sequences.map
|
343
|
+
:sequences => sequences.map(&:info)
|
349
344
|
}.to_json
|
350
345
|
end
|
351
346
|
end
|
352
347
|
|
348
|
+
get '/get_report/' do
|
349
|
+
ofile = BLAST.format(params)
|
350
|
+
|
351
|
+
send_file ofile[:filepath],
|
352
|
+
:filename => ofile[:filename],
|
353
|
+
:type => ofile[:type].to_sym
|
354
|
+
end
|
355
|
+
|
353
356
|
# This error block will only ever be hit if the user gives us a funny
|
354
357
|
# sequence or incorrect advanced parameter. Well, we could hit this block
|
355
358
|
# if someone is playing around with our HTTP API too.
|
356
359
|
error BLAST::ArgumentError do
|
357
360
|
status 400
|
358
361
|
error = env['sinatra.error']
|
359
|
-
erb :'400', :locals => {:error => error}
|
362
|
+
erb :'400', :locals => { :error => error }
|
360
363
|
end
|
361
364
|
|
362
365
|
# This will catch any unhandled error and some very special errors. Ideally
|
@@ -367,7 +370,7 @@ module SequenceServer
|
|
367
370
|
error Exception, BLAST::RuntimeError do
|
368
371
|
status 500
|
369
372
|
error = env['sinatra.error']
|
370
|
-
erb :'500', :locals => {:error => error}
|
373
|
+
erb :'500', :locals => { :error => error }
|
371
374
|
end
|
372
375
|
end
|
373
376
|
end
|