From fd151ade1d9f12157bc0ae25570e982122be0c7d Mon Sep 17 00:00:00 2001 From: BonfaceKilz Date: Wed, 23 Sep 2020 02:23:02 +0300 Subject: Fix failing tests * wqflask/tests/base/test_trait.py: In python2 it's necessary to decode the utf-8 string. --- wqflask/tests/base/test_trait.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wqflask/tests/base/test_trait.py b/wqflask/tests/base/test_trait.py index 53b0d440..960f2c81 100644 --- a/wqflask/tests/base/test_trait.py +++ b/wqflask/tests/base/test_trait.py @@ -96,6 +96,6 @@ class TestRetrieveTraitInfo(unittest.TestCase): test_trait = retrieve_trait_info(trait=mock_trait, dataset=mock_dataset) self.assertEqual(test_trait.abbreviation, - "ファイルを画面毎に見て行くには、次のコマンドを使います。") + "ファイルを画面毎に見て行くには、次のコマンドを使います。".decode('utf-8')) self.assertEqual(test_trait.authors, - "Jane Doe かいと") + "Jane Doe かいと".decode('utf-8')) -- cgit 1.4.1 From d9853ade5a70843c47792e8327301b7b3d5d4a6b Mon Sep 17 00:00:00 2001 From: BonfaceKilz Date: Wed, 23 Sep 2020 03:01:35 +0300 Subject: Fix failing builds * wqflask/wqflask/__init__.py: Move imports from views.py to "__init__.py". Fixes failing build. * wqflask/wqflask/views.py: Ditto. --- wqflask/wqflask/__init__.py | 21 +++++++++++++----- wqflask/wqflask/views.py | 53 ++++++++++++++++++++------------------------- 2 files changed, 40 insertions(+), 34 deletions(-) diff --git a/wqflask/wqflask/__init__.py b/wqflask/wqflask/__init__.py index d729aef5..7ed9c7b8 100644 --- a/wqflask/wqflask/__init__.py +++ b/wqflask/wqflask/__init__.py @@ -12,13 +12,24 @@ logging.basicConfig(level=logging.INFO) app = Flask(__name__) -app.config.from_envvar('GN2_SETTINGS') # See http://flask.pocoo.org/docs/config/#configuring-from-files +# See http://flask.pocoo.org/docs/config/#configuring-from-files # Note no longer use the badly named WQFLASK_OVERRIDES (nyi) - +app.config.from_envvar('GN2_SETTINGS') app.jinja_env.globals.update( - undefined = jinja2.StrictUndefined, - numify = formatting.numify -) + undefined=jinja2.StrictUndefined, + numify=formatting.numify) from wqflask.api import router +from wqflask import group_manager +from wqflask import resource_manager +from wqflask import search_results +from wqflask import export_traits +from wqflask import gsearch +from wqflask import update_search_results +from wqflask import docs +from wqflask import news +from wqflask import db_info +from wqflask import user_login +from wqflask import user_session + import wqflask.views diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index 3d623736..42a10c7a 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -29,15 +29,7 @@ import array import sqlalchemy from wqflask import app from flask import g, Response, request, make_response, render_template, send_from_directory, jsonify, redirect, url_for, send_file -from wqflask import group_manager -from wqflask import resource_manager -from wqflask import search_results -from wqflask import export_traits -from wqflask import gsearch -from wqflask import update_search_results -from wqflask import docs -from wqflask import news -from wqflask import db_info + from wqflask.submit_bnw import get_bnw_input from base.data_set import create_dataset, DataSet # Used by YAML in marker_regression from wqflask.show_trait import show_trait @@ -54,6 +46,12 @@ from wqflask.correlation import corr_scatter_plot from wqflask.wgcna import wgcna_analysis from wqflask.ctl import ctl_analysis from wqflask.snp_browser import snp_browser +from wqflask.search_results import SearchResultPage +from wqflask.export_traits import export_search_results_csv +from wqflask.gsearch import GSearch +from wqflask.update_search_results import GSearch as UpdateGSearch +from wqflask.docs import Docs +from wqflask.db_info import InfoPage from utility import temp_data from utility.tools import SQL_URI,TEMPDIR,USE_REDIS,USE_GN_SERVER,GN_SERVER_URL,GN_VERSION,JS_TWITTER_POST_FETCHER_PATH,JS_GUIX_PATH, CSS_PATH @@ -67,9 +65,6 @@ from utility.benchmark import Bench from pprint import pformat as pf -from wqflask import user_login -from wqflask import user_session - from wqflask import collect from wqflask.database import db_session @@ -216,7 +211,7 @@ def search_page(): logger.info("Skipping Redis cache (USE_REDIS=False)") logger.info("request.args is", request.args) - the_search = search_results.SearchResultPage(request.args) + the_search = SearchResultPage(request.args) result = the_search.__dict__ valid_search = result['search_term_exists'] @@ -234,7 +229,7 @@ def search_page(): @app.route("/gsearch", methods=('GET',)) def gsearchact(): logger.info(request.url) - result = gsearch.GSearch(request.args).__dict__ + result = GSearch(request.args).__dict__ type = request.args['type'] if type == "gene": return render_template("gsearch_gene.html", **result) @@ -245,7 +240,7 @@ def gsearchact(): def gsearch_updating(): logger.info("REQUEST ARGS:", request.values) logger.info(request.url) - result = update_search_results.GSearch(request.args).__dict__ + result = UpdateGSearch(request.args).__dict__ return result['results'] # type = request.args['type'] # if type == "gene": @@ -258,7 +253,7 @@ def docedit(): logger.info(request.url) try: if g.user_session.record['user_email_address'] == "zachary.a.sloan@gmail.com" or g.user_session.record['user_email_address'] == "labwilliams@gmail.com": - doc = docs.Docs(request.args['entry'], request.args) + doc = Docs(request.args['entry'], request.args) return render_template("docedit.html", **doc.__dict__) else: return "You shouldn't be here!" @@ -274,7 +269,7 @@ def generated_file(filename): @app.route("/help") def help(): logger.info(request.url) - doc = docs.Docs("help", request.args) + doc = Docs("help", request.args) return render_template("docs.html", **doc.__dict__) @app.route("/wgcna_setup", methods=('POST',)) @@ -309,54 +304,54 @@ def ctl_results(): @app.route("/news") def news(): - doc = docs.Docs("news", request.args) + doc = Docs("news", request.args) return render_template("docs.html", **doc.__dict__) @app.route("/references") def references(): - doc = docs.Docs("references", request.args) + doc = Docs("references", request.args) return render_template("docs.html", **doc.__dict__) #return render_template("reference.html") @app.route("/intro") def intro(): - doc = docs.Docs("intro", request.args) + doc = Docs("intro", request.args) return render_template("docs.html", **doc.__dict__) @app.route("/policies") def policies(): - doc = docs.Docs("policies", request.args) + doc = Docs("policies", request.args) #return render_template("policies.html") return render_template("docs.html", **doc.__dict__) @app.route("/links") def links(): - #doc = docs.Docs("links", request.args) + #doc = Docs("links", request.args) #return render_template("docs.html", **doc.__dict__) return render_template("links.html") @app.route("/tutorials") def tutorials(): - #doc = docs.Docs("links", request.args) + #doc = Docs("links", request.args) #return render_template("docs.html", **doc.__dict__) return render_template("tutorials.html") @app.route("/credits") def credits(): - #doc = docs.Docs("links", request.args) + #doc = Docs("links", request.args) #return render_template("docs.html", **doc.__dict__) return render_template("credits.html") @app.route("/environments") def environments(): - doc = docs.Docs("environments", request.args) + doc = Docs("environments", request.args) return render_template("docs.html", **doc.__dict__) #return render_template("environments.html", **doc.__dict__) @app.route("/update_text", methods=('POST',)) def update_page(): docs.update_text(request.form) - doc = docs.Docs(request.form['entry_type'], request.form) + doc = Docs(request.form['entry_type'], request.form) return render_template("docs.html", **doc.__dict__) @app.route("/submit_trait") @@ -371,7 +366,7 @@ def create_temp_trait(): #template_vars = submit_trait.SubmitTrait(request.form) - doc = docs.Docs("links") + doc = Docs("links") return render_template("links.html", **doc.__dict__) #return render_template("show_trait.html", **template_vars.__dict__) @@ -426,7 +421,7 @@ def export_traits_csv(): logger.info("In export_traits_csv") logger.info("request.form:", request.form) logger.info(request.url) - file_list = export_traits.export_search_results_csv(request.form) + file_list = export_search_results_csv(request.form) if len(file_list) > 1: now = datetime.datetime.now() @@ -911,7 +906,7 @@ def snp_browser_page(): @app.route("/db_info", methods=('GET',)) def db_info_page(): - template_vars = db_info.InfoPage(request.args) + template_vars = InfoPage(request.args) return render_template("info_page.html", **template_vars.__dict__) -- cgit 1.4.1 From 855558084a538ebdfec0bd43f829ba8d0d314a21 Mon Sep 17 00:00:00 2001 From: BonfaceKilz Date: Wed, 23 Sep 2020 03:05:42 +0300 Subject: Update github action to include mariadb service * .github/workflows/main.yml: Add mariadb service. This makes the build pass because somewhere(because of cyclic imports), a connection to mariadb is required. --- .github/workflows/main.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 4c8db1c4..94b0db75 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -13,6 +13,19 @@ jobs: runs-on: ubuntu-latest container: bonfacekilz/python2-genenetwork2:latest + services: + mariadb: + image: mariadb:latest + ports: + - 3306:3306 + env: + MYSQL_USER: gn2 + MYSQL_PASSWORD: mysql_password + MYSQL_ALLOW_EMPTY_PASSWORD: yes + MYSQL_DATABASE: db_webqtl_s + MYSQL_ROOT_PASSWORD: mysql_password + options: --health-cmd="mysqladmin ping" --health-interval=5s --health-timeout=2s --health-retries=3 + steps: # Use v1 of checkout since v2 fails - name: Checkout Project -- cgit 1.4.1 From 1907457a00f0f7a9f7e74d8955265c8635f03bce Mon Sep 17 00:00:00 2001 From: BonfaceKilz Date: Fri, 25 Sep 2020 03:55:33 +0300 Subject: Update github action * .github/workflows/main.yml: Set up a mariadb and redis within the GH action. (services): Remove mariadb service. --- .github/workflows/main.yml | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 94b0db75..2fd9a886 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -13,32 +13,36 @@ jobs: runs-on: ubuntu-latest container: bonfacekilz/python2-genenetwork2:latest - services: - mariadb: - image: mariadb:latest - ports: - - 3306:3306 - env: - MYSQL_USER: gn2 - MYSQL_PASSWORD: mysql_password - MYSQL_ALLOW_EMPTY_PASSWORD: yes - MYSQL_DATABASE: db_webqtl_s - MYSQL_ROOT_PASSWORD: mysql_password - options: --health-cmd="mysqladmin ping" --health-interval=5s --health-timeout=2s --health-retries=3 - steps: + # First start with mariadb set then checkout. The checkout gives + # the mysqld enough time to start + - name: Set up mariadb + run: | + mysql_install_db --user=mysql --datadir=/usr/local/mysql + # Wait for the mysqld_safe process to start + mysqld_safe --user=mysql --datadir=/usr/local/mysql & + # Use v1 of checkout since v2 fails - name: Checkout Project uses: actions/checkout@v1 - # Redis is required by some of the tests + # Redis is required by some of the tests 6379 - name: Start Redis run: | - redis-server --daemonize yes + /gn2-profile/bin/screen -dmLS redisconn /gn2-profile/bin/redis-server + + # Redis is required by some of the tests 6379 + - name: Bootstrap tables + run: | + mysql -u root -e "SHOW DATABASES;" + mysql -u root -e "CREATE DATABASE db_webqtl_s;" + mysql -u root -e "CREATE USER 'gn2'@'localhost' IDENTIFIED BY 'mysql_password';" + mysql -u root -e "GRANT ALL PRIVILEGES ON *.* TO 'gn2'@'localhost';FLUSH PRIVILEGES;" - name: Run the unit tests run: | - mkdir -p /genotype_files/genotype/json - env GN2_PROFILE=/usr/gn2-profile TMPDIR=/tmp SERVER_PORT=5004 \ - GENENETWORK_FILES=/genotype_files/ bash bin/genenetwork2 \ + env GN2_PROFILE=/gn2-profile \ + TMPDIR=/tmp SERVER_PORT=5004 \ + WEBSERVER_MODE=DEBUG LOG_LEVEL=DEBUG \ + GENENETWORK_FILES=/genotype_files/ bin/genenetwork2 \ etc/default_settings.py -c -m unittest discover -v -- cgit 1.4.1 From 3ec4eb6b831eaa5adcf32a9fca8a60ea229cc1c4 Mon Sep 17 00:00:00 2001 From: BonfaceKilz Date: Fri, 25 Sep 2020 04:09:35 +0300 Subject: Update docs on CI setup with docker * doc/docker-container.org: Update it. --- doc/docker-container.org | 61 +++++++++++++++++++++++++----------------------- 1 file changed, 32 insertions(+), 29 deletions(-) diff --git a/doc/docker-container.org b/doc/docker-container.org index 3c9864c5..ec91824a 100644 --- a/doc/docker-container.org +++ b/doc/docker-container.org @@ -15,57 +15,60 @@ are ran from. Find instructions on how to set docker up inside GUIX [[https://github.com/pjotrp/guix-notes/blob/master/CONTAINERS.org#run-docker][here]]. This document will not get into that. It's assumed that you have a working -dockec setup. +docker setup. The rest of this document outlines how the docker container used in -the CI builds were created. +the CI builds was created. * Creating the Docker Images -First create the image by running: +The general idea is that GUIX is used to generate a set of binaries, +which will be added to a base mariaDB image. + +First create the gn2 tar archive by running: #+begin_src sh # For the Python 2 version: -env GUIX_PACKAGE_PATH="/home/bonface/projects/guix-bioinformatics::/home/bonface/projects/guix-past/modules" \ - ./pre-inst-env guix pack -f docker --no-grafts \ - -S /usr/bin=/bin -S /etc/profile=/etc/profile \ - -S /share/genenetwork2=/share/genenetwork2 \ - -S /share/javascript=/share/javascript \ - -S /lib=/lib \ - -S /usr/gn2-profile=/ \ - coreutils bash genenetwork2 +env GUIX_PACKAGE_PATH="/home/bonface/projects/guix-bioinformatics:/home/bonface/projects/guix-past/modules" \ + ./pre-inst-env guix pack --no-grafts\ + -S /gn2-profile=/ \ + screen genenetwork2 # For the Python 3 version: -env GUIX_PACKAGE_PATH="/home/bonface/projects/guix-bioinformatics::/home/bonface/projects/guix-past/modules" \ - ./pre-inst-env guix pack -f docker --no-grafts \ - -S /usr/bin=/bin -S /etc/profile=/etc/profile \ - -S /share/genenetwork2=/share/genenetwork2 \ - -S /share/javascript=/share/javascript \ - -S /lib=/lib \ - -S /usr/gn2-profile=/ \ - coreutils bash python3-genenetwork2 +env GUIX_PACKAGE_PATH="/home/bonface/projects/guix-bioinformatics:/home/bonface/projects/guix-past/modules" \ + ./pre-inst-env guix pack --no-grafts\ + -S /gn2-profile=/ \ + screen python3-genenetwork2 #+end_src The output will look something similar to: -: /gnu/store/dj1xh19jq1l9vwq24w3nay2954x0wabb-docker-pack.tar.gz +: /gnu/store/x3m77vwaqcwba24p5s4lrb7w2ii16lj9-tarball-pack.tar.gz + +Now create a folder from which will host the following dockerfile. You +can name this file Dockerfile. Note that mariadb is the base image +since it already has mariadb installed for us. + +#+begin_src conf :mkdirp yes :tangle ~/docker/Dockerfile +FROM mariadb:latest -Load the docker image by running: +COPY ./gn2.tar.gz /tmp/gn2.tar.gz +RUN tar -xzf /tmp/gn2.tar.gz -C / && rm -f /tmp/gn2.tar.gz && \ + mkdir -p /usr/local/mysql /genotype_files/genotype/json +#+end_src -: docker load --input /gnu/store/dj1xh19jq1l9vwq24w3nay2954x0wabb-docker-pack.tar.gz +Build the image(Note the fullstop at the end): -Results look something similar to: +: sudo docker build -t python2-genenetwork2:latest -f Dockerfile . -#+begin_export ascii -a93f52b7f565: Loading layer 3.174GB/3.174GB -Loaded image: coreutils-genenetwork2:latest -#+end_export +To load the image interactively you've just created: + +: docker run -ti "python2-genenetwork2:latest" bash Assuming you have a docker instance running, you could always run commands in it e.g: -: docker run "coreutils-genenetwork2:latest" python --version - +: docker run "python2-genenetwork2:latest" python --version * Pushing to DockerHub -- cgit 1.4.1 From e247f43bf9bc31164948760694ff796bb469ae4c Mon Sep 17 00:00:00 2001 From: BonfaceKilz Date: Mon, 28 Sep 2020 02:25:58 +0300 Subject: Update trait tests * wqflask/tests/base/test_trait.py (test_retrieve_trait_info_with_non_empty_lrs): Check trait.LRS_score_repr is set correctly if trait.lrs is None. (test_retrieve_trait_info_with_empty_lrs_field): Check trait.LRS_score_repr and test_trait.LRS_location_repr is set correctly if trait.lrs is None. (test_retrieve_trait_info_with_empty_chr_field): Check test_trait.LRS_score_repr and test_trait.LRS_location_repr is set correctly if trait.locus is None. --- wqflask/tests/base/test_trait.py | 134 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) diff --git a/wqflask/tests/base/test_trait.py b/wqflask/tests/base/test_trait.py index 960f2c81..1a3820f2 100644 --- a/wqflask/tests/base/test_trait.py +++ b/wqflask/tests/base/test_trait.py @@ -99,3 +99,137 @@ class TestRetrieveTraitInfo(unittest.TestCase): "ファイルを画面毎に見て行くには、次のコマンドを使います。".decode('utf-8')) self.assertEqual(test_trait.authors, "Jane Doe かいと".decode('utf-8')) + + @mock.patch('base.trait.requests.get') + @mock.patch('base.trait.g') + @mock.patch('base.trait.get_resource_id') + def test_retrieve_trait_info_with_non_empty_lrs(self, + resource_id_mock, + g_mock, + requests_mock): + """Test """ + resource_id_mock.return_value = 1 + g_mock.db.execute.return_value.fetchone = mock.Mock() + g_mock.db.execute.return_value.fetchone.side_effect = [ + [1, 2, 3, 4], # trait_info = g.db.execute(query).fetchone() + [1, 2.37, 3, 4, 5], # trait_qtl = g.db.execute(query).fetchone() + [2.7333, 2.1204] # trait_info = g.db.execute(query).fetchone() + ] + requests_mock.return_value = None + + mock_dataset = mock.MagicMock() + type(mock_dataset).display_fields = mock.PropertyMock( + return_value=["a", "b", "c", "d"]) + type(mock_dataset).type = "ProbeSet" + type(mock_dataset).name = "RandomName" + + mock_trait = MockTrait( + dataset=mock_dataset, + pre_publication_description="test_string" + ) + trait_attrs = { + "description": "some description", + "probe_target_description": "some description", + "cellid": False, + "chr": 2.733, + "mb": 2.1204 + } + + for key, val in list(trait_attrs.items()): + setattr(mock_trait, key, val) + test_trait = retrieve_trait_info(trait=mock_trait, + dataset=mock_dataset, + get_qtl_info=True) + self.assertEqual(test_trait.LRS_score_repr, + "2.4") + + @mock.patch('base.trait.requests.get') + @mock.patch('base.trait.g') + @mock.patch('base.trait.get_resource_id') + def test_retrieve_trait_info_with_empty_lrs_field(self, + resource_id_mock, + g_mock, + requests_mock): + """Test retrieve trait info with empty lrs field""" + resource_id_mock.return_value = 1 + g_mock.db.execute.return_value.fetchone = mock.Mock() + g_mock.db.execute.return_value.fetchone.side_effect = [ + [1, 2, 3, 4], # trait_info = g.db.execute(query).fetchone() + [1, None, 3, 4, 5], # trait_qtl = g.db.execute(query).fetchone() + [2, 3] # trait_info = g.db.execute(query).fetchone() + ] + requests_mock.return_value = None + + mock_dataset = mock.MagicMock() + type(mock_dataset).display_fields = mock.PropertyMock( + return_value=["a", "b", "c", "d"]) + type(mock_dataset).type = "ProbeSet" + type(mock_dataset).name = "RandomName" + + mock_trait = MockTrait( + dataset=mock_dataset, + pre_publication_description="test_string" + ) + trait_attrs = { + "description": "some description", + "probe_target_description": "some description", + "cellid": False, + "chr": 2.733, + "mb": 2.1204 + } + + for key, val in list(trait_attrs.items()): + setattr(mock_trait, key, val) + test_trait = retrieve_trait_info(trait=mock_trait, + dataset=mock_dataset, + get_qtl_info=True) + self.assertEqual(test_trait.LRS_score_repr, + "N/A") + self.assertEqual(test_trait.LRS_location_repr, + "Chr2: 3.000000") + + @mock.patch('base.trait.requests.get') + @mock.patch('base.trait.g') + @mock.patch('base.trait.get_resource_id') + def test_retrieve_trait_info_with_empty_chr_field(self, + resource_id_mock, + g_mock, + requests_mock): + """Test retrieve trait info with empty chr field""" + resource_id_mock.return_value = 1 + g_mock.db.execute.return_value.fetchone = mock.Mock() + g_mock.db.execute.return_value.fetchone.side_effect = [ + [1, 2, 3, 4], # trait_info = g.db.execute(query).fetchone() + [1, 2, 3, 4, 5], # trait_qtl = g.db.execute(query).fetchone() + [None, 3] # trait_info = g.db.execute(query).fetchone() + ] + + requests_mock.return_value = None + + mock_dataset = mock.MagicMock() + type(mock_dataset).display_fields = mock.PropertyMock( + return_value=["a", "b", "c", "d"]) + type(mock_dataset).type = "ProbeSet" + type(mock_dataset).name = "RandomName" + + mock_trait = MockTrait( + dataset=mock_dataset, + pre_publication_description="test_string" + ) + trait_attrs = { + "description": "some description", + "probe_target_description": "some description", + "cellid": False, + "chr": 2.733, + "mb": 2.1204 + } + + for key, val in list(trait_attrs.items()): + setattr(mock_trait, key, val) + test_trait = retrieve_trait_info(trait=mock_trait, + dataset=mock_dataset, + get_qtl_info=True) + self.assertEqual(test_trait.LRS_score_repr, + "N/A") + self.assertEqual(test_trait.LRS_location_repr, + "N/A") -- cgit 1.4.1 From 312835014d8d243c72f3520bb116eb3c36cd6b85 Mon Sep 17 00:00:00 2001 From: BonfaceKilz Date: Mon, 28 Sep 2020 02:33:09 +0300 Subject: Convert None to "" in if statement * wqflask/base/trait.py: Fixes error parsing error: "(GeneNetwork error: float argument required, not NoneType)" --- wqflask/base/trait.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/wqflask/base/trait.py b/wqflask/base/trait.py index 7666348e..bdd9c3d6 100644 --- a/wqflask/base/trait.py +++ b/wqflask/base/trait.py @@ -599,12 +599,11 @@ def retrieve_trait_info(trait, dataset, get_qtl_info=False): trait.locus = trait.locus_chr = trait.locus_mb = trait.additive = "" else: trait.locus = trait.lrs = trait.additive = "" - - if (dataset.type == 'Publish' or dataset.type == "ProbeSet") and trait.locus_chr != "" and trait.locus_mb != "": + if (dataset.type == 'Publish' or dataset.type == "ProbeSet") and str(trait.locus_chr or "") != "" and str(trait.locus_mb or "") != "": trait.LRS_location_repr = LRS_location_repr = 'Chr%s: %.6f' % (trait.locus_chr, float(trait.locus_mb)) - if trait.lrs != "": + if str(trait.lrs or "") != "": trait.LRS_score_repr = LRS_score_repr = '%3.1f' % trait.lrs else: raise KeyError, `trait.name`+' information is not found in the database.' - return trait \ No newline at end of file + return trait -- cgit 1.4.1 From d34258bed3ef13350499414100401df3bf08a105 Mon Sep 17 00:00:00 2001 From: BonfaceKilz Date: Mon, 28 Sep 2020 18:08:34 +0300 Subject: Fix casting error * wqflask/base/trait.py (retrieve_trait_info): If the description_string or discription_display value return a None object, evaluate to an empty string. Fixes errors related to *len(None)*. --- wqflask/base/trait.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/wqflask/base/trait.py b/wqflask/base/trait.py index bdd9c3d6..8f8b5b70 100644 --- a/wqflask/base/trait.py +++ b/wqflask/base/trait.py @@ -507,13 +507,14 @@ def retrieve_trait_info(trait, dataset, get_qtl_info=False): description_string = unicode(str(trait.description).strip(codecs.BOM_UTF8), 'utf-8') target_string = unicode(str(trait.probe_target_description).strip(codecs.BOM_UTF8), 'utf-8') - if len(description_string) > 1 and description_string != 'None': + if str(description_string or "") != "" and description_string != 'None': description_display = description_string else: description_display = trait.symbol - if (len(description_display) > 1 and description_display != 'N/A' and - len(target_string) > 1 and target_string != 'None'): + if (str(description_display or "") != "" and + description_display != 'N/A' and + str(target_string or "") != "" and target_string != 'None'): description_display = description_display + '; ' + target_string.strip() # Save it for the jinja2 template -- cgit 1.4.1 From a7316acfe9110ee8b7c1482d3eae613aa5d75d1a Mon Sep 17 00:00:00 2001 From: zsloan Date: Mon, 28 Sep 2020 13:37:35 -0500 Subject: Changed add to collection to open the collection in a new tab/page so the results on the initial page aren't lost * wqflask/wqflask/static/new/javascript/search_results.js - Changed the add to collection method name to "add_to_collection" because it was previously "add" which is a terrible method name * wqflask/wqflask/templates/collections/add.html - Added target="_blank" to the add to collection form so it will open in a new tab/window --- wqflask/wqflask/static/new/javascript/search_results.js | 4 ++-- wqflask/wqflask/templates/collections/add.html | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/wqflask/wqflask/static/new/javascript/search_results.js b/wqflask/wqflask/static/new/javascript/search_results.js index 685d6291..61134a88 100644 --- a/wqflask/wqflask/static/new/javascript/search_results.js +++ b/wqflask/wqflask/static/new/javascript/search_results.js @@ -93,7 +93,7 @@ $(function() { }); - add = function() { + add_to_collection = function() { var traits; traits = $("#trait_table input:checked").map(function() { return $(this).val(); @@ -250,7 +250,7 @@ $(function() { $("#select_all").click(select_all); $("#deselect_all").click(deselect_all); $("#invert").click(invert); - $("#add").click(add); + $("#add").click(add_to_collection); $("#submit_bnw").click(submit_bnw); $("#export_traits").click(export_traits); $('.trait_checkbox, .btn').click(change_buttons); diff --git a/wqflask/wqflask/templates/collections/add.html b/wqflask/wqflask/templates/collections/add.html index 825dfb84..62b6abb5 100644 --- a/wqflask/wqflask/templates/collections/add.html +++ b/wqflask/wqflask/templates/collections/add.html @@ -5,7 +5,7 @@ or add to an existing collection.