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
@@ -0,0 +1,94 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
3
|
+
# Define Config class.
|
4
|
+
module SequenceServer
|
5
|
+
# Capture our configuration system.
|
6
|
+
class Config
|
7
|
+
extend Forwardable
|
8
|
+
|
9
|
+
def_delegators SequenceServer, :logger
|
10
|
+
|
11
|
+
def initialize(data = {})
|
12
|
+
@data = normalize data
|
13
|
+
@config_file = @data.delete(:config_file) || default_config_file
|
14
|
+
@config_file = File.expand_path(@config_file)
|
15
|
+
@data = parse_config_file.update @data
|
16
|
+
@data = defaults.update @data
|
17
|
+
end
|
18
|
+
|
19
|
+
attr_reader :data, :config_file
|
20
|
+
|
21
|
+
# Get.
|
22
|
+
def [](key)
|
23
|
+
data[key]
|
24
|
+
end
|
25
|
+
|
26
|
+
# Set.
|
27
|
+
def []=(key, value)
|
28
|
+
data[key] = value
|
29
|
+
end
|
30
|
+
|
31
|
+
# Exists?
|
32
|
+
def include?(key)
|
33
|
+
data.include? key
|
34
|
+
end
|
35
|
+
|
36
|
+
# Write config data to config file.
|
37
|
+
def write_config_file
|
38
|
+
return unless config_file
|
39
|
+
File.open(config_file, 'w') do |f|
|
40
|
+
f.puts(data.delete_if { |_, v| v.nil? }.to_yaml)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
# Symbolizes keys. Changes `database` key to `database_dir`.
|
47
|
+
def normalize(data)
|
48
|
+
return {} unless data
|
49
|
+
|
50
|
+
# Symbolize keys.
|
51
|
+
data = Hash[data.map { |k, v| [k.to_sym, v] }]
|
52
|
+
|
53
|
+
# The newer config file version replaces the older database key with
|
54
|
+
# database_dir for correctness. Let's honour the old version as well.
|
55
|
+
if data[:database]
|
56
|
+
database_dir = data.delete(:database)
|
57
|
+
data[:database_dir] ||= database_dir
|
58
|
+
end
|
59
|
+
|
60
|
+
data
|
61
|
+
end
|
62
|
+
|
63
|
+
# Parses and returns data from config_file if it exists. Returns {}
|
64
|
+
# otherwise.
|
65
|
+
def parse_config_file
|
66
|
+
unless file? config_file
|
67
|
+
logger.debug "Configuration file not found: #{config_file}"
|
68
|
+
return {}
|
69
|
+
end
|
70
|
+
|
71
|
+
logger.debug "Reading configuration file: #{config_file}."
|
72
|
+
normalize YAML.load_file(config_file)
|
73
|
+
rescue => error
|
74
|
+
raise CONFIG_FILE_ERROR.new(config_file, error)
|
75
|
+
end
|
76
|
+
|
77
|
+
def file?(file)
|
78
|
+
file && File.exist?(file) && File.file?(file)
|
79
|
+
end
|
80
|
+
|
81
|
+
# Default configuration data.
|
82
|
+
def defaults
|
83
|
+
{
|
84
|
+
:num_threads => 1,
|
85
|
+
:port => 4567,
|
86
|
+
:host => '0.0.0.0'
|
87
|
+
}
|
88
|
+
end
|
89
|
+
|
90
|
+
def default_config_file
|
91
|
+
'~/.sequenceserver.conf'
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -4,24 +4,45 @@ require 'forwardable'
|
|
4
4
|
|
5
5
|
require 'sequenceserver/sequence'
|
6
6
|
|
7
|
+
# Define Database class.
|
7
8
|
module SequenceServer
|
8
|
-
|
9
9
|
# Captures a directory containing FASTA files and BLAST databases.
|
10
10
|
#
|
11
11
|
# Formatting a FASTA for use with BLAST+ will create 3 or 6 files,
|
12
12
|
# collectively referred to as a BLAST database.
|
13
13
|
#
|
14
|
-
# It is important that formatted BLAST database files have the same dirname
|
15
|
-
# basename as the source FASTA for SequenceServer to be able to tell
|
16
|
-
# FASTA from unformatted. And that FASTA files be formatted with
|
17
|
-
# option of `makeblastdb` for sequence retrieval to work.
|
14
|
+
# It is important that formatted BLAST database files have the same dirname
|
15
|
+
# and basename as the source FASTA for SequenceServer to be able to tell
|
16
|
+
# formatted FASTA from unformatted. And that FASTA files be formatted with
|
17
|
+
# `parse_seqids` option of `makeblastdb` for sequence retrieval to work.
|
18
18
|
#
|
19
19
|
# SequenceServer will always place BLAST database files alongside input FASTA,
|
20
20
|
# and use `parse_seqids` option of `makeblastdb` to format databases.
|
21
|
-
|
21
|
+
Database = Struct.new(:name, :title, :type, :nsequences, :ncharacters,
|
22
|
+
:updated_on) do
|
23
|
+
def initialize(*args)
|
24
|
+
args[2].downcase! # database type
|
25
|
+
args.each(&:freeze)
|
26
|
+
super
|
22
27
|
|
23
|
-
|
28
|
+
@id = Digest::MD5.hexdigest args.first
|
29
|
+
end
|
30
|
+
|
31
|
+
attr_reader :id
|
32
|
+
|
33
|
+
def include?(accession)
|
34
|
+
out = `blastdbcmd -entry '#{accession}' -db #{name} 2> /dev/null`
|
35
|
+
!out.empty?
|
36
|
+
end
|
24
37
|
|
38
|
+
def to_s
|
39
|
+
"#{type}: #{title} #{name}"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Model Database's eigenclass as a collection of Database objects.
|
44
|
+
class Database
|
45
|
+
class << self
|
25
46
|
include Enumerable
|
26
47
|
|
27
48
|
extend Forwardable
|
@@ -68,10 +89,17 @@ module SequenceServer
|
|
68
89
|
all.first
|
69
90
|
end
|
70
91
|
|
92
|
+
# Intended to be used only for testing.
|
93
|
+
def clear
|
94
|
+
collection.clear
|
95
|
+
end
|
96
|
+
|
71
97
|
# Recurisvely scan `database_dir` for blast databases.
|
72
98
|
def scan_databases_dir
|
73
99
|
database_dir = config[:database_dir]
|
74
|
-
|
100
|
+
cmd = "blastdbcmd -recursive -list #{database_dir}" \
|
101
|
+
' -list_outfmt "%f %t %p %n %l %d" 2>&1'
|
102
|
+
list = `#{cmd}`
|
75
103
|
list.each_line do |line|
|
76
104
|
name = line.split(' ')[0]
|
77
105
|
next if multipart_database_name?(name)
|
@@ -82,13 +110,13 @@ module SequenceServer
|
|
82
110
|
# Recursively scan `database_dir` for un-formatted FASTA and format them
|
83
111
|
# for use with BLAST+.
|
84
112
|
def make_blast_databases
|
85
|
-
unformatted_fastas.
|
113
|
+
unformatted_fastas.select do |file, sequence_type|
|
86
114
|
make_blast_database(file, sequence_type)
|
87
115
|
end
|
88
116
|
end
|
89
117
|
|
90
|
-
# Returns an Array of FASTA files that may require formatting, and the
|
91
|
-
# of sequence contained in each FASTA.
|
118
|
+
# Returns an Array of FASTA files that may require formatting, and the
|
119
|
+
# type of sequence contained in each FASTA.
|
92
120
|
#
|
93
121
|
# > unformatted_fastas
|
94
122
|
# => [['/foo/bar.fasta', :nulceotide], ...]
|
@@ -96,13 +124,12 @@ module SequenceServer
|
|
96
124
|
list = []
|
97
125
|
database_dir = config[:database_dir]
|
98
126
|
Find.find database_dir do |file|
|
99
|
-
next if File.directory?
|
127
|
+
next if File.directory? file
|
100
128
|
next if Database.include? file
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
end
|
129
|
+
next unless probably_fasta? file
|
130
|
+
sequence_type = guess_sequence_type_in_fasta file
|
131
|
+
if [:protein, :nucleotide].include?(sequence_type)
|
132
|
+
list << [file, sequence_type]
|
106
133
|
end
|
107
134
|
end
|
108
135
|
list
|
@@ -110,24 +137,46 @@ module SequenceServer
|
|
110
137
|
|
111
138
|
# Create BLAST database, given FASTA file and sequence type in FASTA file.
|
112
139
|
def make_blast_database(file, type)
|
140
|
+
return unless make_blast_database? file, type
|
141
|
+
title = get_database_title(file)
|
142
|
+
_make_blast_database(file, type, title)
|
143
|
+
end
|
144
|
+
|
145
|
+
def _make_blast_database(file, type, title, quiet = false)
|
146
|
+
cmd = 'makeblastdb -parse_seqids -hash_index ' \
|
147
|
+
"-in #{file} -dbtype #{type.to_s.slice(0, 4)} -title '#{title}'"
|
148
|
+
cmd << ' &> /dev/null' if quiet
|
149
|
+
system cmd
|
150
|
+
end
|
151
|
+
|
152
|
+
# Show file path and guessed sequence type to the user and obtain a y/n
|
153
|
+
# response.
|
154
|
+
#
|
155
|
+
# Returns true if the user entered anything but 'n' or 'N'.
|
156
|
+
def make_blast_database?(file, type)
|
157
|
+
puts
|
158
|
+
puts
|
113
159
|
puts "FASTA file: #{file}"
|
114
160
|
puts "FASTA type: #{type}"
|
161
|
+
print 'Proceed? [y/n] (Default: y): '
|
115
162
|
|
116
|
-
print "Proceed? [y/n] (Default: y): "
|
117
163
|
response = STDIN.gets.to_s.strip
|
164
|
+
!response.match(/n/i)
|
165
|
+
end
|
118
166
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
167
|
+
# Generate a title for the given database and show it to the user for
|
168
|
+
# confirmation.
|
169
|
+
#
|
170
|
+
# Returns user input if any. Auto-generated title otherwise.
|
171
|
+
def get_database_title(path)
|
172
|
+
default = make_db_title(File.basename(path))
|
173
|
+
print "Enter a database title or will use '#{default}': "
|
174
|
+
from_user = STDIN.gets.to_s
|
175
|
+
from_user.strip.empty? && default || from_user
|
128
176
|
end
|
129
177
|
|
130
|
-
# Returns true if the database name appears to be a multi-part database
|
178
|
+
# Returns true if the database name appears to be a multi-part database
|
179
|
+
# name.
|
131
180
|
#
|
132
181
|
# e.g.
|
133
182
|
# /home/ben/pd.ben/sequenceserver/db/nr.00 => yes
|
@@ -166,30 +215,21 @@ module SequenceServer
|
|
166
215
|
# NOTE: 2^15 == 32786. Approximately 546 lines, assuming 60 characters on
|
167
216
|
# each line.
|
168
217
|
def guess_sequence_type_in_fasta(file)
|
169
|
-
|
170
|
-
|
171
|
-
sequence_types =
|
218
|
+
sequences = sample_sequences(file)
|
219
|
+
sequence_types = sequences.map { |seq| Sequence.guess_type(seq) }
|
220
|
+
sequence_types = sequence_types.uniq.compact
|
172
221
|
(sequence_types.length == 1) && sequence_types.first
|
173
222
|
end
|
174
|
-
end
|
175
223
|
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
def include?(accession)
|
187
|
-
out = `blastdbcmd -entry '#{accession}' -db #{name} 2> /dev/null`
|
188
|
-
not out.empty?
|
189
|
-
end
|
190
|
-
|
191
|
-
def to_s
|
192
|
-
"#{type}: #{title} #{name}"
|
224
|
+
# Read first 32768 characters of the file. Split on fasta def line
|
225
|
+
# pattern and return.
|
226
|
+
#
|
227
|
+
# If the given file is FASTA, returns Array of as many different
|
228
|
+
# sequences in the portion of the file read. Returns the portion
|
229
|
+
# of the file read wrapped in an Array otherwise.
|
230
|
+
def sample_sequences(file)
|
231
|
+
File.read(file, 32_768).split(/^>.+$/).delete_if(&:empty?)
|
232
|
+
end
|
193
233
|
end
|
194
234
|
end
|
195
235
|
end
|
@@ -0,0 +1,154 @@
|
|
1
|
+
# This file defines all possible exceptions that can be thrown by
|
2
|
+
# SequenceServer on startup.
|
3
|
+
#
|
4
|
+
# Exceptions only ever inform another entity (downstream code or users) of an
|
5
|
+
# issue. Exceptions may or may not be recoverable.
|
6
|
+
#
|
7
|
+
# Error classes should be seen as: the error code (class name), human readable
|
8
|
+
# message (to_s method), and necessary attributes to act on the error.
|
9
|
+
#
|
10
|
+
# We define as many error classes as needed to be precise about the issue, thus
|
11
|
+
# making it easy for downstream code (bin/sequenceserver or config.ru) to act
|
12
|
+
# on them.
|
13
|
+
|
14
|
+
module SequenceServer
|
15
|
+
# Error in config file.
|
16
|
+
class CONFIG_FILE_ERROR < StandardError
|
17
|
+
def initialize(ent, err)
|
18
|
+
@ent = ent
|
19
|
+
@err = err
|
20
|
+
end
|
21
|
+
|
22
|
+
attr_reader :ent, :err
|
23
|
+
|
24
|
+
def to_s
|
25
|
+
<<MSG
|
26
|
+
Error in config file: #{ent}.
|
27
|
+
#{err}
|
28
|
+
MSG
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
## ENOENT ##
|
33
|
+
|
34
|
+
# Name borrowed from standard Errno::ENOENT, this class serves as a template
|
35
|
+
# for defining errors that mean "expected to find <entity> at <path>, but
|
36
|
+
# didn't".
|
37
|
+
#
|
38
|
+
# ENOENT is raised if and only if an entity was set, either using CLI or
|
39
|
+
# config file. For instance, it's compulsory to set database_dir. But ENOENT
|
40
|
+
# is not raised if database_dir is not set. ENOENT is raised if database_dir
|
41
|
+
# was set, but does not exist.
|
42
|
+
class ENOENT < StandardError
|
43
|
+
def initialize(des, ent)
|
44
|
+
@des = des
|
45
|
+
@ent = ent
|
46
|
+
end
|
47
|
+
|
48
|
+
attr_reader :des, :ent
|
49
|
+
|
50
|
+
def to_s
|
51
|
+
"Could not find #{des}: #{ent}"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Raised if bin dir set, but does not exist.
|
56
|
+
class BIN_DIR_NOT_FOUND < ENOENT
|
57
|
+
def initialize(ent)
|
58
|
+
super 'bin dir', ent
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# Raised if database dir set, but does not exist.
|
63
|
+
class DATABASE_DIR_NOT_FOUND < ENOENT
|
64
|
+
def initialize(ent)
|
65
|
+
super 'database dir', ent
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# Raised if extension file set, but does not exist.
|
70
|
+
class EXTENSION_FILE_NOT_FOUND < ENOENT
|
71
|
+
def initialize(ent)
|
72
|
+
super 'extension file', ent
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
## NUM THREADS ##
|
77
|
+
|
78
|
+
# Raised if num_threads set by the user is incorrect.
|
79
|
+
class NUM_THREADS_INCORRECT < StandardError
|
80
|
+
def to_s
|
81
|
+
'Number of threads should be a number greater than or equal to 1.'
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
## BLAST NOT INSTALLED OR NOT COMPATIBLE ##
|
86
|
+
|
87
|
+
# Raised if SequenceServer could not locate NCBI BLAST+ installation on
|
88
|
+
# user's system.
|
89
|
+
class BLAST_NOT_INSTALLED < StandardError
|
90
|
+
def to_s
|
91
|
+
'Could not locate BLAST+ binaries.'
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
# Raised if SequenceServer determined NCBI BLAST+ present on the user's
|
96
|
+
# system but not meeting SequenceServer's minimum version requirement.
|
97
|
+
class BLAST_NOT_COMPATIBLE < StandardError
|
98
|
+
def initialize(version)
|
99
|
+
@version = version
|
100
|
+
end
|
101
|
+
|
102
|
+
attr_reader :version
|
103
|
+
|
104
|
+
def to_s
|
105
|
+
<<MSG
|
106
|
+
Your BLAST+ version #{version} is outdated.
|
107
|
+
SequenceServer needs NCBI BLAST+ version #{MINIMUM_BLAST_VERSION} or higher.
|
108
|
+
MSG
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
## BLAST+ DATABASE RELATED ##
|
113
|
+
|
114
|
+
# Raised if 'database_dir' not set.
|
115
|
+
class DATABASE_DIR_NOT_SET < StandardError
|
116
|
+
def to_s
|
117
|
+
'Database dir not set.'
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
# Raised if not even one BLAST+ database was found in database_dir.
|
122
|
+
class NO_BLAST_DATABASE_FOUND < StandardError
|
123
|
+
def initialize(database_dir)
|
124
|
+
@database_dir = database_dir
|
125
|
+
end
|
126
|
+
|
127
|
+
attr_reader :database_dir
|
128
|
+
|
129
|
+
def to_s
|
130
|
+
"Could not find BLAST+ databases in: #{database_dir}."
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
# Raised if there was an error determining BLAST+ databases in database_dir.
|
135
|
+
class BLAST_DATABASE_ERROR
|
136
|
+
def initialize(cmd, out)
|
137
|
+
@cmd = cmd
|
138
|
+
@out = out
|
139
|
+
end
|
140
|
+
|
141
|
+
attr_reader :cmd, :out
|
142
|
+
|
143
|
+
def to_s
|
144
|
+
<<MSG
|
145
|
+
Error obtaining BLAST databases.
|
146
|
+
Tried: #{cmd}
|
147
|
+
Error:
|
148
|
+
#{out.strip}
|
149
|
+
|
150
|
+
Please could you report this to 'https://groups.google.com/forum/#!forum/sequenceserver'?
|
151
|
+
MSG
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|