sequenceserver 1.1.0.beta12 → 2.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rspec +1 -0
- data/.travis.yml +5 -5
- data/README.md +86 -43
- data/bin/sequenceserver +29 -32
- data/lib/sequenceserver.rb +86 -123
- data/lib/sequenceserver/api_errors.rb +3 -1
- data/lib/sequenceserver/blast/hit.rb +48 -28
- data/lib/sequenceserver/blast/job.rb +28 -8
- data/lib/sequenceserver/blast/report.rb +52 -15
- data/lib/sequenceserver/database.rb +71 -0
- data/lib/sequenceserver/exceptions.rb +5 -10
- data/lib/sequenceserver/job.rb +8 -1
- data/lib/sequenceserver/links.rb +49 -17
- data/lib/sequenceserver/logger.rb +2 -2
- data/lib/sequenceserver/routes.rb +20 -14
- data/lib/sequenceserver/sys.rb +86 -0
- data/lib/sequenceserver/version.rb +1 -1
- data/public/css/sequenceserver.min.css +3 -3
- data/public/js/alignment_exporter.js +1 -1
- data/public/js/hsp.js +1 -1
- data/public/js/report.js +76 -63
- data/public/js/search.js +29 -6
- data/public/sequenceserver-report.min.js +4 -4
- data/public/sequenceserver-search.min.js +2 -2
- data/sequenceserver.gemspec +3 -2
- data/spec/blast_versions/blast_2.2.30/blast_2.2.30_spec.rb +228 -0
- data/spec/blast_versions/blast_2.2.30/import_spec_capybara_local_2.2.30.rb +53 -0
- data/spec/blast_versions/blast_2.2.31/blast_2.2.31_spec.rb +228 -0
- data/spec/blast_versions/blast_2.2.31/import_spec_capybara_local_2.2.31.rb +53 -0
- data/spec/{blast_spec.rb → blast_versions/blast_2.3.0/blast_2.3.0_spec.rb} +8 -37
- data/spec/blast_versions/blast_2.3.0/import_spec_capybara_local_2.3.0.rb +52 -0
- data/spec/blast_versions/blast_2.4.0/blast_2.4.0_spec.rb +228 -0
- data/spec/blast_versions/blast_2.4.0/import_spec_capybara_local_2.4.0.rb +52 -0
- data/spec/blast_versions/blast_2.5.0/blast_2.5.0_spec.rb +228 -0
- data/spec/blast_versions/blast_2.5.0/import_spec_capybara_local_2.5.0.rb +53 -0
- data/spec/blast_versions/blast_2.6.0/blast_2.6.0_spec.rb +228 -0
- data/spec/blast_versions/blast_2.6.0/import_spec_capybara_local_2.6.0.rb +52 -0
- data/spec/blast_versions/blast_2.7.1/blast_2.7.1_spec.rb +228 -0
- data/spec/blast_versions/blast_2.7.1/import_spec_capybara_local_2.7.1.rb +56 -0
- data/spec/blast_versions/blast_2.8.1/blast_2.8.1_spec.rb +228 -0
- data/spec/blast_versions/blast_2.8.1/import_spec_capybara_local_2.8.1.rb +55 -0
- data/spec/blast_versions/blast_2.9.0/blast_2.9.0_spec.rb +228 -0
- data/spec/blast_versions/blast_2.9.0/import_spec_capybara_local_2.9.0.rb +53 -0
- data/spec/blast_versions/diamond_0.9.24/diamond_0.9.24_spec.rb +176 -0
- data/spec/blast_versions/diamond_0.9.24/import_spec_capybara_local_0.9.24.rb +39 -0
- data/spec/capybara_spec.local.rb +190 -0
- data/spec/capybara_spec.rb +15 -13
- data/spec/config_spec.rb +1 -1
- data/spec/database/funky_ids/funky_ids.fa +2 -0
- data/spec/database/funky_ids/funky_ids.fa.nhd +8 -0
- data/spec/database/funky_ids/funky_ids.fa.nhi +0 -0
- data/spec/database/funky_ids/funky_ids.fa.nhr +0 -0
- data/spec/database/funky_ids/funky_ids.fa.nin +0 -0
- data/spec/database/funky_ids/funky_ids.fa.nog +0 -0
- data/spec/database/funky_ids/funky_ids.fa.nsd +15 -13
- data/spec/database/funky_ids/funky_ids.fa.nsi +0 -0
- data/spec/database/funky_ids/funky_ids.fa.nsq +0 -0
- data/spec/database_spec.rb +2 -2
- data/spec/dotdir/blast_2.2.30/blastn/BLASTN_XML_2.2.30.xml +1201 -0
- data/spec/dotdir/blast_2.2.30/blastn/job.yaml +8 -0
- data/spec/dotdir/blast_2.2.30/blastn_nohits/BLASTN_NO_HITS_XML_2.2.30.xml +866 -0
- data/spec/dotdir/blast_2.2.30/blastn_nohits/job.yaml +8 -0
- data/spec/dotdir/blast_2.2.30/blastp/BLASTP_XML_2.2.30.xml +1181 -0
- data/spec/dotdir/blast_2.2.30/blastp/job.yaml +8 -0
- data/spec/dotdir/blast_2.2.30/blastx/BLASTX_XML_2.2.30.xml +1181 -0
- data/spec/dotdir/blast_2.2.30/blastx/job.yaml +8 -0
- data/spec/dotdir/blast_2.2.30/tblastn/TBLASTN_XML_2.2.30.xml +1181 -0
- data/spec/dotdir/blast_2.2.30/tblastn/job.yaml +8 -0
- data/spec/dotdir/blast_2.2.30/tblastx/TBLASTX_XML_2.2.30.xml +8857 -0
- data/spec/dotdir/blast_2.2.30/tblastx/job.yaml +8 -0
- data/spec/dotdir/blast_2.2.31/blastn/BLASTN_XML_2.2.31.xml +1201 -0
- data/spec/dotdir/blast_2.2.31/blastn/job.yaml +8 -0
- data/spec/dotdir/blast_2.2.31/blastn_nohits/BLASTN_NO_HITS_XML_2.2.31.xml +866 -0
- data/spec/dotdir/blast_2.2.31/blastn_nohits/job.yaml +8 -0
- data/spec/dotdir/blast_2.2.31/blastp/BLASTP_XML_2.2.31.xml +1181 -0
- data/spec/dotdir/blast_2.2.31/blastp/job.yaml +8 -0
- data/spec/dotdir/blast_2.2.31/blastx/BLASTX_XML_2.2.31.xml +1181 -0
- data/spec/dotdir/blast_2.2.31/blastx/job.yaml +8 -0
- data/spec/dotdir/blast_2.2.31/tblastn/TBLASTN_XML_2.2.31.xml +1181 -0
- data/spec/dotdir/blast_2.2.31/tblastn/job.yaml +8 -0
- data/spec/dotdir/blast_2.2.31/tblastx/TBLASTX_XML_2.2.31.xml +8857 -0
- data/spec/dotdir/blast_2.2.31/tblastx/job.yaml +8 -0
- data/spec/dotdir/blast_2.3.0/blastn/BLASTN_XML_2.3.0.xml +1201 -0
- data/spec/dotdir/blast_2.3.0/blastn/job.yaml +8 -0
- data/spec/dotdir/blast_2.3.0/blastn_nohits/BLASTN_NO_HITS_XML_2.3.0.xml +866 -0
- data/spec/dotdir/blast_2.3.0/blastn_nohits/job.yaml +8 -0
- data/spec/dotdir/blast_2.3.0/blastp/BLASTP_XML_2.3.0.xml +1181 -0
- data/spec/dotdir/blast_2.3.0/blastp/job.yaml +8 -0
- data/spec/dotdir/blast_2.3.0/blastx/BLASTX_XML_2.3.0.xml +1181 -0
- data/spec/dotdir/blast_2.3.0/blastx/job.yaml +8 -0
- data/spec/dotdir/blast_2.3.0/tblastn/TBLASTN_XML_2.3.0.xml +1181 -0
- data/spec/dotdir/blast_2.3.0/tblastn/job.yaml +8 -0
- data/spec/dotdir/blast_2.3.0/tblastx/TBLASTX_XML_2.3.0.xml +8857 -0
- data/spec/dotdir/blast_2.3.0/tblastx/job.yaml +8 -0
- data/spec/dotdir/blast_2.4.0/blastn/BLASTN_XML_2.4.0.xml +1201 -0
- data/spec/dotdir/blast_2.4.0/blastn/TBLASTN_XML_2.4.0.xml +1181 -0
- data/spec/dotdir/blast_2.4.0/blastn/job.yaml +8 -0
- data/spec/dotdir/blast_2.4.0/blastn_nohits/BLASTN_NO_HITS_XML_2.4.0.xml +866 -0
- data/spec/dotdir/blast_2.4.0/blastn_nohits/job.yaml +8 -0
- data/spec/dotdir/blast_2.4.0/blastp/BLASTP_XML_2.4.0.xml +1181 -0
- data/spec/dotdir/blast_2.4.0/blastp/job.yaml +8 -0
- data/spec/dotdir/blast_2.4.0/blastx/BLASTX_XML_2.4.0.xml +1181 -0
- data/spec/dotdir/blast_2.4.0/blastx/job.yaml +8 -0
- data/spec/dotdir/blast_2.4.0/tblastn/TBLASTN_XML_2.4.0.xml +1181 -0
- data/spec/dotdir/blast_2.4.0/tblastn/job.yaml +8 -0
- data/spec/dotdir/blast_2.4.0/tblastx/TBLASTX_XML_2.4.0.xml +8857 -0
- data/spec/dotdir/blast_2.4.0/tblastx/job.yaml +8 -0
- data/spec/dotdir/blast_2.5.0/blastn/BLASTN_LONG_XML_2.5.0.xml +18813 -0
- data/spec/dotdir/blast_2.5.0/blastn/BLASTN_XML_2.5.0.xml +1201 -0
- data/spec/dotdir/blast_2.5.0/blastn/job.yaml +8 -0
- data/spec/dotdir/blast_2.5.0/blastn_nohits/BLASTN_NO_HITS_XML_2.5.0.xml +866 -0
- data/spec/dotdir/blast_2.5.0/blastn_nohits/job.yaml +8 -0
- data/spec/dotdir/blast_2.5.0/blastp/BLASTP +2161 -0
- data/spec/dotdir/blast_2.5.0/blastp/BLASTP_XML_2.5.0.xml +1181 -0
- data/spec/dotdir/blast_2.5.0/blastp/job.yaml +8 -0
- data/spec/dotdir/blast_2.5.0/blastx/BLASTX +28080 -0
- data/spec/dotdir/blast_2.5.0/blastx/BLASTX_XML_2.5.0.xml +1181 -0
- data/spec/dotdir/blast_2.5.0/blastx/job.yaml +8 -0
- data/spec/dotdir/blast_2.5.0/tblastn/TBLASTN +29486 -0
- data/spec/dotdir/blast_2.5.0/tblastn/TBLASTN_XML_2.5.0.xml +1181 -0
- data/spec/dotdir/blast_2.5.0/tblastn/job.yaml +8 -0
- data/spec/dotdir/blast_2.5.0/tblastx/TBLASTX +180859 -0
- data/spec/dotdir/blast_2.5.0/tblastx/TBLASTX_XML_2.5.0.xml +8857 -0
- data/spec/dotdir/blast_2.5.0/tblastx/job.yaml +8 -0
- data/spec/dotdir/blast_2.6.0/blastn/BLASTN_XML_2.6.0.xml +1201 -0
- data/spec/dotdir/blast_2.6.0/blastn/job.yaml +8 -0
- data/spec/dotdir/blast_2.6.0/blastn_nohits/BLASTN_NO_HITS_XML_2.6.0.xml +866 -0
- data/spec/dotdir/blast_2.6.0/blastn_nohits/job.yaml +8 -0
- data/spec/dotdir/blast_2.6.0/blastp/BLASTP_XML_2.6.0.xml +1181 -0
- data/spec/dotdir/blast_2.6.0/blastp/job.yaml +8 -0
- data/spec/dotdir/blast_2.6.0/blastx/BLASTX_XML_2.6.0.xml +1181 -0
- data/spec/dotdir/blast_2.6.0/blastx/job.yaml +8 -0
- data/spec/dotdir/blast_2.6.0/tblastn/TBLASTN_XML_2.6.0.xml +1181 -0
- data/spec/dotdir/blast_2.6.0/tblastn/job.yaml +8 -0
- data/spec/dotdir/blast_2.6.0/tblastx/TBLASTX_XML_2.6.0.xml +8857 -0
- data/spec/dotdir/blast_2.6.0/tblastx/job.yaml +8 -0
- data/spec/dotdir/blast_2.7.1/blastn/BLASTN_XML_2.7.1.xml +1201 -0
- data/spec/dotdir/blast_2.7.1/blastn/job.yaml +8 -0
- data/spec/dotdir/blast_2.7.1/blastn_nohits/BLASTN_NO_HITS_XML_2.7.1.xml +866 -0
- data/spec/dotdir/blast_2.7.1/blastn_nohits/job.yaml +8 -0
- data/spec/dotdir/blast_2.7.1/blastp/BLASTP_XML_2.7.1.xml +1181 -0
- data/spec/dotdir/blast_2.7.1/blastp/job.yaml +8 -0
- data/spec/dotdir/blast_2.7.1/blastx/BLASTX_XML_2.7.1.xml +1181 -0
- data/spec/dotdir/blast_2.7.1/blastx/job.yaml +8 -0
- data/spec/dotdir/blast_2.7.1/tblastn/TBLASTN_XML_2.7.1.xml +1181 -0
- data/spec/dotdir/blast_2.7.1/tblastn/job.yaml +8 -0
- data/spec/dotdir/blast_2.7.1/tblastx/TBLASTX_XML_2.7.1.xml +8857 -0
- data/spec/dotdir/blast_2.7.1/tblastx/job.yaml +8 -0
- data/spec/dotdir/blast_2.8.1/blastn/BLASTN_XML_2.8.1.xml +1201 -0
- data/spec/dotdir/blast_2.8.1/blastn/job.yaml +8 -0
- data/spec/dotdir/blast_2.8.1/blastn_nohits/BLASTN_NO_HITS_XML_2.8.1.xml +866 -0
- data/spec/dotdir/blast_2.8.1/blastn_nohits/job.yaml +8 -0
- data/spec/dotdir/blast_2.8.1/blastp/BLASTP_XML_2.8.1.xml +1181 -0
- data/spec/dotdir/blast_2.8.1/blastp/job.yaml +8 -0
- data/spec/dotdir/blast_2.8.1/blastx/BLASTX_XML_2.8.1.xml +1181 -0
- data/spec/dotdir/blast_2.8.1/blastx/job.yaml +8 -0
- data/spec/dotdir/blast_2.8.1/tblastn/TBLASTN_XML_2.8.1.xml +1181 -0
- data/spec/dotdir/blast_2.8.1/tblastn/job.yaml +8 -0
- data/spec/dotdir/blast_2.8.1/tblastx/TBLASTX_XML_2.8.1.xml +8857 -0
- data/spec/dotdir/blast_2.8.1/tblastx/job.yaml +8 -0
- data/spec/dotdir/blast_2.9.0/blastn/BLASTN_XML_2.9.0.xml +1201 -0
- data/spec/dotdir/blast_2.9.0/blastn/job.yaml +8 -0
- data/spec/dotdir/blast_2.9.0/blastn_nohits/BLASTN_NO_HITS_XML_2.9.0.xml +866 -0
- data/spec/dotdir/blast_2.9.0/blastn_nohits/job.yaml +8 -0
- data/spec/dotdir/blast_2.9.0/blastp/BLASTP_XML_2.9.0.xml +1181 -0
- data/spec/dotdir/blast_2.9.0/blastp/job.yaml +8 -0
- data/spec/dotdir/blast_2.9.0/blastx/BLASTX_XML_2.9.0.xml +1181 -0
- data/spec/dotdir/blast_2.9.0/blastx/job.yaml +8 -0
- data/spec/dotdir/blast_2.9.0/tblastn/TBLASTN_XML_2.9.0.xml +1181 -0
- data/spec/dotdir/blast_2.9.0/tblastn/job.yaml +8 -0
- data/spec/dotdir/blast_2.9.0/tblastx/TBLASTX_XML_2.9.0.xml +8857 -0
- data/spec/dotdir/blast_2.9.0/tblastx/job.yaml +8 -0
- data/spec/dotdir/diamond_0.9.24/blastp/DIAMOND_BLASTP_0.9.24.xml +1040 -0
- data/spec/dotdir/diamond_0.9.24/blastp/job.yaml +8 -0
- data/spec/dotdir/diamond_0.9.24/blastx/DIAMOND_BLASTX_0.9.24.xml +1040 -0
- data/spec/dotdir/diamond_0.9.24/blastx/job.yaml +8 -0
- data/spec/dotdir/diamond_0.9.24/blastx_nohits/DIAMOND_BLASTX_NOHITS_0.9.24.xml +41 -0
- data/spec/dotdir/diamond_0.9.24/blastx_nohits/job.yaml +8 -0
- data/spec/download_helper.rb +32 -0
- data/spec/import_spec_capybara_local.rb +61 -0
- data/spec/sequence_spec.rb +1 -2
- data/spec/sequences/Nucleotide_TP53_COX41.fasta +15 -0
- data/spec/sequences/Protein_TP53_COX41.fasta +12 -0
- data/spec/sequences/Query_1_SI2_2_0_06267.txt +6 -0
- data/spec/{nucleotide_query.fa → sequences/nucleotide_query.fa} +0 -0
- data/spec/sequences/problematic_query.fa +5 -0
- data/spec/sequences/protein_query.fa +9 -0
- data/spec/sequences/sample_query_fire_ant_obps.fa +44 -0
- data/spec/sequences/sequenceserver-SI2.2.0_06267.fa +5 -0
- data/spec/sequenceserver_spec.rb +3 -3
- data/spec/spec_helper.rb +59 -0
- metadata +185 -28
- data/spec/protein_query.fa +0 -21
- data/spec/sample_reports/blastn_sample/job.yaml +0 -10
- data/spec/sample_reports/blastn_sample/stdout +0 -144
- data/spec/sample_reports/blastp_sample/job.yaml +0 -10
- data/spec/sample_reports/blastp_sample/stdout +0 -1187
- data/spec/sample_reports/blastx_sample/job.yaml +0 -10
- data/spec/sample_reports/blastx_sample/stdout +0 -1191
- data/spec/sample_reports/no_hits_sample/job.yaml +0 -10
- data/spec/sample_reports/no_hits_sample/stdout +0 -130
- data/spec/sample_reports/tblastn_sample/job.yaml +0 -10
- data/spec/sample_reports/tblastn_sample/stdout +0 -1107
- data/spec/sample_reports/tblastx_sample/job.yaml +0 -10
- data/spec/sample_reports/tblastx_sample/stdout +0 -2422
- data/spec/sample_reports/with_hits_sample/job.yaml +0 -10
- data/spec/sample_reports/with_hits_sample/stdout +0 -1489
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9e93a0ff5ecf5f80747e270285cf563557ecfb46
|
4
|
+
data.tar.gz: 17d972e191f301ffb704bb3838b5f7de0b8f0f4c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 15ef2d18c14fc2cfaec9a422ee1b569cfa380ea23df1258045c4085ccb2fbfef8f0b26a5eccde5a58ceb68eace7c67669cef6bade15dc11ec0e85fbfb07bb4dd
|
7
|
+
data.tar.gz: 9ecd465890cb316446748d181b9c4a2a29a53b203d943142d76f23e2a53cd8bbabbaf5f798f8478317aef09ed0b3d23dfbbe4487f97eee013167de4b2dee410c
|
data/.rspec
CHANGED
data/.travis.yml
CHANGED
@@ -24,12 +24,12 @@ before_script:
|
|
24
24
|
- ./cc-test-reporter before-build
|
25
25
|
script:
|
26
26
|
- bundle exec rspec --exclude-pattern 'capybara*' # unit tests
|
27
|
-
- platform='macOS 10.
|
28
|
-
- platform='macOS 10.
|
29
|
-
- platform='macOS 10.
|
27
|
+
- platform='macOS 10.14' browserName=safari browserVersion=12 bundle exec rspec spec/capybara_spec.rb
|
28
|
+
- platform='macOS 10.14' browserName=chrome browserVersion=71 bundle exec rspec spec/capybara_spec.rb
|
29
|
+
- platform='macOS 10.14' browserName=firefox browserVersion=64 bundle exec rspec spec/capybara_spec.rb
|
30
30
|
- platform='Windows 10' browserName=microsoftedge browserVersion='16.16299' bundle exec rspec spec/capybara_spec.rb
|
31
|
-
- platform='Windows 10' browserName=chrome browserVersion=
|
32
|
-
- platform='Windows 10' browserName=firefox browserVersion=
|
31
|
+
- platform='Windows 10' browserName=chrome browserVersion=71 bundle exec rspec spec/capybara_spec.rb
|
32
|
+
- platform='Windows 10' browserName=firefox browserVersion=64 bundle exec rspec spec/capybara_spec.rb
|
33
33
|
- platform='Linux' browserName=chrome browserVersion=48 bundle exec rspec spec/capybara_spec.rb
|
34
34
|
- platform='Linux' browserName=firefox browserVersion=45 bundle exec rspec spec/capybara_spec.rb
|
35
35
|
after_script:
|
data/README.md
CHANGED
@@ -1,79 +1,122 @@
|
|
1
|
-
[![
|
2
|
-
[![
|
3
|
-
[![coverage](https://codeclimate.com/github/wurmlab/sequenceserver/badges/coverage.svg)](https://codeclimate.com/github/wurmlab/sequenceserver)
|
4
|
-
[![gem version](https://badge.fury.io/rb/sequenceserver.svg)](http://rubygems.org/gems/sequenceserver)
|
1
|
+
[![gem version](https://img.shields.io/badge/version-1.0.x%20(old%20stable)-green.svg)](http://rubygems.org/gems/sequenceserver)
|
2
|
+
[![build status](https://secure.travis-ci.org/wurmlab/sequenceserver.png?branch=1.0.x)](https://travis-ci.org/wurmlab/sequenceserver)
|
5
3
|
[![total downloads](http://ruby-gem-downloads-badge.herokuapp.com/sequenceserver?type=total&color=brightgreen)](http://rubygems.org/gems/sequenceserver)
|
6
|
-
|
7
4
|
[![gitter chat](https://badges.gitter.im/gitterHQ/gitter.png)](https://gitter.im/wurmlab/sequenceserver)
|
8
5
|
|
9
|
-
|
6
|
+
**Beta version:**
|
7
|
+
[![new gem version](https://img.shields.io/badge/version-1.1.0%20(new%20beta)-yellowgreen.svg)](http://rubygems.org/gems/sequenceserver) **GitHub Master:** [![build status](https://secure.travis-ci.org/wurmlab/sequenceserver.png)](https://travis-ci.org/wurmlab/sequenceserver)
|
8
|
+
|
9
|
+
|
10
|
+
|
11
|
+
|
12
|
+
<!--[![code climate](https://codeclimate.com/github/wurmlab/sequenceserver/badges/gpa.svg)](https://codeclimate.com/github/wurmlab/sequenceserver)-->
|
13
|
+
<!--[![coverage](https://codeclimate.com/github/wurmlab/sequenceserver/badges/coverage.svg)](https://codeclimate.com/github/wurmlab/sequenceserver)-->
|
14
|
+
<!--[![browser matrix](https://saucelabs.com/browser-matrix/yeban.svg)](https://saucelabs.com/u/yeban)-->
|
10
15
|
|
11
16
|
# SequenceServer - BLAST searching made easy!
|
12
17
|
|
13
|
-
SequenceServer lets you rapidly set up a BLAST+ server with an intuitive user interface for personal or group use.
|
18
|
+
SequenceServer lets you rapidly set up a BLAST+ server with an intuitive user interface for personal or group use.
|
14
19
|
|
15
|
-
|
20
|
+
## Version 1.0.11
|
16
21
|
|
17
|
-
|
22
|
+
- Stable release
|
23
|
+
- Release date: June 2017
|
24
|
+
- Works with BLAST 2.2.30
|
18
25
|
|
19
|
-
|
26
|
+
For installation instructions and how to use SequenceServer please see
|
20
27
|
http://sequenceserver.com.
|
21
28
|
|
29
|
+
If you want to install and use SequenceServer from source, we recommend the
|
30
|
+
use of 'bundler' Ruby gem to install dependencies and to run SequenceServer:
|
31
|
+
|
32
|
+
# Install bundler gem
|
33
|
+
gem install bundler
|
34
|
+
|
35
|
+
# Use bundler to install dependencies
|
36
|
+
cd sequenceserver
|
37
|
+
bundle install --without=development
|
38
|
+
|
39
|
+
# Use bundler command to run SequenceServer
|
40
|
+
bundle exec bin/sequenceserver
|
41
|
+
|
42
|
+
If you use SequenceServer, please cite our preprint:
|
43
|
+
|
44
|
+
> [Priyam A, Woodcroft BJ, Rai V, Munagala A, Moghul I, Ter F, Gibbins MA, Moon H, Leonard G, Rumpf W & Wurm Y. 2015. Sequenceserver: A modern graphical user interface for custom BLAST databases. biorxiv doi: 10.1101/033142](http://www.biorxiv.org/content/early/2015/11/27/033142).
|
45
|
+
|
46
|
+
## Version 1.1.0-beta12
|
47
|
+
|
48
|
+
This is a beta release of SequenceServer 2.0
|
49
|
+
|
50
|
+
Here, we have changed the underlying architecture to persist jobs so that
|
51
|
+
the results can be bookmarked or shared, and to support integration with
|
52
|
+
grid engines such as qsub. Furthermore, the HTML report is now generated
|
53
|
+
in the browser by fetching BLAST results in JSON format from the server.
|
54
|
+
This facilitates the use of existing JavaScript libraries to visualise
|
55
|
+
BLAST results.
|
56
|
+
|
57
|
+
The new beta releases are announced on [Google Group](https://groups.google.com/forum/#!forum/sequenceserver) and on the [GitHub release page](https://github.com/wurmlab/sequenceserver/releases).
|
58
|
+
|
59
|
+
### Install and configure
|
60
|
+
|
22
61
|
To get the latest 1.1.0-beta release, run:
|
23
62
|
|
24
63
|
gem install --pre sequenceserver
|
25
64
|
|
26
|
-
|
27
|
-
|
65
|
+
If you are new to the above command, please consult the 'Install or update'
|
66
|
+
section on our website http://sequenceserver.com.
|
28
67
|
|
29
|
-
|
68
|
+
If you want to install and use the beta versions from source, the process is
|
69
|
+
the same as for the old stable release (instructions above).
|
30
70
|
|
31
|
-
|
71
|
+
### Develop and contribute
|
32
72
|
|
33
|
-
|
34
|
-
Get source code and install dependencies.
|
73
|
+
In addition to [Ruby](https://www.ruby-lang.org/en/) and [RubyGems](https://rubygems.org/), you will need [Node and npm](https://nodejs.org/) if you want to build JavaScript assets, and [CodeClimate](https://codeclimate.com/) to run static code analysis.
|
35
74
|
|
36
|
-
|
37
|
-
|
38
|
-
cd sequenceserver
|
39
|
-
npm install
|
40
|
-
bundle
|
75
|
+
If you want to submit a pull-request, you don't need to build JavaScript assets
|
76
|
+
(we will do it) or to have run CodeClimate.
|
41
77
|
|
42
|
-
|
43
|
-
|
78
|
+
To develop and contribute, you will need to run SequenceServer from source (see
|
79
|
+
previous section).
|
44
80
|
|
45
|
-
|
46
|
-
gem install bundler
|
47
|
-
cd sequenceserver
|
48
|
-
bundle install --without=development
|
49
|
-
|
50
|
-
### Run, test, build
|
81
|
+
#### Workflow commands
|
51
82
|
|
52
83
|
Launch SequenceServer in development mode. In development mode SequenceServer
|
53
84
|
logs verbosely and uses raw front-end files.
|
54
|
-
|
55
|
-
bundle exec bin/sequenceserver -D
|
56
|
-
```
|
85
|
+
|
86
|
+
bundle exec bin/sequenceserver -D
|
57
87
|
|
58
88
|
Run tests:
|
59
|
-
|
60
|
-
bundle exec rspec
|
61
|
-
```
|
89
|
+
|
90
|
+
bundle exec rspec
|
62
91
|
|
63
92
|
Run code style checkers (rubocop, csslint, eslint) -
|
64
|
-
```
|
65
|
-
codeclimate analyze
|
66
|
-
```
|
67
93
|
|
68
|
-
|
94
|
+
codeclimate analyze
|
95
|
+
|
96
|
+
To install JS dependencies to be build JS and CSS bundles:
|
97
|
+
|
98
|
+
npm install
|
99
|
+
|
100
|
+
Build minified JS and CSS bundles:
|
101
|
+
|
102
|
+
npm run-script build
|
103
|
+
|
104
|
+
## Docker builds
|
105
|
+
|
106
|
+
Both the old stable and new beta versions of SequenceServer are available as
|
107
|
+
Docker images.
|
108
|
+
|
69
109
|
```
|
70
|
-
|
110
|
+
# With database fasta files inside a folder named db
|
111
|
+
docker run --rm -ti -p 4567:4567 -v $(pwd)/db:/db wurmlab/sequenceserver
|
71
112
|
```
|
72
113
|
|
73
|
-
|
74
|
-
|
114
|
+
This will use the new beta release of SequenceServer. To use the old stable
|
115
|
+
release, add the version tag to the command:
|
116
|
+
|
117
|
+
```
|
75
118
|
# With database fasta files inside a folder named db
|
76
|
-
docker run --rm -ti -p 4567:4567 -v $(pwd)/db:/db wurmlab/sequenceserver
|
119
|
+
docker run --rm -ti -p 4567:4567 -v $(pwd)/db:/db wurmlab/sequenceserver:1.0.11
|
77
120
|
```
|
78
121
|
|
79
122
|
## Contact
|
data/bin/sequenceserver
CHANGED
@@ -14,8 +14,8 @@ def download_from_url(url)
|
|
14
14
|
archive = File.join('/tmp', File.basename(url))
|
15
15
|
# -ip4 is required to avoid this curl bug http://sourceforge.net/p/curl/bugs/1424/?limit=25
|
16
16
|
# see also https://github.com/yannickwurm/sequenceserver/issues/139
|
17
|
-
cmd = "curl
|
18
|
-
'mkdir -p ~/.sequenceserver && '
|
17
|
+
cmd = "curl --ipv4 -C - #{url} -o #{archive} && " \
|
18
|
+
'mkdir -p ~/.sequenceserver && ' \
|
19
19
|
"tar xvf #{archive} -C ~/.sequenceserver"
|
20
20
|
system(cmd)
|
21
21
|
end
|
@@ -117,6 +117,10 @@ begin
|
|
117
117
|
on 'i', 'interactive',
|
118
118
|
'Run SequenceServer in interactive mode'
|
119
119
|
|
120
|
+
on 'x', 'import=',
|
121
|
+
'Import the xml file',
|
122
|
+
argument: true
|
123
|
+
|
120
124
|
# on 'doctor',
|
121
125
|
# 'Run SequenceServer doctor'
|
122
126
|
|
@@ -162,27 +166,6 @@ begin
|
|
162
166
|
# working SequenceServer installation. We expect to land following
|
163
167
|
# error scenarios either when creating a new SequenceServer (first
|
164
168
|
# time or later), or updating config values using -s CLI option.
|
165
|
-
rescue SequenceServer::CONFIG_FILE_ERROR,
|
166
|
-
SequenceServer::BLAST_DATABASE_ERROR => e
|
167
|
-
|
168
|
-
puts e
|
169
|
-
exit!
|
170
|
-
rescue SequenceServer::ENOENT => e
|
171
|
-
puts e
|
172
|
-
|
173
|
-
puts 'Please consult sequenceserver --help for instructions on how to set the correct values.'
|
174
|
-
exit!
|
175
|
-
rescue SequenceServer::NUM_THREADS_INCORRECT => e
|
176
|
-
puts e
|
177
|
-
|
178
|
-
unless num_threads?
|
179
|
-
puts 'You can set the correct value by running:'
|
180
|
-
puts
|
181
|
-
puts ' sequenceserver -s -n <value>'
|
182
|
-
puts
|
183
|
-
end
|
184
|
-
|
185
|
-
exit!
|
186
169
|
rescue SequenceServer::BLAST_NOT_INSTALLED_OR_NOT_EXECUTABLE,
|
187
170
|
SequenceServer::BLAST_NOT_COMPATIBLE => e
|
188
171
|
|
@@ -198,19 +181,17 @@ begin
|
|
198
181
|
# BLAST+ for her.
|
199
182
|
puts
|
200
183
|
puts <<~MSG
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
Please enter the path to NCBI BLAST+ or press Enter to download.
|
184
|
+
If you have downloaded NCBI BLAST+ already, please enter the path
|
185
|
+
below. Otherwise just press Enter and SequenceServer will download
|
186
|
+
a copy of NCBI BLAST+ for itself.
|
206
187
|
|
207
|
-
Press Ctrl+C to
|
188
|
+
Press Ctrl+C to abort setup.
|
208
189
|
MSG
|
209
190
|
puts
|
210
191
|
response = Readline.readline('>> ').to_s.strip
|
211
192
|
if response.empty?
|
212
193
|
puts
|
213
|
-
puts '
|
194
|
+
puts 'Downloading NCBI BLAST+.'
|
214
195
|
puts "RUBY_PLATFORM #{RUBY_PLATFORM}"
|
215
196
|
puts 'Archive will be extracted in ~/.sequenceserver directory.'
|
216
197
|
puts
|
@@ -252,7 +233,7 @@ begin
|
|
252
233
|
unless File.basename(response) == 'bin'
|
253
234
|
response = File.join(response, 'bin')
|
254
235
|
end
|
255
|
-
fetch_option(:bin).value =
|
236
|
+
fetch_option(:bin).value = response
|
256
237
|
puts
|
257
238
|
end
|
258
239
|
redo
|
@@ -312,6 +293,14 @@ begin
|
|
312
293
|
exit! unless set?
|
313
294
|
end
|
314
295
|
end
|
296
|
+
rescue SequenceServer::ENOENT,
|
297
|
+
SequenceServer::CONFIG_FILE_ERROR,
|
298
|
+
SequenceServer::BLAST_DATABASE_ERROR,
|
299
|
+
SequenceServer::NUM_THREADS_INCORRECT => e
|
300
|
+
# Known errors with clear error message are handled here.
|
301
|
+
|
302
|
+
puts e
|
303
|
+
exit!
|
315
304
|
rescue => e
|
316
305
|
# This will catch any unhandled error and some very special errors.
|
317
306
|
# Ideally we will never hit this block. If we do, there's a bug in
|
@@ -328,7 +317,7 @@ begin
|
|
328
317
|
Error:
|
329
318
|
#{e.backtrace.unshift(e.message).join("\n")}
|
330
319
|
MSG
|
331
|
-
exit
|
320
|
+
exit!
|
332
321
|
end
|
333
322
|
|
334
323
|
if doctor?
|
@@ -375,6 +364,14 @@ begin
|
|
375
364
|
exit
|
376
365
|
end
|
377
366
|
|
367
|
+
if import?
|
368
|
+
xml_file = fetch_option(:import).value
|
369
|
+
params = {:xml => xml_file}
|
370
|
+
job = SequenceServer::BLAST::Job.new(params)
|
371
|
+
puts job.id
|
372
|
+
exit
|
373
|
+
end
|
374
|
+
|
378
375
|
if set?
|
379
376
|
SequenceServer.config.write_config_file
|
380
377
|
exit
|
data/lib/sequenceserver.rb
CHANGED
@@ -1,22 +1,11 @@
|
|
1
1
|
require 'English'
|
2
|
-
require '
|
3
|
-
|
4
|
-
require 'sequenceserver/version'
|
5
|
-
require 'sequenceserver/exceptions'
|
6
|
-
require 'sequenceserver/config'
|
7
|
-
require 'sequenceserver/logger'
|
8
|
-
require 'sequenceserver/server'
|
9
|
-
require 'sequenceserver/sequence'
|
10
|
-
require 'sequenceserver/database'
|
11
|
-
require 'sequenceserver/blast'
|
12
|
-
require 'sequenceserver/routes'
|
13
|
-
require 'sequenceserver/job_remover'
|
14
|
-
require 'sequenceserver/doctor'
|
2
|
+
require 'socket'
|
3
|
+
require 'resolv'
|
15
4
|
|
16
5
|
# Top level module / namespace.
|
17
6
|
module SequenceServer
|
18
7
|
# Use a fixed minimum version of BLAST+
|
19
|
-
BLAST_VERSION = '2.
|
8
|
+
BLAST_VERSION = '2.9.0+'.freeze
|
20
9
|
|
21
10
|
# Default location of configuration file.
|
22
11
|
DEFAULT_CONFIG_FILE = '~/.sequenceserver.conf'.freeze
|
@@ -24,133 +13,98 @@ module SequenceServer
|
|
24
13
|
# Constant for denoting the path ~/.sequenceserver
|
25
14
|
DOTDIR = File.expand_path('~/.sequenceserver').freeze
|
26
15
|
|
16
|
+
# Load nested class, modules, constants, and files that extend SequenceServer
|
17
|
+
# module (e.g. sys).
|
18
|
+
require 'sequenceserver/version'
|
19
|
+
require 'sequenceserver/logger'
|
20
|
+
require 'sequenceserver/config'
|
21
|
+
require 'sequenceserver/server'
|
22
|
+
require 'sequenceserver/routes'
|
23
|
+
require 'sequenceserver/job_remover'
|
24
|
+
require 'sequenceserver/exceptions'
|
25
|
+
require 'sequenceserver/sys'
|
26
|
+
|
27
|
+
# The singleton methods defined below constitute the "runtime" environment of
|
28
|
+
# SequenceServer.
|
27
29
|
class << self
|
30
|
+
# Returns ENV['RACK_ENV']. This environment variable determines if we are
|
31
|
+
# in development on in production mode (default).
|
28
32
|
def environment
|
29
33
|
ENV['RACK_ENV']
|
30
34
|
end
|
31
35
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
def root
|
37
|
-
File.dirname(File.dirname(__FILE__))
|
36
|
+
# Returns true if RACK_ENV is set to 'development'. Raw JS and CSS files
|
37
|
+
# are served in development mode and the logger is made more verbose.
|
38
|
+
def development?
|
39
|
+
environment == 'development'
|
38
40
|
end
|
41
|
+
alias verbose? development?
|
39
42
|
|
43
|
+
# Logger object used in the initialisation routine and throughout the
|
44
|
+
# application.
|
40
45
|
def logger
|
41
|
-
@logger ||=
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
+
@logger ||= case environment
|
47
|
+
when 'development'
|
48
|
+
Logger.new(STDERR, Logger::DEBUG)
|
49
|
+
when 'test'
|
50
|
+
Logger.new(STDERR, Logger::WARN)
|
51
|
+
else
|
52
|
+
Logger.new(STDERR, Logger::INFO)
|
53
|
+
end
|
46
54
|
end
|
47
55
|
|
56
|
+
# SequenceServer initialisation routine.
|
48
57
|
def init(config = {})
|
49
58
|
# Use default config file if caller didn't specify one.
|
50
59
|
config[:config_file] ||= DEFAULT_CONFIG_FILE
|
60
|
+
|
61
|
+
# Initialise global configuration object from the above config hash.
|
51
62
|
@config = Config.new(config)
|
52
63
|
|
53
|
-
|
64
|
+
# When in development mode, cause SequenceServer to terminate if any
|
65
|
+
# thread spawned by the main process raises an unhandled exception. In
|
66
|
+
# production mode the expectation is to log at appropriate severity level
|
67
|
+
# and continue operating.
|
68
|
+
Thread.abort_on_exception = true if development?
|
54
69
|
|
70
|
+
# Now locate binaries, scan databases directory, require any plugin files.
|
55
71
|
init_binaries
|
56
72
|
init_database
|
57
73
|
load_extension
|
74
|
+
|
75
|
+
# The above methods validate bin dir, database dir, and path to plugin
|
76
|
+
# files. Port and host settings don't need to be validated: if running
|
77
|
+
# in self-hosted mode, WEBrick will handle incorrect values and if
|
78
|
+
# running via Apache+Passenger host and port settings are not used.
|
79
|
+
# Let's validate remaining configuration keys next.
|
80
|
+
|
81
|
+
# Validate number of threads to use with BLAST.
|
58
82
|
check_num_threads
|
59
|
-
@job_remover = JobRemover.new(@config[:job_lifetime])
|
60
83
|
|
61
|
-
|
84
|
+
# Doesn't make sense to activate JobRemover when testing. It anyway
|
85
|
+
# keeps stumbling on the mock test jobs that miss a few keys.
|
86
|
+
unless environment == 'test'
|
87
|
+
@job_remover = JobRemover.new(@config[:job_lifetime])
|
88
|
+
end
|
62
89
|
|
63
|
-
#
|
64
|
-
#
|
65
|
-
|
90
|
+
# 'self' is the most meaningful object that can be returned by this
|
91
|
+
# method.
|
92
|
+
self
|
66
93
|
end
|
67
94
|
|
95
|
+
# Holds SequenceServer configuration object for this process. This is
|
96
|
+
# available only after calling SequenceServer.init.
|
68
97
|
attr_reader :config
|
69
98
|
|
70
|
-
#
|
71
|
-
#
|
72
|
-
# 'sys' can write the stdout and/or stderr from a shell command to files, or
|
73
|
-
# return these values.
|
74
|
-
#
|
75
|
-
# 'sys' can get from a failed shell command stdout, stderr, and exit status.
|
76
|
-
#
|
77
|
-
# Supply 'sys' with the shell command and optionally:
|
78
|
-
# dir: A directory to change to for the duration of the execution of
|
79
|
-
# the shell command.
|
80
|
-
# path: A directory to change the PATH environment variable to for the
|
81
|
-
# duration of the execution of the shell command.
|
82
|
-
# stdout: A path to a file to store stdout.
|
83
|
-
# stderr: A path to a file to store stderr.
|
84
|
-
#
|
85
|
-
# Usage:
|
86
|
-
#
|
87
|
-
# sys(command, dir: '/path/to/directory', path: '/path/to/directory',
|
88
|
-
# stdout: '/path/to/stdout_file', stderr: '/path/to/stderr_file')
|
99
|
+
# Rack-interface.
|
89
100
|
#
|
90
|
-
#
|
91
|
-
def
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
# Make temporary files to store output from stdout and stderr.
|
96
|
-
temp_files = {
|
97
|
-
stdout: Tempfile.new('sequenceserver-sys'),
|
98
|
-
stderr: Tempfile.new('sequenceserver-sys')
|
99
|
-
}
|
100
|
-
|
101
|
-
# Log the command we are going to run - use -D option to view.
|
102
|
-
logger.debug("Executing: #{command}")
|
103
|
-
|
104
|
-
# Run command in a child process. This allows us to control PATH
|
105
|
-
# and pwd of the running process.
|
106
|
-
child_pid = fork do
|
107
|
-
# Set the PATH environment variable to the binary directory or
|
108
|
-
# safe directory.
|
109
|
-
ENV['PATH'] = options[:path] if options[:path]
|
110
|
-
|
111
|
-
# Change to the specified directory.
|
112
|
-
Dir.chdir(options[:dir]) if options[:dir] && Dir.exist?(options[:dir])
|
113
|
-
|
114
|
-
# Execute the shell command, redirect stdout and stderr to the
|
115
|
-
# temporary files.
|
116
|
-
exec("#{command} 1>#{temp_files[:stdout].path}" \
|
117
|
-
" 2>#{temp_files[:stderr].path}")
|
118
|
-
end
|
119
|
-
|
120
|
-
# Wait for the termination of the child process.
|
121
|
-
_, status = Process.wait2(child_pid)
|
122
|
-
|
123
|
-
# If a full path was given for stdout and stderr files, move the
|
124
|
-
# temporary files to this path. If the path given does not exist,
|
125
|
-
# create it.
|
126
|
-
channels.each do |channel|
|
127
|
-
filename = options[channel]
|
128
|
-
break unless filename
|
129
|
-
|
130
|
-
# If the given path has a directory component, ensure it exists.
|
131
|
-
file_dir = File.dirname(filename)
|
132
|
-
FileUtils.mkdir_p(file_dir) unless File.directory?(file_dir)
|
133
|
-
|
134
|
-
# Now move the temporary file to the given path.
|
135
|
-
# TODO: don't we need to explicitly close the temp file here?
|
136
|
-
FileUtils.mv(temp_files.delete(channel), filename)
|
137
|
-
end
|
138
|
-
|
139
|
-
# Read the remaining temp files into memory. For large outputs,
|
140
|
-
# the caller should supply a file path to prevent loading the
|
141
|
-
# output in memory.
|
142
|
-
temp_files.each do |channel, tempfile|
|
143
|
-
temp_files[channel] = tempfile.read
|
144
|
-
end
|
145
|
-
|
146
|
-
# Finally, return contents of the remaining temp files if the
|
147
|
-
# command completed successfully or raise CommandFailed error.
|
148
|
-
return temp_files.values if status.success?
|
149
|
-
raise CommandFailed.new(status.exitstatus, **temp_files)
|
101
|
+
# Add our logger to Rack env and let Routes do the rest.
|
102
|
+
def call(env)
|
103
|
+
env['rack.logger'] = logger
|
104
|
+
Routes.call(env)
|
150
105
|
end
|
151
|
-
# rubocop:enable Metrics/CyclomaticComplexity
|
152
106
|
|
153
|
-
# Run SequenceServer
|
107
|
+
# Run SequenceServer using WEBrick.
|
154
108
|
def run
|
155
109
|
check_host
|
156
110
|
Server.run(self)
|
@@ -167,13 +121,19 @@ module SequenceServer
|
|
167
121
|
puts ' Instructions available on http://sequenceserver.com.'
|
168
122
|
end
|
169
123
|
|
124
|
+
# This method is called after WEBrick has bound to the host and port and is
|
125
|
+
# ready to accept connections.
|
170
126
|
def on_start
|
171
127
|
puts '** SequenceServer is ready.'
|
172
128
|
puts " Go to #{server_url} in your browser and start BLASTing!"
|
129
|
+
puts ' To share your setup, please try one of the following: '
|
130
|
+
puts " - http://#{ip_address}:#{config[:port]}"
|
131
|
+
puts " - http://#{hostname}:#{config[:port]}" if hostname
|
173
132
|
puts ' Press CTRL+C to quit.'
|
174
133
|
open_in_browser(server_url)
|
175
134
|
end
|
176
135
|
|
136
|
+
# This method is called when WEBrick is terminated.
|
177
137
|
def on_stop
|
178
138
|
puts
|
179
139
|
puts '** Thank you for using SequenceServer :).'
|
@@ -184,16 +144,8 @@ module SequenceServer
|
|
184
144
|
puts ' custom BLAST databases. biorxiv doi: 10.1101/033142.'
|
185
145
|
end
|
186
146
|
|
187
|
-
#
|
188
|
-
#
|
189
|
-
# Inject our logger in the env and dispatch request to our
|
190
|
-
# controller.
|
191
|
-
def call(env)
|
192
|
-
env['rack.logger'] = logger
|
193
|
-
Routes.call(env)
|
194
|
-
end
|
195
|
-
|
196
|
-
# Run SequenceServer interactively.
|
147
|
+
# This method is invoked by the -i switch to start an IRB shell with
|
148
|
+
# SequenceServer loaded.
|
197
149
|
def irb
|
198
150
|
ARGV.clear
|
199
151
|
require 'irb'
|
@@ -229,7 +181,7 @@ module SequenceServer
|
|
229
181
|
fail ENOENT.new('database dir', config[:database_dir])
|
230
182
|
end
|
231
183
|
|
232
|
-
logger.debug("Will
|
184
|
+
logger.debug("Will look for BLAST+ databases in: #{config[:database_dir]}")
|
233
185
|
Database.scan_databases_dir
|
234
186
|
Database.each do |database|
|
235
187
|
logger.debug("Found #{database.type} database '#{database.title}'" \
|
@@ -287,6 +239,17 @@ module SequenceServer
|
|
287
239
|
"http://#{host}:#{config[:port]}"
|
288
240
|
end
|
289
241
|
|
242
|
+
# Returns a local ip adress
|
243
|
+
def ip_address
|
244
|
+
Socket.ip_address_list.find { |ai| ai.ipv4? && !ai.ipv4_loopback? }.ip_address
|
245
|
+
end
|
246
|
+
|
247
|
+
# Returns machine's hostname based on the local ip;
|
248
|
+
# If hostname cannot be determined then print nothing
|
249
|
+
def hostname
|
250
|
+
Resolv.getname(ip_address) rescue nil
|
251
|
+
end
|
252
|
+
|
290
253
|
# Uses `open` on Mac or `xdg-open` on Linux to opens the search form in
|
291
254
|
# user's default browser. This function is called when SequenceServer
|
292
255
|
# is launched from the terminal. Errors, if any, are silenced.
|