From 121ecdeb9d923e9964969007ac56210fb17e2c4d Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Wed, 10 Jan 2018 15:05:03 +0300 Subject: Add configuration variables for external services * Add configuration variables for GitHub and ORCID which will be used by the system to allow users to login. --- wqflask/utility/tools.py | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'wqflask/utility') diff --git a/wqflask/utility/tools.py b/wqflask/utility/tools.py index d3113302..e7a673ad 100644 --- a/wqflask/utility/tools.py +++ b/wqflask/utility/tools.py @@ -251,6 +251,10 @@ assert_dir(JS_GUIX_PATH) JS_GN_PATH = get_setting('JS_GN_PATH') # assert_dir(JS_GN_PATH) +GITHUB_AUTH_URL = get_setting('GITHUB_AUTH_URL') +ORCID_AUTH_URL = get_setting('ORCID_AUTH_URL') +ORCID_TOKEN_URL = get_setting('ORCID_TOKEN_URL') + PYLMM_COMMAND = app_set("PYLMM_COMMAND",pylmm_command()) GEMMA_COMMAND = app_set("GEMMA_COMMAND",gemma_command()) assert(GEMMA_COMMAND is not None) -- cgit v1.2.3 From ccdf9b81147fba35e4df704f39026af6a64e3a20 Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Fri, 12 Jan 2018 18:01:11 +0300 Subject: Add client_id and client_secret configurations * Provide the OAuth2 client_id and client_secret values in configuration variables. --- wqflask/utility/tools.py | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'wqflask/utility') diff --git a/wqflask/utility/tools.py b/wqflask/utility/tools.py index e7a673ad..330344d1 100644 --- a/wqflask/utility/tools.py +++ b/wqflask/utility/tools.py @@ -251,7 +251,11 @@ assert_dir(JS_GUIX_PATH) JS_GN_PATH = get_setting('JS_GN_PATH') # assert_dir(JS_GN_PATH) +GITHUB_CLIENT_ID = get_setting('GITHUB_CLIENT_ID') +GITHUB_CLIENT_SECRET = get_setting('GITHUB_CLIENT_SECRET') GITHUB_AUTH_URL = get_setting('GITHUB_AUTH_URL') +ORCID_CLIENT_ID = get_setting('ORCID_CLIENT_ID') +ORCID_CLIENT_SECRET = get_setting('ORCID_CLIENT_SECRET') ORCID_AUTH_URL = get_setting('ORCID_AUTH_URL') ORCID_TOKEN_URL = get_setting('ORCID_TOKEN_URL') -- cgit v1.2.3 From d0f071a3871a2bcbb2c5170996a4afb145c21f9c Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Fri, 12 Jan 2018 18:05:45 +0300 Subject: Add elasticsearch_tools module * Collect variables and functions for using the elasticsearch system in a separate module. --- wqflask/utility/elasticsearch_tools.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 wqflask/utility/elasticsearch_tools.py (limited to 'wqflask/utility') diff --git a/wqflask/utility/elasticsearch_tools.py b/wqflask/utility/elasticsearch_tools.py new file mode 100644 index 00000000..bc7bb240 --- /dev/null +++ b/wqflask/utility/elasticsearch_tools.py @@ -0,0 +1,22 @@ +from elasticsearch import Elasticsearch, TransportError +from utility.tools import ELASTICSEARCH_HOST, ELASTICSEARCH_PORT + +es = Elasticsearch([{ + "host": ELASTICSEARCH_HOST + , "port": ELASTICSEARCH_PORT +}]) + +def get_user_by_unique_column(column_name, column_value): + user_details = None + try: + response = es.search( + index = "users" + , doc_type = "local" + , body = { + "query": { "match": { column_name: column_value } } + }) + if len(response["hits"]["hits"]) > 0: + user_details = response["hits"]["hits"][0]["_source"] + except TransportError as te: + pass + return user_details -- cgit v1.2.3 From 98de7bf9649115b67a13018454a2c3766be1fc12 Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Fri, 19 Jan 2018 10:38:04 +0300 Subject: Add save_user() function * On successful login via OAuth2, save the details of the user in elasticsearch store, to avoid hitting the external provider for the basic details. --- wqflask/utility/elasticsearch_tools.py | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'wqflask/utility') diff --git a/wqflask/utility/elasticsearch_tools.py b/wqflask/utility/elasticsearch_tools.py index bc7bb240..74db489b 100644 --- a/wqflask/utility/elasticsearch_tools.py +++ b/wqflask/utility/elasticsearch_tools.py @@ -20,3 +20,10 @@ def get_user_by_unique_column(column_name, column_value): except TransportError as te: pass return user_details + +def save_user(user, user_id, index="users", doc_type="local"): + es = Elasticsearch([{ + "host": ELASTICSEARCH_HOST + , "port": ELASTICSEARCH_PORT + }]) + es.create(index, doc_type, body=user, id=user_id) -- cgit v1.2.3 From 38c85f80090322b2dc9278812b7b1f011bb35390 Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Fri, 19 Jan 2018 10:41:41 +0300 Subject: Add more configuration variables. * Add configurations for elasticsearch and github. --- wqflask/utility/tools.py | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'wqflask/utility') diff --git a/wqflask/utility/tools.py b/wqflask/utility/tools.py index 330344d1..ea7b8120 100644 --- a/wqflask/utility/tools.py +++ b/wqflask/utility/tools.py @@ -254,11 +254,15 @@ JS_GN_PATH = get_setting('JS_GN_PATH') GITHUB_CLIENT_ID = get_setting('GITHUB_CLIENT_ID') GITHUB_CLIENT_SECRET = get_setting('GITHUB_CLIENT_SECRET') GITHUB_AUTH_URL = get_setting('GITHUB_AUTH_URL') +GITHUB_API_URL = get_setting('GITHUB_API_URL') ORCID_CLIENT_ID = get_setting('ORCID_CLIENT_ID') ORCID_CLIENT_SECRET = get_setting('ORCID_CLIENT_SECRET') ORCID_AUTH_URL = get_setting('ORCID_AUTH_URL') ORCID_TOKEN_URL = get_setting('ORCID_TOKEN_URL') +ELASTICSEARCH_HOST = get_setting('ELASTICSEARCH_HOST') +ELASTICSEARCH_PORT = get_setting('ELASTICSEARCH_PORT') + PYLMM_COMMAND = app_set("PYLMM_COMMAND",pylmm_command()) GEMMA_COMMAND = app_set("GEMMA_COMMAND",gemma_command()) assert(GEMMA_COMMAND is not None) -- cgit v1.2.3 From 7959930d3276b5317d933a428a3c2f9ea8f7ddf4 Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Fri, 19 Jan 2018 12:00:04 +0300 Subject: Delay after save for indexing * Elasticsearch need a short delay after adding document for it to index the document for subsequent access. --- wqflask/utility/elasticsearch_tools.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'wqflask/utility') diff --git a/wqflask/utility/elasticsearch_tools.py b/wqflask/utility/elasticsearch_tools.py index 74db489b..c2c999ea 100644 --- a/wqflask/utility/elasticsearch_tools.py +++ b/wqflask/utility/elasticsearch_tools.py @@ -22,8 +22,10 @@ def get_user_by_unique_column(column_name, column_value): return user_details def save_user(user, user_id, index="users", doc_type="local"): + from time import sleep es = Elasticsearch([{ "host": ELASTICSEARCH_HOST , "port": ELASTICSEARCH_PORT }]) es.create(index, doc_type, body=user, id=user_id) + sleep(1) # Delay 1 second to allow indexing -- cgit v1.2.3 From 49067569b4236da81013f30e9382d77277a1cd75 Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Fri, 19 Jan 2018 13:00:51 +0300 Subject: Update configurations * Have the authorisation URLs build up from the client id and client secret values. --- wqflask/utility/tools.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/tools.py b/wqflask/utility/tools.py index ea7b8120..c96b3699 100644 --- a/wqflask/utility/tools.py +++ b/wqflask/utility/tools.py @@ -253,11 +253,11 @@ JS_GN_PATH = get_setting('JS_GN_PATH') GITHUB_CLIENT_ID = get_setting('GITHUB_CLIENT_ID') GITHUB_CLIENT_SECRET = get_setting('GITHUB_CLIENT_SECRET') -GITHUB_AUTH_URL = get_setting('GITHUB_AUTH_URL') +GITHUB_AUTH_URL = "https://github.com/login/oauth/authorize?client_id="+GITHUB_CLIENT_ID+"&client_secret="+GITHUB_CLIENT_SECRET GITHUB_API_URL = get_setting('GITHUB_API_URL') ORCID_CLIENT_ID = get_setting('ORCID_CLIENT_ID') ORCID_CLIENT_SECRET = get_setting('ORCID_CLIENT_SECRET') -ORCID_AUTH_URL = get_setting('ORCID_AUTH_URL') +ORCID_AUTH_URL = "https://sandbox.orcid.org/oauth/authorize?response_type=code&scope=/authenticate&show_login=true&client_id="+ORCID_CLIENT_ID+"&client_secret="+ORCID_CLIENT_SECRET ORCID_TOKEN_URL = get_setting('ORCID_TOKEN_URL') ELASTICSEARCH_HOST = get_setting('ELASTICSEARCH_HOST') -- cgit v1.2.3 From 3029ae6ffe66f083f02d35d39e09500f76977197 Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Tue, 30 Jan 2018 12:23:31 +0300 Subject: Set to None if no value provided * Add a method to set the configuration variables to None if the configuration values are not provided at startup or in the configuration files. The system already checks for these values, and if they are absent, it simply fails to display the OAuth service as available for use to login. --- wqflask/utility/tools.py | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/tools.py b/wqflask/utility/tools.py index c96b3699..a67a930b 100644 --- a/wqflask/utility/tools.py +++ b/wqflask/utility/tools.py @@ -251,17 +251,28 @@ assert_dir(JS_GUIX_PATH) JS_GN_PATH = get_setting('JS_GN_PATH') # assert_dir(JS_GN_PATH) -GITHUB_CLIENT_ID = get_setting('GITHUB_CLIENT_ID') -GITHUB_CLIENT_SECRET = get_setting('GITHUB_CLIENT_SECRET') -GITHUB_AUTH_URL = "https://github.com/login/oauth/authorize?client_id="+GITHUB_CLIENT_ID+"&client_secret="+GITHUB_CLIENT_SECRET -GITHUB_API_URL = get_setting('GITHUB_API_URL') -ORCID_CLIENT_ID = get_setting('ORCID_CLIENT_ID') -ORCID_CLIENT_SECRET = get_setting('ORCID_CLIENT_SECRET') -ORCID_AUTH_URL = "https://sandbox.orcid.org/oauth/authorize?response_type=code&scope=/authenticate&show_login=true&client_id="+ORCID_CLIENT_ID+"&client_secret="+ORCID_CLIENT_SECRET -ORCID_TOKEN_URL = get_setting('ORCID_TOKEN_URL') - -ELASTICSEARCH_HOST = get_setting('ELASTICSEARCH_HOST') -ELASTICSEARCH_PORT = get_setting('ELASTICSEARCH_PORT') +def get_setting_safe(setting): + try: + return get_setting(setting) + except: + print("Could not find the setting '", setting, "'. Continuing with value unset") + return None + +GITHUB_CLIENT_ID = get_setting_safe('GITHUB_CLIENT_ID') +GITHUB_CLIENT_SECRET = get_setting_safe('GITHUB_CLIENT_SECRET') +GITHUB_AUTH_URL = None +if GITHUB_CLIENT_ID and GITHUB_CLIENT_SECRET: + GITHUB_AUTH_URL = "https://github.com/login/oauth/authorize?client_id="+GITHUB_CLIENT_ID+"&client_secret="+GITHUB_CLIENT_SECRET +GITHUB_API_URL = get_setting_safe('GITHUB_API_URL') +ORCID_CLIENT_ID = get_setting_safe('ORCID_CLIENT_ID') +ORCID_CLIENT_SECRET = get_setting_safe('ORCID_CLIENT_SECRET') +ORCID_AUTH_URL = None +if ORCID_CLIENT_ID and ORCID_CLIENT_SECRET: + ORCID_AUTH_URL = "https://sandbox.orcid.org/oauth/authorize?response_type=code&scope=/authenticate&show_login=true&client_id="+ORCID_CLIENT_ID+"&client_secret="+ORCID_CLIENT_SECRET +ORCID_TOKEN_URL = get_setting_safe('ORCID_TOKEN_URL') + +ELASTICSEARCH_HOST = get_setting_safe('ELASTICSEARCH_HOST') +ELASTICSEARCH_PORT = get_setting_safe('ELASTICSEARCH_PORT') PYLMM_COMMAND = app_set("PYLMM_COMMAND",pylmm_command()) GEMMA_COMMAND = app_set("GEMMA_COMMAND",gemma_command()) -- cgit v1.2.3 From e0295504fb0097db394e99568339e24a71406123 Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Tue, 30 Jan 2018 13:07:58 +0300 Subject: Fail safely if elasticsearch is down or unconfigured * If elasticsearch server is down, or the configuration variables are not provided at startup or in a configuration file, then do not allow the system to simply crash, but instead, inform the user that they cannot use the services that depend on elasticsearch to be running. --- wqflask/utility/elasticsearch_tools.py | 16 ++++++++------ .../wqflask/templates/new_security/login_user.html | 25 ++++++++++++++++++---- wqflask/wqflask/user_manager.py | 6 +++++- 3 files changed, 36 insertions(+), 11 deletions(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/elasticsearch_tools.py b/wqflask/utility/elasticsearch_tools.py index c2c999ea..8b8ad9cc 100644 --- a/wqflask/utility/elasticsearch_tools.py +++ b/wqflask/utility/elasticsearch_tools.py @@ -1,10 +1,14 @@ -from elasticsearch import Elasticsearch, TransportError -from utility.tools import ELASTICSEARCH_HOST, ELASTICSEARCH_PORT +es = None +try: + from elasticsearch import Elasticsearch, TransportError + from utility.tools import ELASTICSEARCH_HOST, ELASTICSEARCH_PORT -es = Elasticsearch([{ - "host": ELASTICSEARCH_HOST - , "port": ELASTICSEARCH_PORT -}]) + es = Elasticsearch([{ + "host": ELASTICSEARCH_HOST + , "port": ELASTICSEARCH_PORT + }]) if (ELASTICSEARCH_HOST and ELASTICSEARCH_PORT) else None +except: + es = None def get_user_by_unique_column(column_name, column_value): user_details = None diff --git a/wqflask/wqflask/templates/new_security/login_user.html b/wqflask/wqflask/templates/new_security/login_user.html index 15f0a27e..0dae3503 100644 --- a/wqflask/wqflask/templates/new_security/login_user.html +++ b/wqflask/wqflask/templates/new_security/login_user.html @@ -16,7 +16,14 @@

Don't have an account?

- Create a new account + {% if es_server: %} + Create a new account + {% else: %} +
+

You cannot create an account at this moment.
+ Please try again later.

+
+ {% endif %}

Login with external services

@@ -31,13 +38,17 @@ Login with ORCID {% endif %} - -
+ {% else: %} +
+

You cannot login with external services at this time.
+ Please try again later.

+
{% endif %} +

Already have an account? Sign in here.

- + {% if es_server: %}
@@ -75,6 +86,12 @@
+ {% else: %} +
+

You cannot login at this moment using your GeneNetwork account.
+ Please try again later.

+
+ {% endif %} diff --git a/wqflask/wqflask/user_manager.py b/wqflask/wqflask/user_manager.py index 4322945b..772d6c83 100644 --- a/wqflask/wqflask/user_manager.py +++ b/wqflask/wqflask/user_manager.py @@ -585,13 +585,17 @@ class LoginUser(object): logger.debug("in login params are:", params) if not params: from utility.tools import GITHUB_AUTH_URL, ORCID_AUTH_URL + from utility.elasticsearch_tools import es external_login = None if GITHUB_AUTH_URL or ORCID_AUTH_URL: external_login={ "github": GITHUB_AUTH_URL, "orcid": ORCID_AUTH_URL } - return render_template("new_security/login_user.html", external_login=external_login) + return render_template( + "new_security/login_user.html" + , external_login=external_login + , es_server=es) else: user_details = get_user_by_unique_column("email_address", params["email_address"]) user = None -- cgit v1.2.3 From d0530d880e11dba4cd6dd35e3d04ac4541c11722 Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Mon, 5 Feb 2018 17:47:29 +0300 Subject: Add SMTP configuration variables * Add configuration variables to enable the system connect to the configured SMTP server to send out emails. --- wqflask/utility/tools.py | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'wqflask/utility') diff --git a/wqflask/utility/tools.py b/wqflask/utility/tools.py index a67a930b..005f9b0f 100644 --- a/wqflask/utility/tools.py +++ b/wqflask/utility/tools.py @@ -274,6 +274,10 @@ ORCID_TOKEN_URL = get_setting_safe('ORCID_TOKEN_URL') ELASTICSEARCH_HOST = get_setting_safe('ELASTICSEARCH_HOST') ELASTICSEARCH_PORT = get_setting_safe('ELASTICSEARCH_PORT') +SMTP_CONNECT = get_setting_safe('SMTP_CONNECT') +SMTP_USERNAME = get_setting_safe('SMTP_USERNAME') +SMTP_PASSWORD = get_setting_safe('SMTP_PASSWORD') + PYLMM_COMMAND = app_set("PYLMM_COMMAND",pylmm_command()) GEMMA_COMMAND = app_set("GEMMA_COMMAND",gemma_command()) assert(GEMMA_COMMAND is not None) -- cgit v1.2.3 From a494260a8f9cf0e3ecf0c428bb70d4066623f1dd Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Mon, 5 Feb 2018 20:01:45 +0300 Subject: Refactor common items to more generic methods. * Refactor code that can be used in more than one place to a more generic method/function that's called by other methods --- wqflask/utility/elasticsearch_tools.py | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/elasticsearch_tools.py b/wqflask/utility/elasticsearch_tools.py index 8b8ad9cc..ea636b2e 100644 --- a/wqflask/utility/elasticsearch_tools.py +++ b/wqflask/utility/elasticsearch_tools.py @@ -11,25 +11,27 @@ except: es = None def get_user_by_unique_column(column_name, column_value): - user_details = None + return get_item_by_unique_column(column_name, column_value, index="users", doc_type="local") + +def save_user(user, user_id): + es_save_data("users", "local", user, user_id) + +def get_item_by_unique_column(column_name, column_value, index, doc_type): + item_details = None try: response = es.search( - index = "users" - , doc_type = "local" + index = index + , doc_type = doc_type , body = { "query": { "match": { column_name: column_value } } }) if len(response["hits"]["hits"]) > 0: - user_details = response["hits"]["hits"][0]["_source"] + item_details = response["hits"]["hits"][0]["_source"] except TransportError as te: pass - return user_details + return item_details -def save_user(user, user_id, index="users", doc_type="local"): +def es_save_data(index, doc_type, data_item, data_id,): from time import sleep - es = Elasticsearch([{ - "host": ELASTICSEARCH_HOST - , "port": ELASTICSEARCH_PORT - }]) - es.create(index, doc_type, body=user, id=user_id) + es.create(index, doc_type, body=data_item, id=data_id) sleep(1) # Delay 1 second to allow indexing -- cgit v1.2.3 From 49f3111bcac8d69dea52ff75bdd39e01e99c2f02 Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Fri, 9 Feb 2018 10:11:21 +0300 Subject: Add check for elasticsearch * Add some extra checks to ensure that elasticsearch is running before presenting the UI to the user. --- wqflask/utility/elasticsearch_tools.py | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'wqflask/utility') diff --git a/wqflask/utility/elasticsearch_tools.py b/wqflask/utility/elasticsearch_tools.py index ea636b2e..a0383033 100644 --- a/wqflask/utility/elasticsearch_tools.py +++ b/wqflask/utility/elasticsearch_tools.py @@ -7,6 +7,10 @@ try: "host": ELASTICSEARCH_HOST , "port": ELASTICSEARCH_PORT }]) if (ELASTICSEARCH_HOST and ELASTICSEARCH_PORT) else None + + # Check if elasticsearch is running + if not es.ping(): + es = None except: es = None -- cgit v1.2.3 From 690e525a8a063d1be107c15521474052bd6ae2b4 Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Fri, 9 Feb 2018 11:02:07 +0300 Subject: Check elasticsearch at point of use * Instead of checking for the state of elasticsearch at startup, check the state at the moment the user requests a feature that depends on elasticsearch. This reduces the chances that the user is dropped onto an exception page when elasticsearch server goes down. --- wqflask/utility/elasticsearch_tools.py | 3 --- wqflask/wqflask/user_manager.py | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/elasticsearch_tools.py b/wqflask/utility/elasticsearch_tools.py index a0383033..4fc0035c 100644 --- a/wqflask/utility/elasticsearch_tools.py +++ b/wqflask/utility/elasticsearch_tools.py @@ -8,9 +8,6 @@ try: , "port": ELASTICSEARCH_PORT }]) if (ELASTICSEARCH_HOST and ELASTICSEARCH_PORT) else None - # Check if elasticsearch is running - if not es.ping(): - es = None except: es = None diff --git a/wqflask/wqflask/user_manager.py b/wqflask/wqflask/user_manager.py index 8f09c206..630be9aa 100644 --- a/wqflask/wqflask/user_manager.py +++ b/wqflask/wqflask/user_manager.py @@ -626,7 +626,7 @@ class LoginUser(object): return render_template( "new_security/login_user.html" , external_login=external_login - , es_server=es) + , es_server=es.ping()) else: user_details = get_user_by_unique_column("email_address", params["email_address"]) user = None -- cgit v1.2.3 From c68cffc414ac6d7536db36e79914f7d57af741c6 Mon Sep 17 00:00:00 2001 From: Muriithi Frederick Muriuki Date: Tue, 13 Feb 2018 13:48:28 +0300 Subject: Update module to make it more testable * Update functions to make them more testable. * Update code using updated functions. --- wqflask/utility/elasticsearch_tools.py | 40 +++++++++++++--------- wqflask/wqflask/user_manager.py | 61 +++++++++++++++++++--------------- 2 files changed, 58 insertions(+), 43 deletions(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/elasticsearch_tools.py b/wqflask/utility/elasticsearch_tools.py index 4fc0035c..a964b025 100644 --- a/wqflask/utility/elasticsearch_tools.py +++ b/wqflask/utility/elasticsearch_tools.py @@ -1,23 +1,31 @@ -es = None -try: - from elasticsearch import Elasticsearch, TransportError - from utility.tools import ELASTICSEARCH_HOST, ELASTICSEARCH_PORT +from elasticsearch import Elasticsearch, TransportError +import logging - es = Elasticsearch([{ - "host": ELASTICSEARCH_HOST - , "port": ELASTICSEARCH_PORT - }]) if (ELASTICSEARCH_HOST and ELASTICSEARCH_PORT) else None - -except: +def get_elasticsearch_connection(): es = None + try: + from utility.tools import ELASTICSEARCH_HOST, ELASTICSEARCH_PORT + + es = Elasticsearch([{ + "host": ELASTICSEARCH_HOST + , "port": ELASTICSEARCH_PORT + }]) if (ELASTICSEARCH_HOST and ELASTICSEARCH_PORT) else None + + es_logger = logging.getLogger("elasticsearch") + es_logger.setLevel(logging.INFO) + es_logger.addHandler(logging.NullHandler()) + except: + es = None + + return es -def get_user_by_unique_column(column_name, column_value): - return get_item_by_unique_column(column_name, column_value, index="users", doc_type="local") +def get_user_by_unique_column(es, column_name, column_value, index="users", doc_type="local"): + return get_item_by_unique_column(es, column_name, column_value, index=index, doc_type=doc_type) -def save_user(user, user_id): - es_save_data("users", "local", user, user_id) +def save_user(es, user, user_id): + es_save_data(es, "users", "local", user, user_id) -def get_item_by_unique_column(column_name, column_value, index, doc_type): +def get_item_by_unique_column(es, column_name, column_value, index, doc_type): item_details = None try: response = es.search( @@ -32,7 +40,7 @@ def get_item_by_unique_column(column_name, column_value, index, doc_type): pass return item_details -def es_save_data(index, doc_type, data_item, data_id,): +def es_save_data(es, index, doc_type, data_item, data_id,): from time import sleep es.create(index, doc_type, body=data_item, id=data_id) sleep(1) # Delay 1 second to allow indexing diff --git a/wqflask/wqflask/user_manager.py b/wqflask/wqflask/user_manager.py index 630be9aa..6b667615 100644 --- a/wqflask/wqflask/user_manager.py +++ b/wqflask/wqflask/user_manager.py @@ -55,8 +55,9 @@ logger = getLogger(__name__) from base.data_set import create_datasets_list import requests -from utility.elasticsearch_tools import get_user_by_unique_column, save_user, es_save_data +from utility.elasticsearch_tools import * +es = get_elasticsearch_connection() THREE_DAYS = 60 * 60 * 24 * 3 #THREE_DAYS = 45 @@ -271,14 +272,18 @@ class RegisterUser(object): self.thank_you_mode = False self.errors = [] self.user = Bunch() + es = kw.get('es_connection', None) + + if not es: + self.errors.append("Missing connection object") self.user.email_address = kw.get('email_address', '').encode("utf-8").strip() if not (5 <= len(self.user.email_address) <= 50): self.errors.append('Email Address needs to be between 5 and 50 characters.') - - email_exists = get_user_by_unique_column("email_address", self.user.email_address) - if email_exists: - self.errors.append('User already exists with that email') + else: + email_exists = get_user_by_unique_column(es, "email_address", self.user.email_address) + if email_exists: + self.errors.append('User already exists with that email') self.user.full_name = kw.get('full_name', '').encode("utf-8").strip() if not (5 <= len(self.user.full_name) <= 50): @@ -305,7 +310,7 @@ class RegisterUser(object): self.user.confirmed = 1 self.user.registration_info = json.dumps(basic_info(), sort_keys=True) - save_user(self.user.__dict__, self.user.user_id) + save_user(es, self.user.__dict__, self.user.user_id) def set_password(password, user): pwfields = Bunch() @@ -381,7 +386,7 @@ class ForgotPasswordEmail(VerificationEmail): "email_address": toaddr, "timestamp": timestamp() } - es_save_data(self.key_prefix, "local", data, verification_code) + es_save_data(es, self.key_prefix, "local", data, verification_code) subject = self.subject body = render_template( @@ -431,7 +436,6 @@ def verify_email(): @app.route("/n/password_reset", methods=['GET']) def password_reset(): - from utility.elasticsearch_tools import get_item_by_unique_column logger.debug("in password_reset request.url is:", request.url) # We do this mainly just to assert that it's in proper form for displaying next page @@ -441,14 +445,16 @@ def password_reset(): hmac = request.args.get('hm') if verification_code: code_details = get_item_by_unique_column( - "verification_code", - verification_code, - ForgotPasswordEmail.key_prefix, - "local") + es + , "verification_code" + , verification_code + , ForgotPasswordEmail.key_prefix + , "local") if code_details: user_details = get_user_by_unique_column( - "email_address", - code_details["email_address"]) + es + , "email_address" + , code_details["email_address"]) if user_details: return render_template( "new_security/password_reset.html", user_encode=user_details["user_id"]) @@ -533,7 +539,7 @@ def github_oauth2(): result_dict = {arr[0]:arr[1] for arr in [tok.split("=") for tok in [token.encode("utf-8") for token in result.text.split("&")]]} github_user = get_github_user_details(result_dict["access_token"]) - user_details = get_user_by_unique_column("github_id", github_user["id"]) + user_details = get_user_by_unique_column(es, "github_id", github_user["id"]) if user_details == None: user_details = { "user_id": str(uuid.uuid4()) @@ -545,7 +551,7 @@ def github_oauth2(): , "active": 1 , "confirmed": 1 } - save_user(user_details, user_details["user_id"]) + save_user(es, user_details, user_details["user_id"]) url = "/n/login?type=github&uid="+user_details["user_id"] return redirect(url) @@ -566,7 +572,7 @@ def orcid_oauth2(): result = requests.post(ORCID_TOKEN_URL, data=data) result_dict = json.loads(result.text.encode("utf-8")) - user_details = get_user_by_unique_column("orcid", result_dict["orcid"]) + user_details = get_user_by_unique_column(es, "orcid", result_dict["orcid"]) if user_details == None: user_details = { "user_id": str(uuid4()) @@ -580,7 +586,7 @@ def orcid_oauth2(): , "active": 1 , "confirmed": 1 } - save_user(user_details, user_details["user_id"]) + save_user(es, user_details, user_details["user_id"]) url = "/n/login?type=orcid&uid="+user_details["user_id"] else: flash("There was an error getting code from ORCID") @@ -599,7 +605,7 @@ class LoginUser(object): def oauth2_login(self, login_type, user_id): """Login via an OAuth2 provider""" - user_details = get_user_by_unique_column("user_id", user_id) + user_details = get_user_by_unique_column(es, "user_id", user_id) if user_details: user = model.User() user.id = user_details["user_id"] @@ -616,7 +622,6 @@ class LoginUser(object): logger.debug("in login params are:", params) if not params: from utility.tools import GITHUB_AUTH_URL, ORCID_AUTH_URL - from utility.elasticsearch_tools import es external_login = None if GITHUB_AUTH_URL or ORCID_AUTH_URL: external_login={ @@ -628,8 +633,9 @@ class LoginUser(object): , external_login=external_login , es_server=es.ping()) else: - user_details = get_user_by_unique_column("email_address", params["email_address"]) + user_details = get_user_by_unique_column(es, "email_address", params["email_address"]) user = None + valid = None if user_details: user = model.User(); for key in user_details: @@ -672,7 +678,7 @@ class LoginUser(object): else: if user: self.unsuccessful_login(user) - flash("Invalid email-address or password. Please try again.", "alert-error") + flash("Invalid email-address or password. Please try again.", "alert-danger") response = make_response(redirect(url_for('login'))) return response @@ -739,7 +745,7 @@ def forgot_password(): def forgot_password_submit(): params = request.form email_address = params['email_address'] - user_details = get_user_by_unique_column("email_address", email_address) + user_details = get_user_by_unique_column(es, "email_address", email_address) if user_details: ForgotPasswordEmail(user_details["email_address"]) # try: @@ -815,16 +821,17 @@ def register(): params = request.form if request.form else request.args + params = params.to_dict(flat=True) + params["es_connection"] = es if params: logger.debug("Attempting to register the user...") result = RegisterUser(params) errors = result.errors - if result.thank_you_mode: - assert not errors, "Errors while in thank you mode? That seems wrong..." - return render_template("new_security/registered.html", - subject=VerificationEmail.subject) + if len(errors) == 0: + flash("Registration successful. You may login with your new account", "alert-info") + return redirect(url_for("login")) return render_template("new_security/register_user.html", values=params, errors=errors) -- cgit v1.2.3 From 3de1ecfa37b73b4cb011b634c8b4afc2362f858c Mon Sep 17 00:00:00 2001 From: Pjotr Prins Date: Thu, 15 Feb 2018 10:30:52 +0000 Subject: Fixing authentication stuff so it uses parameters properly. Also no PYTHONPATH needed as it is now in the Guix build. --- bin/genenetwork2 | 12 +++++++----- etc/default_settings.py | 18 ++++++++++++++++++ wqflask/run_gunicorn.py | 3 +++ wqflask/utility/elasticsearch_tools.py | 16 ++++++++++++---- wqflask/utility/tools.py | 29 +++++++++++------------------ wqflask/wqflask/user_manager.py | 7 +++++-- 6 files changed, 56 insertions(+), 29 deletions(-) (limited to 'wqflask/utility') diff --git a/bin/genenetwork2 b/bin/genenetwork2 index 74ed7f9b..31fefbd3 100755 --- a/bin/genenetwork2 +++ b/bin/genenetwork2 @@ -95,11 +95,13 @@ export WQFLASK_OVERRIDES=$overrides # JSON echo WQFLASK_SETTINGS=$settings echo WQFLASK_OVERRIDES=$overrides -if [ -z $ELASTICSEARCH_PROFILE ]; then - echo -e "\033[1;33mWARNING: Elastic Search profile has not been set - use ELASTICSEARCH_PROFILE\033[0m"; -else - PYTHONPATH="$PYTHONPATH${PYTHONPATH:+:}$ELASTICSEARCH_PROFILE/lib/python2.7/site-packages" -fi +# This is a temporary hack to inject ES - should have added python2-elasticsearch package to guix instead +# if [ -z $ELASTICSEARCH_PROFILE ]; then +# echo -e "WARNING: Elastic Search profile has not been set - use ELASTICSEARCH_PROFILE"; +# else +# PYTHONPATH="$PYTHONPATH${PYTHONPATH:+:}$ELASTICSEARCH_PROFILE/lib/python2.7/site-packages" +# fi + if [ -z $GN2_PROFILE ] ; then echo "WARNING: GN2_PROFILE has not been set - you need the environment, so I hope you know what you are doing!" export GN2_PROFILE=$(dirname $(dirname $(which genenetwork2))) diff --git a/etc/default_settings.py b/etc/default_settings.py index 699d21f1..a70d8aec 100644 --- a/etc/default_settings.py +++ b/etc/default_settings.py @@ -41,6 +41,24 @@ SECURITY_POST_LOGIN_VIEW = "/thank_you" SERVER_PORT = 5003 # running on localhost SECRET_HMAC_CODE = '\x08\xdf\xfa\x93N\x80\xd9\\H@\\\x9f`\x98d^\xb4a;\xc6OM\x946a\xbc\xfc\x80:*\xebc' +GITHUB_CLIENT_ID = "UNKNOWN" +GITHUB_CLIENT_SECRET = "UNKNOWN" +GITHUB_AUTH_URL = "UNKNOWN" +GITHUB_API_URL = "UNKNOWN" + +ORCID_CLIENT_ID = "UNKNOWN" +ORCID_CLIENT_SECRET = "UNKNOWN" +ORCID_AUTH_URL = "UNKNOWN" +ORCID_TOKEN_URL = "UNKNOWN" + +ELASTICSEARCH_HOST = "localhost" +ELASTICSEARCH_PORT = '9200' + +SMTP_CONNECT = "UNKNOWN" +SMTP_USERNAME = "UNKNOWN" +SMTP_PASSWORD = "UNKNOWN" + + # ---- Behavioural settings (defaults) note that logger and log levels can # be overridden at the module level and with enviroment settings WEBSERVER_MODE = 'DEV' # Python webserver mode (DEBUG|DEV|PROD) diff --git a/wqflask/run_gunicorn.py b/wqflask/run_gunicorn.py index 14a2d689..ebe3add5 100644 --- a/wqflask/run_gunicorn.py +++ b/wqflask/run_gunicorn.py @@ -11,6 +11,9 @@ print "Starting up Gunicorn process" from wqflask import app +app.config['SESSION_TYPE'] = 'filesystem' +app.config['SECRET_KEY'] = 'super secret key' + @app.route("/gunicorn") def hello(): return "

Hello There!

" diff --git a/wqflask/utility/elasticsearch_tools.py b/wqflask/utility/elasticsearch_tools.py index a964b025..2d3d5add 100644 --- a/wqflask/utility/elasticsearch_tools.py +++ b/wqflask/utility/elasticsearch_tools.py @@ -1,10 +1,18 @@ from elasticsearch import Elasticsearch, TransportError import logging +from utility.logger import getLogger +logger = getLogger(__name__) + +from utility.tools import ELASTICSEARCH_HOST, ELASTICSEARCH_PORT + def get_elasticsearch_connection(): + logger.info("get_elasticsearch_connection") es = None try: - from utility.tools import ELASTICSEARCH_HOST, ELASTICSEARCH_PORT + assert(ELASTICSEARCH_HOST) + assert(ELASTICSEARCH_PORT) + logger.info("ES HOST",ELASTICSEARCH_HOST) es = Elasticsearch([{ "host": ELASTICSEARCH_HOST @@ -31,12 +39,12 @@ def get_item_by_unique_column(es, column_name, column_value, index, doc_type): response = es.search( index = index , doc_type = doc_type - , body = { - "query": { "match": { column_name: column_value } } + , body = { + "query": { "match": { column_name: column_value } } }) if len(response["hits"]["hits"]) > 0: item_details = response["hits"]["hits"][0]["_source"] - except TransportError as te: + except TransportError as te: pass return item_details diff --git a/wqflask/utility/tools.py b/wqflask/utility/tools.py index 005f9b0f..8c9fed96 100644 --- a/wqflask/utility/tools.py +++ b/wqflask/utility/tools.py @@ -251,32 +251,25 @@ assert_dir(JS_GUIX_PATH) JS_GN_PATH = get_setting('JS_GN_PATH') # assert_dir(JS_GN_PATH) -def get_setting_safe(setting): - try: - return get_setting(setting) - except: - print("Could not find the setting '", setting, "'. Continuing with value unset") - return None - -GITHUB_CLIENT_ID = get_setting_safe('GITHUB_CLIENT_ID') -GITHUB_CLIENT_SECRET = get_setting_safe('GITHUB_CLIENT_SECRET') +GITHUB_CLIENT_ID = get_setting('GITHUB_CLIENT_ID') +GITHUB_CLIENT_SECRET = get_setting('GITHUB_CLIENT_SECRET') GITHUB_AUTH_URL = None if GITHUB_CLIENT_ID and GITHUB_CLIENT_SECRET: GITHUB_AUTH_URL = "https://github.com/login/oauth/authorize?client_id="+GITHUB_CLIENT_ID+"&client_secret="+GITHUB_CLIENT_SECRET -GITHUB_API_URL = get_setting_safe('GITHUB_API_URL') -ORCID_CLIENT_ID = get_setting_safe('ORCID_CLIENT_ID') -ORCID_CLIENT_SECRET = get_setting_safe('ORCID_CLIENT_SECRET') +GITHUB_API_URL = get_setting('GITHUB_API_URL') +ORCID_CLIENT_ID = get_setting('ORCID_CLIENT_ID') +ORCID_CLIENT_SECRET = get_setting('ORCID_CLIENT_SECRET') ORCID_AUTH_URL = None if ORCID_CLIENT_ID and ORCID_CLIENT_SECRET: ORCID_AUTH_URL = "https://sandbox.orcid.org/oauth/authorize?response_type=code&scope=/authenticate&show_login=true&client_id="+ORCID_CLIENT_ID+"&client_secret="+ORCID_CLIENT_SECRET -ORCID_TOKEN_URL = get_setting_safe('ORCID_TOKEN_URL') +ORCID_TOKEN_URL = get_setting('ORCID_TOKEN_URL') -ELASTICSEARCH_HOST = get_setting_safe('ELASTICSEARCH_HOST') -ELASTICSEARCH_PORT = get_setting_safe('ELASTICSEARCH_PORT') +ELASTICSEARCH_HOST = get_setting('ELASTICSEARCH_HOST') +ELASTICSEARCH_PORT = get_setting('ELASTICSEARCH_PORT') -SMTP_CONNECT = get_setting_safe('SMTP_CONNECT') -SMTP_USERNAME = get_setting_safe('SMTP_USERNAME') -SMTP_PASSWORD = get_setting_safe('SMTP_PASSWORD') +SMTP_CONNECT = get_setting('SMTP_CONNECT') +SMTP_USERNAME = get_setting('SMTP_USERNAME') +SMTP_PASSWORD = get_setting('SMTP_PASSWORD') PYLMM_COMMAND = app_set("PYLMM_COMMAND",pylmm_command()) GEMMA_COMMAND = app_set("GEMMA_COMMAND",gemma_command()) diff --git a/wqflask/wqflask/user_manager.py b/wqflask/wqflask/user_manager.py index 6b667615..c8471cb1 100644 --- a/wqflask/wqflask/user_manager.py +++ b/wqflask/wqflask/user_manager.py @@ -55,9 +55,8 @@ logger = getLogger(__name__) from base.data_set import create_datasets_list import requests -from utility.elasticsearch_tools import * +from utility.elasticsearch_tools import get_elasticsearch_connection, get_user_by_unique_column, save_user -es = get_elasticsearch_connection() THREE_DAYS = 60 * 60 * 24 * 3 #THREE_DAYS = 45 @@ -479,6 +478,7 @@ def password_reset_step2(): password = request.form['password'] set_password(password, user) + es = get_elasticsearch_connection() es.update( index = "users" , doc_type = "local" @@ -620,6 +620,7 @@ class LoginUser(object): """Login through the normal form""" params = request.form if request.form else request.args logger.debug("in login params are:", params) + es = get_elasticsearch_connection() if not params: from utility.tools import GITHUB_AUTH_URL, ORCID_AUTH_URL external_login = None @@ -628,6 +629,7 @@ class LoginUser(object): "github": GITHUB_AUTH_URL, "orcid": ORCID_AUTH_URL } + assert(es is not None) return render_template( "new_security/login_user.html" , external_login=external_login @@ -822,6 +824,7 @@ def register(): params = request.form if request.form else request.args params = params.to_dict(flat=True) + es = get_elasticsearch_connection() params["es_connection"] = es if params: -- cgit v1.2.3 From 3c8089e2c3957ca2d4a5906249b4818d367221dc Mon Sep 17 00:00:00 2001 From: Pjotr Prins Date: Mon, 19 Mar 2018 13:06:13 +0000 Subject: - Disabled PYTHONPATH injection - fix Guix instead, see https://github.com/pjotrp/genenetwork2/commit/63a5c8a42ad02e9126bb207465ff5eca98f6515d - Renamed WQFLASK_SETTINGS to GN2_SETTINGS --- bin/genenetwork2 | 33 +++++++++++++++------------------ wqflask/utility/tools.py | 15 +-------------- wqflask/wqflask/__init__.py | 4 ++-- 3 files changed, 18 insertions(+), 34 deletions(-) (limited to 'wqflask/utility') diff --git a/bin/genenetwork2 b/bin/genenetwork2 index ceafeedd..3f06e7f9 100755 --- a/bin/genenetwork2 +++ b/bin/genenetwork2 @@ -68,32 +68,29 @@ if [ "$1" = "-c" -o "$1" = "-gunicorn" ]; then echo "Can not use $1 switch without default settings file" exit 1 fi -# Handle settings parameter (can be .py or .json) -if [ ! -z $1 ]; then - settings=$(realpath "$1") - if [ ! -e $settings ]; then - settings=$GN2_BASE_DIR/etc/default_settings.py - else - shift - fi -fi -ext="${settings##*.}" -if [ "$ext" = "json" -o "$ext" = "JSON" ]; then - overrides=$settings +settings=$1 +if [ -z $settings ]; then + settings=$GN2_BASE_DIR/etc/default_settings.py else - echo $settings + shift fi +settings=$(realpath $settings) + +# ext="${settings##*.}" +# if [ "$ext" = "json" -o "$ext" = "JSON" ]; then +# overrides=$settings +# else +# echo $settings +# fi if [ ! -e $settings ]; then echo "ERROR: can not locate settings file - pass it in the command line" exit 1 fi -export WQFLASK_SETTINGS=$settings # Python -export WQFLASK_OVERRIDES=$overrides # JSON -echo WQFLASK_SETTINGS=$settings -echo WQFLASK_OVERRIDES=$overrides +export GN2_SETTINGS=$settings # Python +echo GN2_SETTINGS=$settings # This is a temporary hack to inject ES - should have added python2-elasticsearch package to guix instead # if [ -z $ELASTICSEARCH_PROFILE ]; then @@ -115,7 +112,7 @@ if [ -z $GN2_PROFILE ]; then read -p "PRESS [ENTER] TO CONTINUE..." else export PATH=$GN2_PROFILE/bin:$PATH - export PYTHONPATH="$GN2_PROFILE/lib/python2.7/site-packages${PYTHONPATH:+:}$PYTHONPATH" + export PYTHONPATH="$GN2_PROFILE/lib/python2.7/site-packages" # never inject another PYTHONPATH!! export R_LIBS_SITE=$GN2_PROFILE/site-library export GEM_PATH=$GN2_PROFILE/lib/ruby/gems/2.4.0 export JS_GUIX_PATH=$GN2_PROFILE/share/genenetwork2/javascript diff --git a/wqflask/utility/tools.py b/wqflask/utility/tools.py index 8c9fed96..bae3a7f4 100644 --- a/wqflask/utility/tools.py +++ b/wqflask/utility/tools.py @@ -54,7 +54,7 @@ def get_setting(command_id,guess=None): # print("Looking for "+command_id+"\n") command = value(os.environ.get(command_id)) if command is None or command == "": - command = OVERRIDES.get(command_id) + command = OVERRIDES.get(command_id) # currently not in use if command is None: # ---- Check whether setting exists in app command = value(app.config.get(command_id)) @@ -285,18 +285,5 @@ assert_dir(JS_TWITTER_POST_FETCHER_PATH) from six import string_types -if os.environ.get('WQFLASK_OVERRIDES'): - jsonfn = get_setting('WQFLASK_OVERRIDES') - logger.info("WQFLASK_OVERRIDES: %s" % jsonfn) - with open(jsonfn) as data_file: - overrides = json.load(data_file) - for k in overrides: - cmd = overrides[k] - if isinstance(cmd, string_types): - OVERRIDES[k] = eval(cmd) - else: - OVERRIDES[k] = cmd - logger.debug(OVERRIDES) - # assert_file(PHEWAS_FILES+"/auwerx/PheWAS_pval_EMMA_norm.RData") assert_file(JS_TWITTER_POST_FETCHER_PATH+"/js/twitterFetcher_min.js") diff --git a/wqflask/wqflask/__init__.py b/wqflask/wqflask/__init__.py index 2188ce17..bc8e9900 100644 --- a/wqflask/wqflask/__init__.py +++ b/wqflask/wqflask/__init__.py @@ -13,8 +13,8 @@ logging.basicConfig(level=logging.INFO) app = Flask(__name__) app.config.from_object('cfg.default_settings') # Get the defaults from cfg.default_settings -app.config.from_envvar('WQFLASK_SETTINGS') # See http://flask.pocoo.org/docs/config/#configuring-from-files -# Note we also use WQFLASK_OVERRIDES +app.config.from_envvar('GN2_SETTINGS') # See http://flask.pocoo.org/docs/config/#configuring-from-files +# Note no longer use the badly named WQFLASK_OVERRIDES (nyi) app.jinja_env.globals.update( undefined = jinja2.StrictUndefined, -- cgit v1.2.3 From 2b75b5d56c99d58e205aed59e721bf578489e802 Mon Sep 17 00:00:00 2001 From: Pjotr Prins Date: Tue, 20 Mar 2018 09:41:36 +0000 Subject: Authentication: some mods around defaults --- wqflask/utility/tools.py | 15 +++++++++------ wqflask/wqflask/templates/new_security/login_user.html | 2 +- wqflask/wqflask/user_manager.py | 13 ++++++------- 3 files changed, 16 insertions(+), 14 deletions(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/tools.py b/wqflask/utility/tools.py index bae3a7f4..ed54f77c 100644 --- a/wqflask/utility/tools.py +++ b/wqflask/utility/tools.py @@ -254,15 +254,18 @@ JS_GN_PATH = get_setting('JS_GN_PATH') GITHUB_CLIENT_ID = get_setting('GITHUB_CLIENT_ID') GITHUB_CLIENT_SECRET = get_setting('GITHUB_CLIENT_SECRET') GITHUB_AUTH_URL = None -if GITHUB_CLIENT_ID and GITHUB_CLIENT_SECRET: - GITHUB_AUTH_URL = "https://github.com/login/oauth/authorize?client_id="+GITHUB_CLIENT_ID+"&client_secret="+GITHUB_CLIENT_SECRET -GITHUB_API_URL = get_setting('GITHUB_API_URL') +if GITHUB_CLIENT_ID != 'UNKNOWN' and GITHUB_CLIENT_SECRET: + GITHUB_AUTH_URL = "https://github.com/login/oauth/authorize?client_id=" + \ + GITHUB_CLIENT_ID+"&client_secret="+GITHUB_CLIENT_SECRET + GITHUB_API_URL = get_setting('GITHUB_API_URL') + ORCID_CLIENT_ID = get_setting('ORCID_CLIENT_ID') ORCID_CLIENT_SECRET = get_setting('ORCID_CLIENT_SECRET') ORCID_AUTH_URL = None -if ORCID_CLIENT_ID and ORCID_CLIENT_SECRET: - ORCID_AUTH_URL = "https://sandbox.orcid.org/oauth/authorize?response_type=code&scope=/authenticate&show_login=true&client_id="+ORCID_CLIENT_ID+"&client_secret="+ORCID_CLIENT_SECRET -ORCID_TOKEN_URL = get_setting('ORCID_TOKEN_URL') +if ORCID_CLIENT_ID != 'UNKNOWN' and ORCID_CLIENT_SECRET: + ORCID_AUTH_URL = "https://sandbox.orcid.org/oauth/authorize?response_type=code&scope=/authenticate&show_login=true&client_id=" + + ORCID_CLIENT_ID+"&client_secret="+ORCID_CLIENT_SECRET + ORCID_TOKEN_URL = get_setting('ORCID_TOKEN_URL') ELASTICSEARCH_HOST = get_setting('ELASTICSEARCH_HOST') ELASTICSEARCH_PORT = get_setting('ELASTICSEARCH_PORT') diff --git a/wqflask/wqflask/templates/new_security/login_user.html b/wqflask/wqflask/templates/new_security/login_user.html index 0dae3503..6d597f6b 100644 --- a/wqflask/wqflask/templates/new_security/login_user.html +++ b/wqflask/wqflask/templates/new_security/login_user.html @@ -88,7 +88,7 @@ {% else: %}
-

You cannot login at this moment using your GeneNetwork account.
+

You cannot login at this moment using your GeneNetwork account (the authentication service is down).
Please try again later.

{% endif %} diff --git a/wqflask/wqflask/user_manager.py b/wqflask/wqflask/user_manager.py index c344ea27..c55649f3 100644 --- a/wqflask/wqflask/user_manager.py +++ b/wqflask/wqflask/user_manager.py @@ -626,13 +626,12 @@ class LoginUser(object): logger.debug("in login params are:", params) es = get_elasticsearch_connection() if not params: - from utility.tools import GITHUB_AUTH_URL, ORCID_AUTH_URL - external_login = None - if GITHUB_AUTH_URL or ORCID_AUTH_URL: - external_login={ - "github": GITHUB_AUTH_URL, - "orcid": ORCID_AUTH_URL - } + from utility.tools import GITHUB_AUTH_URL, GITHUB_CLIENT_ID, ORCID_AUTH_URL, ORCID_CLIENT_ID + external_login = {} + if GITHUB_AUTH_URL and GITHUB_CLIENT_ID != 'UNKNOWN': + external_login["github"] = GITHUB_AUTH_URL + if ORCID_AUTH_URL and ORCID_CLIENT_ID != 'UNKNOWN': + external_login["orcid"] = ORCID_AUTH_URL assert(es is not None) return render_template( "new_security/login_user.html" -- cgit v1.2.3 From e2339a0a491f1853b8411d499be1e08bf62a2da8 Mon Sep 17 00:00:00 2001 From: Pjotr Prins Date: Tue, 20 Mar 2018 09:50:34 +0000 Subject: Fix --- wqflask/utility/tools.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/tools.py b/wqflask/utility/tools.py index ed54f77c..4b4cd633 100644 --- a/wqflask/utility/tools.py +++ b/wqflask/utility/tools.py @@ -263,7 +263,7 @@ ORCID_CLIENT_ID = get_setting('ORCID_CLIENT_ID') ORCID_CLIENT_SECRET = get_setting('ORCID_CLIENT_SECRET') ORCID_AUTH_URL = None if ORCID_CLIENT_ID != 'UNKNOWN' and ORCID_CLIENT_SECRET: - ORCID_AUTH_URL = "https://sandbox.orcid.org/oauth/authorize?response_type=code&scope=/authenticate&show_login=true&client_id=" + + ORCID_AUTH_URL = "https://sandbox.orcid.org/oauth/authorize?response_type=code&scope=/authenticate&show_login=true&client_id=" + \ ORCID_CLIENT_ID+"&client_secret="+ORCID_CLIENT_SECRET ORCID_TOKEN_URL = get_setting('ORCID_TOKEN_URL') -- cgit v1.2.3 From 7aae77762e47c9269591e138ab25320d3ed3a85f Mon Sep 17 00:00:00 2001 From: Pjotr Prins Date: Tue, 20 Mar 2018 11:02:25 +0000 Subject: Refactor startup config for gunicorn and werkzeug --- wqflask/run_gunicorn.py | 6 ++-- wqflask/runserver.py | 17 ++-------- wqflask/utility/elasticsearch_tools.py | 5 +++ wqflask/utility/startup_config.py | 39 ++++++++++++++++++++++ wqflask/utility/tools.py | 4 ++- .../wqflask/templates/new_security/login_user.html | 8 ++++- 6 files changed, 59 insertions(+), 20 deletions(-) create mode 100644 wqflask/utility/startup_config.py (limited to 'wqflask/utility') diff --git a/wqflask/run_gunicorn.py b/wqflask/run_gunicorn.py index ebe3add5..adffdca3 100644 --- a/wqflask/run_gunicorn.py +++ b/wqflask/run_gunicorn.py @@ -7,12 +7,12 @@ # from flask import Flask # application = Flask(__name__) -print "Starting up Gunicorn process" +print "===> Starting up Gunicorn process" from wqflask import app +from utility.startup_config import app_config -app.config['SESSION_TYPE'] = 'filesystem' -app.config['SECRET_KEY'] = 'super secret key' +app_config() @app.route("/gunicorn") def hello(): diff --git a/wqflask/runserver.py b/wqflask/runserver.py index a0c76e51..5f41d04d 100644 --- a/wqflask/runserver.py +++ b/wqflask/runserver.py @@ -21,22 +21,9 @@ GREEN = '\033[92m' BOLD = '\033[1m' ENDC = '\033[0m' -import os -app.config['SECRET_KEY'] = os.urandom(24) +from utility.startup_config import app_config -from utility.tools import WEBSERVER_MODE,get_setting_int,get_setting,get_setting_bool - -port = get_setting_int("SERVER_PORT") - -print("GN2 API server URL is ["+BLUE+get_setting("GN_SERVER_URL")+ENDC+"]") - -if get_setting_bool("USE_GN_SERVER"): - import requests - page = requests.get(get_setting("GN_SERVER_URL")) - if page.status_code != 200: - raise Exception("API server not found!") - -print("GN2 is running. Visit %s[http://localhost:%s/%s](%s)" % (BLUE,str(port),ENDC,get_setting("WEBSERVER_URL"))) +app_config() werkzeug_logger = logging.getLogger('werkzeug') diff --git a/wqflask/utility/elasticsearch_tools.py b/wqflask/utility/elasticsearch_tools.py index 2d3d5add..734379f7 100644 --- a/wqflask/utility/elasticsearch_tools.py +++ b/wqflask/utility/elasticsearch_tools.py @@ -6,6 +6,11 @@ logger = getLogger(__name__) from utility.tools import ELASTICSEARCH_HOST, ELASTICSEARCH_PORT +def test_elasticsearch_connection(): + es = Elasticsearch(['http://'+ELASTICSEARCH_HOST+":"+ELASTICSEARCH_PORT+'/'], verify_certs=True) + if not es.ping(): + logger.warning("Elasticsearch is DOWN") + def get_elasticsearch_connection(): logger.info("get_elasticsearch_connection") es = None diff --git a/wqflask/utility/startup_config.py b/wqflask/utility/startup_config.py new file mode 100644 index 00000000..02e8e56c --- /dev/null +++ b/wqflask/utility/startup_config.py @@ -0,0 +1,39 @@ + +from wqflask import app +from utility.tools import WEBSERVER_MODE, show_settings, get_setting_int, get_setting, get_setting_bool + +import utility.logger +logger = utility.logger.getLogger(__name__ ) + +BLUE = '\033[94m' +GREEN = '\033[92m' +BOLD = '\033[1m' +ENDC = '\033[0m' + +def app_config(): + app.config['SESSION_TYPE'] = 'filesystem' + if not app.config.get('SECRET_KEY'): + import os + app.config['SECRET_KEY'] = str(os.urandom(24)) + + mode = WEBSERVER_MODE + if mode == "DEV" or mode == "DEBUG": + app.config['TEMPLATES_AUTO_RELOAD'] = True + if mode == "DEBUG": + app.config['EXPLAIN_TEMPLATE_LOADING'] = True + print("==========================================") + show_settings() + + port = get_setting_int("SERVER_PORT") + + if get_setting_bool("USE_GN_SERVER"): + print("GN2 API server URL is ["+BLUE+get_setting("GN_SERVER_URL")+ENDC+"]") + import requests + page = requests.get(get_setting("GN_SERVER_URL")) + if page.status_code != 200: + raise Exception("API server not found!") + + import utility.elasticsearch_tools as es + es.test_elasticsearch_connection() + + print("GN2 is running. Visit %s[http://localhost:%s/%s](%s)" % (BLUE,str(port),ENDC,get_setting("WEBSERVER_URL"))) diff --git a/wqflask/utility/tools.py b/wqflask/utility/tools.py index 4b4cd633..59bb49d8 100644 --- a/wqflask/utility/tools.py +++ b/wqflask/utility/tools.py @@ -220,7 +220,7 @@ def show_settings(): logger.info(OVERRIDES) logger.info(BLUE+"Mr. Mojo Risin 2"+ENDC) - print "runserver.py: ****** Webserver configuration ******" + print "runserver.py: ****** Webserver configuration - k,v pairs from app.config ******" keylist = app.config.keys() keylist.sort() for k in keylist: @@ -269,6 +269,8 @@ if ORCID_CLIENT_ID != 'UNKNOWN' and ORCID_CLIENT_SECRET: ELASTICSEARCH_HOST = get_setting('ELASTICSEARCH_HOST') ELASTICSEARCH_PORT = get_setting('ELASTICSEARCH_PORT') +import utility.elasticsearch_tools as es +es.test_elasticsearch_connection() SMTP_CONNECT = get_setting('SMTP_CONNECT') SMTP_USERNAME = get_setting('SMTP_USERNAME') diff --git a/wqflask/wqflask/templates/new_security/login_user.html b/wqflask/wqflask/templates/new_security/login_user.html index 6d597f6b..949760b6 100644 --- a/wqflask/wqflask/templates/new_security/login_user.html +++ b/wqflask/wqflask/templates/new_security/login_user.html @@ -15,7 +15,6 @@

Don't have an account?

- {% if es_server: %} Create a new account {% else: %} @@ -92,6 +91,13 @@ Please try again later.

{% endif %} + {% if not es_server and not external_login: %} +
+
+ Note: it is safe to use GeneNetwork without a login. Login is only required for keeping track of + collections and getting access to some types of restricted data. +
+ {% endif %} -- cgit v1.2.3 From a0514e4d0119791267094581e2dc5c7eefb86b8f Mon Sep 17 00:00:00 2001 From: Pjotr Prins Date: Wed, 21 Mar 2018 10:05:54 +0000 Subject: Skip automatic use of EXPLAIN_TEMPLATE_LOADING. --- wqflask/utility/startup_config.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'wqflask/utility') diff --git a/wqflask/utility/startup_config.py b/wqflask/utility/startup_config.py index 02e8e56c..5a62cc50 100644 --- a/wqflask/utility/startup_config.py +++ b/wqflask/utility/startup_config.py @@ -19,8 +19,8 @@ def app_config(): mode = WEBSERVER_MODE if mode == "DEV" or mode == "DEBUG": app.config['TEMPLATES_AUTO_RELOAD'] = True - if mode == "DEBUG": - app.config['EXPLAIN_TEMPLATE_LOADING'] = True + # if mode == "DEBUG": + # app.config['EXPLAIN_TEMPLATE_LOADING'] = True <--- use overriding app param instead print("==========================================") show_settings() -- cgit v1.2.3 From b9ada0431b880e632b830a6e2169279ae1ecdd36 Mon Sep 17 00:00:00 2001 From: Pjotr Prins Date: Thu, 29 Mar 2018 11:00:41 +0000 Subject: Type checking in its own file --- wqflask/utility/type_checking.py | 42 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 wqflask/utility/type_checking.py (limited to 'wqflask/utility') diff --git a/wqflask/utility/type_checking.py b/wqflask/utility/type_checking.py new file mode 100644 index 00000000..220e5f62 --- /dev/null +++ b/wqflask/utility/type_checking.py @@ -0,0 +1,42 @@ +# Type checking functions + +def is_float(value): + try: + float(value) + return True + except: + return False + +def is_int(value): + try: + int(value) + return True + except: + return False + +def is_str(value): + if value is None: + return False + try: + str(value) + return True + except: + return False + +def get_float(vars,name,default=None): + if name in vars: + if is_float(vars[name]): + return float(vars[name]) + return None + +def get_int(vars,name,default=None): + if name in vars: + if is_int(vars[name]): + return float(vars[name]) + return default + +def get_string(vars,name,default=None): + if name in vars: + if not vars[name] is None: + return str(vars[name]) + return default -- cgit v1.2.3 From 8145507d6d617554cf996e6cebf286d30ae64df0 Mon Sep 17 00:00:00 2001 From: Pjotr Prins Date: Wed, 4 Apr 2018 16:58:21 +0000 Subject: ES: doc --- bin/genenetwork2 | 18 ++++++++++----- doc/elasticsearch.org | 41 ++++++++++++++++++++++++++++++++++ wqflask/utility/elasticsearch_tools.py | 9 ++++---- wqflask/wqflask/user_manager.py | 23 +++++-------------- 4 files changed, 62 insertions(+), 29 deletions(-) create mode 100644 doc/elasticsearch.org (limited to 'wqflask/utility') diff --git a/bin/genenetwork2 b/bin/genenetwork2 index 3f06e7f9..18e02388 100755 --- a/bin/genenetwork2 +++ b/bin/genenetwork2 @@ -21,10 +21,18 @@ # # env GN2_PROFILE=~/opt/gn-latest-guix ./bin/genenetwork2 ~/my_settings.py # -# To run a maintenance script with settings (instead of the webserver) add that with -# a -c switch, e.g. +# To run a maintenance python script with settings (instead of the +# webserver) add that with a -c switch, e.g. # -# env GN2_PROFILE=~/opt/gn-latest-guix ./bin/genenetwork2 ~/my_overrides.json -c ./wqflask/maintenance/gen_select_dataset.py +# env GN2_PROFILE=~/opt/gn-latest-guix ./bin/genenetwork2 -c ./wqflask/maintenance/gen_select_dataset.py +# +# To run any script in the environment +# +# env GN2_PROFILE=~/opt/gn-latest-guix ./bin/genenetwork2 ./etc/default_settings.py -cli echo "HELLO WORLD" +# +# To get a python REPL(!) +# +# env GN2_PROFILE=~/opt/gn-latest-guix ./bin/genenetwork2 ./etc/default_settings.py -cli python # # For development you may want to run # @@ -114,7 +122,6 @@ else export PATH=$GN2_PROFILE/bin:$PATH export PYTHONPATH="$GN2_PROFILE/lib/python2.7/site-packages" # never inject another PYTHONPATH!! export R_LIBS_SITE=$GN2_PROFILE/site-library - export GEM_PATH=$GN2_PROFILE/lib/ruby/gems/2.4.0 export JS_GUIX_PATH=$GN2_PROFILE/share/genenetwork2/javascript export GUIX_GTK3_PATH="$GN2_PROFILE/lib/gtk-3.0" export GI_TYPELIB_PATH="$GN2_PROFILE/lib/girepository-1.0" @@ -134,7 +141,6 @@ else done done <<< "$PYTHONPATH" if [ ! -d $R_LIBS_SITE ] ; then echo "R_LIBS_SITE not valid "$R_LIBS_SITE ; exit 1 ; fi - if [ ! -d $GEM_PATH ] ; then echo "GEM_PATH not valid "$GEM_PATH ; exit 1 ; fi fi if [ -z $PYTHONPATH ] ; then echo "ERROR PYTHONPATH has not been set - use GN2_PROFILE!" @@ -170,9 +176,9 @@ if [ "$1" = '-c' ] ; then python $cmd $* exit $? fi + # Now handle command parameter -cli which runs in bash if [ "$1" = "-cli" ] ; then - echo "HERE" cd $GN2_BASE_DIR/wqflask cmd=$2 echo PYTHONPATH=$PYTHONPATH diff --git a/doc/elasticsearch.org b/doc/elasticsearch.org new file mode 100644 index 00000000..18adfc8b --- /dev/null +++ b/doc/elasticsearch.org @@ -0,0 +1,41 @@ +* Elasticsearch + +To get the right environment, first you can get a python REPL with something like + +: env GN2_PROFILE=~/opt/gn-latest ./bin/genenetwork2 ../etc/default_settings.py -cli python + +(make sure to use the correct GN2_PROFILE!) + +Next try + +#+BEGIN_SRC python + +from elasticsearch import Elasticsearch, TransportError + +es = Elasticsearch([{ "host": 'localhost', "port": '9200' }]) + +# Dump all data + +es.search("*") + +# To fetch an E-mail record from the users index + +record = es.search( + index = 'users', doc_type = 'local', body = { + "query": { "match": { "email_address": "myname@email.com" } } + }) + +# It is also possible to do wild card matching + +q = { "query": { "wildcard" : { "full_name" : "pjot*" } }} +es.search(index = 'users', doc_type = 'local', body = q) + +# To get elements from that record: + +record['hits']['hits'][0][u'_source']['full_name'] +u'Pjotr' + +record['hits']['hits'][0][u'_source']['email_address'] +u"myname@email.com" + +#+END_SRC diff --git a/wqflask/utility/elasticsearch_tools.py b/wqflask/utility/elasticsearch_tools.py index 734379f7..1dba357d 100644 --- a/wqflask/utility/elasticsearch_tools.py +++ b/wqflask/utility/elasticsearch_tools.py @@ -12,6 +12,7 @@ def test_elasticsearch_connection(): logger.warning("Elasticsearch is DOWN") def get_elasticsearch_connection(): + """Return a connection to ES. Returns None on failure""" logger.info("get_elasticsearch_connection") es = None try: @@ -20,14 +21,14 @@ def get_elasticsearch_connection(): logger.info("ES HOST",ELASTICSEARCH_HOST) es = Elasticsearch([{ - "host": ELASTICSEARCH_HOST - , "port": ELASTICSEARCH_PORT + "host": ELASTICSEARCH_HOST, "port": ELASTICSEARCH_PORT }]) if (ELASTICSEARCH_HOST and ELASTICSEARCH_PORT) else None es_logger = logging.getLogger("elasticsearch") es_logger.setLevel(logging.INFO) es_logger.addHandler(logging.NullHandler()) except: + logger.error("Failed to get elasticsearch connection") es = None return es @@ -42,9 +43,7 @@ def get_item_by_unique_column(es, column_name, column_value, index, doc_type): item_details = None try: response = es.search( - index = index - , doc_type = doc_type - , body = { + index = index, doc_type = doc_type, body = { "query": { "match": { column_name: column_value } } }) if len(response["hits"]["hits"]) > 0: diff --git a/wqflask/wqflask/user_manager.py b/wqflask/wqflask/user_manager.py index ac3824a7..ead919fc 100644 --- a/wqflask/wqflask/user_manager.py +++ b/wqflask/wqflask/user_manager.py @@ -1,45 +1,30 @@ from __future__ import print_function, division, absolute_import -"""Used to Access things in template like this: -(BUT NOW OUT OF DATE) - - x: {{ g.identity.name }} - security: {{ security.__dict__ }} - -""" - import os import hashlib import datetime import time import logging - import uuid import hashlib import hmac import base64 - import urlparse import simplejson as json #from redis import StrictRedis -import redis +import redis # used for collections Redis = redis.StrictRedis() - from flask import (Flask, g, render_template, url_for, request, make_response, redirect, flash, abort) from wqflask import app - - from pprint import pformat as pf -from wqflask import pbkdf2 - +from wqflask import pbkdf2 # password hashing from wqflask.database import db_session - from wqflask import model from utility import Bunch, Struct, after @@ -62,8 +47,8 @@ THREE_DAYS = 60 * 60 * 24 * 3 def timestamp(): return datetime.datetime.utcnow().isoformat() - class AnonUser(object): + """Anonymous user handling""" cookie_name = 'anon_user_v8' def __init__(self): @@ -169,6 +154,8 @@ def create_signed_cookie(): return the_uuid, uuid_signed class UserSession(object): + """Logged in user handling""" + cookie_name = 'session_id_v2' def __init__(self): -- cgit v1.2.3 From 1debb0849066a31c8538b529536a9a7a12a0a8f9 Mon Sep 17 00:00:00 2001 From: Pjotr Prins Date: Fri, 6 Apr 2018 10:21:35 +0000 Subject: See #308. Cytoscape and related is now loaded from Guix. Use the latest GN2_PROFILE. --- jquery.qtip.css | 623 +++++++++++++++++++++++++++ unused.txt | 610 ++++++++++++++++++++++++++ wqflask/utility/tools.py | 12 +- wqflask/wqflask/templates/ctl_results.html | 22 +- wqflask/wqflask/templates/network_graph.html | 28 +- wqflask/wqflask/views.py | 10 +- 6 files changed, 1283 insertions(+), 22 deletions(-) create mode 100644 jquery.qtip.css create mode 100644 unused.txt (limited to 'wqflask/utility') diff --git a/jquery.qtip.css b/jquery.qtip.css new file mode 100644 index 00000000..c2dcb306 --- /dev/null +++ b/jquery.qtip.css @@ -0,0 +1,623 @@ +/* + * qTip2 - Pretty powerful tooltips - v2.2.0 + * http://qtip2.com + * + * Copyright (c) 2013 Craig Michael Thompson + * Released under the MIT, GPL licenses + * http://jquery.org/license + * + * Date: Thu Nov 21 2013 08:34 GMT+0000 + * Plugins: tips modal viewport svg imagemap ie6 + * Styles: basic css3 + */ +.qtip{ + position: absolute; + left: -28000px; + top: -28000px; + display: none; + + max-width: 280px; + min-width: 50px; + + font-size: 10.5px; + line-height: 12px; + + direction: ltr; + + box-shadow: none; + padding: 0; +} + + .qtip-content{ + position: relative; + padding: 5px 9px; + overflow: hidden; + + text-align: left; + word-wrap: break-word; + } + + .qtip-titlebar{ + position: relative; + padding: 5px 35px 5px 10px; + overflow: hidden; + + border-width: 0 0 1px; + font-weight: bold; + } + + .qtip-titlebar + .qtip-content{ border-top-width: 0 !important; } + + /* Default close button class */ + .qtip-close{ + position: absolute; + right: -9px; top: -9px; + + cursor: pointer; + outline: medium none; + + border-width: 1px; + border-style: solid; + border-color: transparent; + } + + .qtip-titlebar .qtip-close{ + right: 4px; top: 50%; + margin-top: -9px; + } + + * html .qtip-titlebar .qtip-close{ top: 16px; } /* IE fix */ + + .qtip-titlebar .ui-icon, + .qtip-icon .ui-icon{ + display: block; + text-indent: -1000em; + direction: ltr; + } + + .qtip-icon, .qtip-icon .ui-icon{ + -moz-border-radius: 3px; + -webkit-border-radius: 3px; + border-radius: 3px; + text-decoration: none; + } + + .qtip-icon .ui-icon{ + width: 18px; + height: 14px; + + line-height: 14px; + text-align: center; + text-indent: 0; + font: normal bold 10px/13px Tahoma,sans-serif; + + color: inherit; + background: transparent none no-repeat -100em -100em; + } + +/* Applied to 'focused' tooltips e.g. most recently displayed/interacted with */ +.qtip-focus{} + +/* Applied on hover of tooltips i.e. added/removed on mouseenter/mouseleave respectively */ +.qtip-hover{} + +/* Default tooltip style */ +.qtip-default{ + border-width: 1px; + border-style: solid; + border-color: #F1D031; + + background-color: #FFFFA3; + color: #555; +} + + .qtip-default .qtip-titlebar{ + background-color: #FFEF93; + } + + .qtip-default .qtip-icon{ + border-color: #CCC; + background: #F1F1F1; + color: #777; + } + + .qtip-default .qtip-titlebar .qtip-close{ + border-color: #AAA; + color: #111; + } + + + +/*! Light tooltip style */ +.qtip-light{ + background-color: white; + border-color: #E2E2E2; + color: #454545; +} + + .qtip-light .qtip-titlebar{ + background-color: #f1f1f1; + } + + +/*! Dark tooltip style */ +.qtip-dark{ + background-color: #505050; + border-color: #303030; + color: #f3f3f3; +} + + .qtip-dark .qtip-titlebar{ + background-color: #404040; + } + + .qtip-dark .qtip-icon{ + border-color: #444; + } + + .qtip-dark .qtip-titlebar .ui-state-hover{ + border-color: #303030; + } + + +/*! Cream tooltip style */ +.qtip-cream{ + background-color: #FBF7AA; + border-color: #F9E98E; + color: #A27D35; +} + + .qtip-cream .qtip-titlebar{ + background-color: #F0DE7D; + } + + .qtip-cream .qtip-close .qtip-icon{ + background-position: -82px 0; + } + + +/*! Red tooltip style */ +.qtip-red{ + background-color: #F78B83; + border-color: #D95252; + color: #912323; +} + + .qtip-red .qtip-titlebar{ + background-color: #F06D65; + } + + .qtip-red .qtip-close .qtip-icon{ + background-position: -102px 0; + } + + .qtip-red .qtip-icon{ + border-color: #D95252; + } + + .qtip-red .qtip-titlebar .ui-state-hover{ + border-color: #D95252; + } + + +/*! Green tooltip style */ +.qtip-green{ + background-color: #CAED9E; + border-color: #90D93F; + color: #3F6219; +} + + .qtip-green .qtip-titlebar{ + background-color: #B0DE78; + } + + .qtip-green .qtip-close .qtip-icon{ + background-position: -42px 0; + } + + +/*! Blue tooltip style */ +.qtip-blue{ + background-color: #E5F6FE; + border-color: #ADD9ED; + color: #5E99BD; +} + + .qtip-blue .qtip-titlebar{ + background-color: #D0E9F5; + } + + .qtip-blue .qtip-close .qtip-icon{ + background-position: -2px 0; + } + + + +.qtip-shadow{ + -webkit-box-shadow: 1px 1px 3px 1px rgba(0, 0, 0, 0.15); + -moz-box-shadow: 1px 1px 3px 1px rgba(0, 0, 0, 0.15); + box-shadow: 1px 1px 3px 1px rgba(0, 0, 0, 0.15); +} + +/* Add rounded corners to your tooltips in: FF3+, Chrome 2+, Opera 10.6+, IE9+, Safari 2+ */ +.qtip-rounded, +.qtip-tipsy, +.qtip-bootstrap{ + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + border-radius: 5px; +} + +.qtip-rounded .qtip-titlebar{ + -moz-border-radius: 4px 4px 0 0; + -webkit-border-radius: 4px 4px 0 0; + border-radius: 4px 4px 0 0; +} + +/* Youtube tooltip style */ +.qtip-youtube{ + -moz-border-radius: 2px; + -webkit-border-radius: 2px; + border-radius: 2px; + + -webkit-box-shadow: 0 0 3px #333; + -moz-box-shadow: 0 0 3px #333; + box-shadow: 0 0 3px #333; + + color: white; + border-width: 0; + + background: #4A4A4A; + background-image: -webkit-gradient(linear,left top,left bottom,color-stop(0,#4A4A4A),color-stop(100%,black)); + background-image: -webkit-linear-gradient(top,#4A4A4A 0,black 100%); + background-image: -moz-linear-gradient(top,#4A4A4A 0,black 100%); + background-image: -ms-linear-gradient(top,#4A4A4A 0,black 100%); + background-image: -o-linear-gradient(top,#4A4A4A 0,black 100%); +} + + .qtip-youtube .qtip-titlebar{ + background-color: #4A4A4A; + background-color: rgba(0,0,0,0); + } + + .qtip-youtube .qtip-content{ + padding: .75em; + font: 12px arial,sans-serif; + + filter: progid:DXImageTransform.Microsoft.Gradient(GradientType=0,StartColorStr=#4a4a4a,EndColorStr=#000000); + -ms-filter: "progid:DXImageTransform.Microsoft.Gradient(GradientType=0,StartColorStr=#4a4a4a,EndColorStr=#000000);"; + } + + .qtip-youtube .qtip-icon{ + border-color: #222; + } + + .qtip-youtube .qtip-titlebar .ui-state-hover{ + border-color: #303030; + } + + +/* jQuery TOOLS Tooltip style */ +.qtip-jtools{ + background: #232323; + background: rgba(0, 0, 0, 0.7); + background-image: -webkit-gradient(linear, left top, left bottom, from(#717171), to(#232323)); + background-image: -moz-linear-gradient(top, #717171, #232323); + background-image: -webkit-linear-gradient(top, #717171, #232323); + background-image: -ms-linear-gradient(top, #717171, #232323); + background-image: -o-linear-gradient(top, #717171, #232323); + + border: 2px solid #ddd; + border: 2px solid rgba(241,241,241,1); + + -moz-border-radius: 2px; + -webkit-border-radius: 2px; + border-radius: 2px; + + -webkit-box-shadow: 0 0 12px #333; + -moz-box-shadow: 0 0 12px #333; + box-shadow: 0 0 12px #333; +} + + /* IE Specific */ + .qtip-jtools .qtip-titlebar{ + background-color: transparent; + filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#717171,endColorstr=#4A4A4A); + -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#717171,endColorstr=#4A4A4A)"; + } + .qtip-jtools .qtip-content{ + filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#4A4A4A,endColorstr=#232323); + -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#4A4A4A,endColorstr=#232323)"; + } + + .qtip-jtools .qtip-titlebar, + .qtip-jtools .qtip-content{ + background: transparent; + color: white; + border: 0 dashed transparent; + } + + .qtip-jtools .qtip-icon{ + border-color: #555; + } + + .qtip-jtools .qtip-titlebar .ui-state-hover{ + border-color: #333; + } + + +/* Cluetip style */ +.qtip-cluetip{ + -webkit-box-shadow: 4px 4px 5px rgba(0, 0, 0, 0.4); + -moz-box-shadow: 4px 4px 5px rgba(0, 0, 0, 0.4); + box-shadow: 4px 4px 5px rgba(0, 0, 0, 0.4); + + background-color: #D9D9C2; + color: #111; + border: 0 dashed transparent; +} + + .qtip-cluetip .qtip-titlebar{ + background-color: #87876A; + color: white; + border: 0 dashed transparent; + } + + .qtip-cluetip .qtip-icon{ + border-color: #808064; + } + + .qtip-cluetip .qtip-titlebar .ui-state-hover{ + border-color: #696952; + color: #696952; + } + + +/* Tipsy style */ +.qtip-tipsy{ + background: black; + background: rgba(0, 0, 0, .87); + + color: white; + border: 0 solid transparent; + + font-size: 11px; + font-family: 'Lucida Grande', sans-serif; + font-weight: bold; + line-height: 16px; + text-shadow: 0 1px black; +} + + .qtip-tipsy .qtip-titlebar{ + padding: 6px 35px 0 10px; + background-color: transparent; + } + + .qtip-tipsy .qtip-content{ + padding: 6px 10px; + } + + .qtip-tipsy .qtip-icon{ + border-color: #222; + text-shadow: none; + } + + .qtip-tipsy .qtip-titlebar .ui-state-hover{ + border-color: #303030; + } + + +/* Tipped style */ +.qtip-tipped{ + border: 3px solid #959FA9; + + -moz-border-radius: 3px; + -webkit-border-radius: 3px; + border-radius: 3px; + + background-color: #F9F9F9; + color: #454545; + + font-weight: normal; + font-family: serif; +} + + .qtip-tipped .qtip-titlebar{ + border-bottom-width: 0; + + color: white; + background: #3A79B8; + background-image: -webkit-gradient(linear, left top, left bottom, from(#3A79B8), to(#2E629D)); + background-image: -webkit-linear-gradient(top, #3A79B8, #2E629D); + background-image: -moz-linear-gradient(top, #3A79B8, #2E629D); + background-image: -ms-linear-gradient(top, #3A79B8, #2E629D); + background-image: -o-linear-gradient(top, #3A79B8, #2E629D); + filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#3A79B8,endColorstr=#2E629D); + -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#3A79B8,endColorstr=#2E629D)"; + } + + .qtip-tipped .qtip-icon{ + border: 2px solid #285589; + background: #285589; + } + + .qtip-tipped .qtip-icon .ui-icon{ + background-color: #FBFBFB; + color: #555; + } + + +/** + * Twitter Bootstrap style. + * + * Tested with IE 8, IE 9, Chrome 18, Firefox 9, Opera 11. + * Does not work with IE 7. + */ +.qtip-bootstrap{ + /** Taken from Bootstrap body */ + font-size: 14px; + line-height: 20px; + color: #333333; + + /** Taken from Bootstrap .popover */ + padding: 1px; + background-color: #ffffff; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -webkit-background-clip: padding-box; + -moz-background-clip: padding; + background-clip: padding-box; +} + + .qtip-bootstrap .qtip-titlebar{ + /** Taken from Bootstrap .popover-title */ + padding: 8px 14px; + margin: 0; + font-size: 14px; + font-weight: normal; + line-height: 18px; + background-color: #f7f7f7; + border-bottom: 1px solid #ebebeb; + -webkit-border-radius: 5px 5px 0 0; + -moz-border-radius: 5px 5px 0 0; + border-radius: 5px 5px 0 0; + } + + .qtip-bootstrap .qtip-titlebar .qtip-close{ + /** + * Overrides qTip2: + * .qtip-titlebar .qtip-close{ + * [...] + * right: 4px; + * top: 50%; + * [...] + * border-style: solid; + * } + */ + right: 11px; + top: 45%; + border-style: none; + } + + .qtip-bootstrap .qtip-content{ + /** Taken from Bootstrap .popover-content */ + padding: 9px 14px; + } + + .qtip-bootstrap .qtip-icon{ + /** + * Overrides qTip2: + * .qtip-default .qtip-icon { + * border-color: #CCC; + * background: #F1F1F1; + * color: #777; + * } + */ + background: transparent; + } + + .qtip-bootstrap .qtip-icon .ui-icon{ + /** + * Overrides qTip2: + * .qtip-icon .ui-icon{ + * width: 18px; + * height: 14px; + * } + */ + width: auto; + height: auto; + + /* Taken from Bootstrap .close */ + float: right; + font-size: 20px; + font-weight: bold; + line-height: 18px; + color: #000000; + text-shadow: 0 1px 0 #ffffff; + opacity: 0.2; + filter: alpha(opacity=20); + } + + .qtip-bootstrap .qtip-icon .ui-icon:hover{ + /* Taken from Bootstrap .close:hover */ + color: #000000; + text-decoration: none; + cursor: pointer; + opacity: 0.4; + filter: alpha(opacity=40); + } + + +/* IE9 fix - removes all filters */ +.qtip:not(.ie9haxors) div.qtip-content, +.qtip:not(.ie9haxors) div.qtip-titlebar{ + filter: none; + -ms-filter: none; +} + + + +.qtip .qtip-tip{ + margin: 0 auto; + overflow: hidden; + z-index: 10; + +} + + /* Opera bug #357 - Incorrect tip position + https://github.com/Craga89/qTip2/issues/367 */ + x:-o-prefocus, .qtip .qtip-tip{ + visibility: hidden; + } + + .qtip .qtip-tip, + .qtip .qtip-tip .qtip-vml, + .qtip .qtip-tip canvas{ + position: absolute; + + color: #123456; + background: transparent; + border: 0 dashed transparent; + } + + .qtip .qtip-tip canvas{ top: 0; left: 0; } + + .qtip .qtip-tip .qtip-vml{ + behavior: url(#default#VML); + display: inline-block; + visibility: visible; + } + +#qtip-overlay{ + position: fixed; + left: 0; top: 0; + width: 100%; height: 100%; +} + + /* Applied to modals with show.modal.blur set to true */ + #qtip-overlay.blurs{ cursor: pointer; } + + /* Change opacity of overlay here */ + #qtip-overlay div{ + position: absolute; + left: 0; top: 0; + width: 100%; height: 100%; + + background-color: black; + + opacity: 0.7; + filter:alpha(opacity=70); + -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=70)"; + } + + + +.qtipmodal-ie6fix{ + position: absolute !important; +} \ No newline at end of file diff --git a/unused.txt b/unused.txt new file mode 100644 index 00000000..8eab64ea --- /dev/null +++ b/unused.txt @@ -0,0 +1,610 @@ +wqflask/base/data_set.py:32: unused import 'itemgetter' (90% confidence) +wqflask/base/data_set.py:271: unused attribute 'genetic_type' (60% confidence) +wqflask/base/data_set.py:273: unused attribute 'genetic_type' (60% confidence) +wqflask/base/data_set.py:281: unused attribute 'accession_id' (60% confidence) +wqflask/base/data_set.py:282: unused attribute 'mapping_id' (60% confidence) +wqflask/base/data_set.py:282: unused attribute 'mapping_names' (60% confidence) +wqflask/base/data_set.py:319: unused function 'get_specified_markers' (60% confidence) +wqflask/base/data_set.py:460: unused variable 'dataset_sub_menu' (60% confidence) +wqflask/base/data_set.py:463: unused variable 'tissue_position' (60% confidence) +wqflask/base/data_set.py:467: unused variable 'tissue_position' (60% confidence) +wqflask/base/data_set.py:660: unused class 'PhenotypeDataSet' (60% confidence) +wqflask/base/data_set.py:722: unused function 'get_trait_list' (60% confidence) +wqflask/base/data_set.py:751: unreachable code after 'continue' (100% confidence) +wqflask/base/data_set.py:773: unused attribute 'LRS_score_value' (60% confidence) +wqflask/base/data_set.py:775: unused attribute 'LRS_location_value' (60% confidence) +wqflask/base/data_set.py:794: unused variable 'LRS_location_value' (60% confidence) +wqflask/base/data_set.py:797: unused variable 'LRS_location_value' (60% confidence) +wqflask/base/data_set.py:799: unused variable 'LRS_location_value' (60% confidence) +wqflask/base/data_set.py:802: unused attribute 'LRS_score_value' (60% confidence) +wqflask/base/data_set.py:802: unused variable 'LRS_score_value' (60% confidence) +wqflask/base/data_set.py:828: unused class 'GenotypeDataSet' (60% confidence) +wqflask/base/data_set.py:864: unused function 'get_trait_list' (60% confidence) +wqflask/base/data_set.py:884: unused variable 'trait_location_repr' (60% confidence) +wqflask/base/data_set.py:897: unused attribute 'location_value' (60% confidence) +wqflask/base/data_set.py:923: unused class 'MrnaAssayDataSet' (60% confidence) +wqflask/base/data_set.py:992: unused function 'get_trait_list_1' (60% confidence) +wqflask/base/data_set.py:1038: unused variable 'trait_location_repr' (60% confidence) +wqflask/base/data_set.py:1057: unused attribute 'location_value' (60% confidence) +wqflask/base/data_set.py:1079: unused attribute 'LRS_score_value' (60% confidence) +wqflask/base/data_set.py:1081: unused attribute 'LRS_location_value' (60% confidence) +wqflask/base/data_set.py:1097: unused variable 'lrs_location_value' (60% confidence) +wqflask/base/data_set.py:1099: unused attribute 'LRS_score_value' (60% confidence) +wqflask/base/data_set.py:1115: unused function 'get_sequence' (60% confidence) +wqflask/base/data_set.py:1167: unused class 'TempDataSet' (60% confidence) +wqflask/base/data_set.py:1207: unused function 'get_group' (60% confidence) +wqflask/base/data_set.py:1218: unused attribute 'group_id' (60% confidence) +wqflask/base/mrna_assay_tissue_data.py:21: unused attribute 'have_data' (60% confidence) +wqflask/base/species.py:21: unused attribute 'genome_mb_length' (60% confidence) +wqflask/base/species.py:45: unused function 'set_cm_length' (60% confidence) +wqflask/base/species.py:77: unused attribute 'mb_graph_interval' (60% confidence) +wqflask/base/species.py:79: unused attribute 'mb_graph_interval' (60% confidence) +wqflask/base/species.py:94: unused function 'get_genome_cm_length' (60% confidence) +wqflask/base/species.py:99: unused function 'get_cm_length_list' (60% confidence) +wqflask/base/template.py:27: unused variable 'template' (60% confidence) +wqflask/base/trait.py:28: unused function 'print_mem' (60% confidence) +wqflask/base/trait.py:58: unused attribute 'pvalue' (60% confidence) +wqflask/base/trait.py:66: unused attribute 'LRS_score_value' (60% confidence) +wqflask/base/trait.py:68: unused attribute 'LRS_location_value' (60% confidence) +wqflask/base/trait.py:86: unused function 'get_name' (60% confidence) +wqflask/base/trait.py:97: unused function 'get_given_name' (60% confidence) +wqflask/base/trait.py:118: unused function 'display_name' (60% confidence) +wqflask/base/trait.py:148: unused function 'export_data' (60% confidence) +wqflask/base/trait.py:189: unused property 'name_header_fmt' (60% confidence) +wqflask/base/trait.py:201: unused property 'description_fmt' (60% confidence) +wqflask/base/trait.py:220: unused property 'alias_fmt' (60% confidence) +wqflask/base/trait.py:232: unused property 'location_fmt' (60% confidence) +wqflask/base/trait.py:261: unused function 'getSequence' (60% confidence) +wqflask/base/trait.py:309: unused function 'get_sample_data' (60% confidence) +wqflask/base/trait.py:546: unused attribute 'homologeneid' (60% confidence) +wqflask/base/trait.py:575: unused attribute 'homologeneid' (60% confidence) +wqflask/base/trait.py:594: unused attribute 'location_value' (60% confidence) +wqflask/base/trait.py:611: unused attribute 'location_value' (60% confidence) +wqflask/base/trait.py:615: unused attribute 'location_value' (60% confidence) +wqflask/base/trait.py:624: unused attribute 'location_value' (60% confidence) +wqflask/base/trait.py:629: unused attribute 'LRS_score_value' (60% confidence) +wqflask/base/trait.py:631: unused attribute 'LRS_location_value' (60% confidence) +wqflask/base/trait.py:646: unused attribute 'pvalue' (60% confidence) +wqflask/base/trait.py:664: unused attribute 'pvalue' (60% confidence) +wqflask/base/trait.py:704: unused variable 'LRS_location_value' (60% confidence) +wqflask/base/trait.py:707: unused variable 'LRS_location_value' (60% confidence) +wqflask/base/trait.py:709: unused variable 'LRS_location_value' (60% confidence) +wqflask/base/trait.py:714: unused attribute 'LRS_score_value' (60% confidence) +wqflask/base/trait.py:714: unused variable 'LRS_score_value' (60% confidence) +wqflask/base/webqtlCaseData.py:42: unused attribute 'this_id' (60% confidence) +wqflask/base/webqtlCaseData.py:59: unused property 'class_outlier' (60% confidence) +wqflask/base/webqtlCaseData.py:67: unused property 'display_value' (60% confidence) +wqflask/base/webqtlCaseData.py:74: unused property 'display_variance' (60% confidence) +wqflask/base/webqtlConfig.py:24: unused variable 'MULTIPLEMAPPINGLIMIT' (60% confidence) +wqflask/base/webqtlConfig.py:27: unused variable 'MAXCORR' (60% confidence) +wqflask/base/webqtlConfig.py:36: unused variable 'MAXLIFE' (60% confidence) +wqflask/base/webqtlConfig.py:42: unused variable 'NCBI_LOCUSID' (60% confidence) +wqflask/base/webqtlConfig.py:43: unused variable 'UCSC_REFSEQ' (60% confidence) +wqflask/base/webqtlConfig.py:44: unused variable 'GENBANK_ID' (60% confidence) +wqflask/base/webqtlConfig.py:45: unused variable 'OMIM_ID' (60% confidence) +wqflask/base/webqtlConfig.py:46: unused variable 'UNIGEN_ID' (60% confidence) +wqflask/base/webqtlConfig.py:47: unused variable 'HOMOLOGENE_ID' (60% confidence) +wqflask/base/webqtlConfig.py:49: unused variable 'UCSC_POS' (60% confidence) +wqflask/base/webqtlConfig.py:53: unused variable 'UCSC_GENOME' (60% confidence) +wqflask/base/webqtlConfig.py:54: unused variable 'ENSEMBLE_BLAT' (60% confidence) +wqflask/base/webqtlConfig.py:55: unused variable 'DBSNP' (60% confidence) +wqflask/base/webqtlConfig.py:56: unused variable 'UCSC_RUDI_TRACK_URL' (60% confidence) +wqflask/base/webqtlConfig.py:57: unused variable 'GENOMEBROWSER_URL' (60% confidence) +wqflask/base/webqtlConfig.py:58: unused variable 'ENSEMBLETRANSCRIPT_URL' (60% confidence) +wqflask/base/webqtlFormData.py:53: unused variable 'mod_python_session' (60% confidence) +wqflask/base/webqtlFormData.py:54: unused variable 'FieldStorage_formdata' (60% confidence) +wqflask/base/webqtlFormData.py:61: unused attribute 'varianceDispName' (60% confidence) +wqflask/base/webqtlFormData.py:74: unused attribute 'refURL' (60% confidence) +wqflask/base/webqtlFormData.py:76: unused attribute 'refURL' (60% confidence) +wqflask/base/webqtlFormData.py:328: unused function 'Sample' (60% confidence) +wqflask/basicStatistics/BasicStatisticsFunctions.py:21: unused function 'basicStatsTable' (60% confidence) +wqflask/basicStatistics/BasicStatisticsFunctions.py:101: unused function 'plotNormalProbability' (60% confidence) +wqflask/basicStatistics/BasicStatisticsFunctions.py:155: unused function 'plotBarGraph' (60% confidence) +wqflask/basicStatistics/corestats.py:61: unused function 'median' (60% confidence) +wqflask/maintenance/convert_geno_to_bimbam.py:74: unused attribute 'geno_fh' (60% confidence) +wqflask/maintenance/convert_geno_to_bimbam.py:82: unused variable 'row_count' (60% confidence) +wqflask/maintenance/gen_select_dataset.py:69: unused variable 'db_uri' (60% confidence) +wqflask/maintenance/gen_select_dataset.py:302: unused function '_test_it' (60% confidence) +wqflask/maintenance/get_group_samplelists.py:9: unused function 'process_genofiles' (60% confidence) +wqflask/mock/es_double.py:1: unused class 'ESDouble' (60% confidence) +wqflask/run_gunicorn.py:17: unused function 'hello' (60% confidence) +wqflask/utility/after.py:18: unused function 'call_after_request_callbacks' (60% confidence) +wqflask/utility/AJAX_table.py:41: unused class 'AJAX_table' (60% confidence) +wqflask/utility/benchmark.py:6: unused import 'LOG_BENCH' (90% confidence) +wqflask/utility/elasticsearch_tools.py:51: unused variable 'te' (60% confidence) +wqflask/utility/genofile_parser.py:75: unused variable 'row_count' (60% confidence) +wqflask/utility/logger.py:36: unused import 'LOG_FORMAT' (90% confidence) +wqflask/utility/logger.py:59: unused function 'debug20' (60% confidence) +wqflask/utility/logger.py:84: unused function 'infof' (60% confidence) +wqflask/utility/Plot.py:167: unused function 'erf' (60% confidence) +wqflask/utility/Plot.py:182: unused function 'calMeanVar' (60% confidence) +wqflask/utility/Plot.py:370: unused variable 'tstrain' (60% confidence) +wqflask/utility/Plot.py:449: unused function 'plotSecurity' (60% confidence) +wqflask/utility/Plot.py:594: unused variable 'Xll' (60% confidence) +wqflask/utility/Plot.py:595: unused variable 'Xur' (60% confidence) +wqflask/utility/Plot.py:914: unused function 'plotXYSVG' (60% confidence) +wqflask/utility/Plot.py:914: unused variable 'plotColor' (60% confidence) +wqflask/utility/Plot.py:923: unused variable 'dataXAlt' (60% confidence) +wqflask/utility/Plot.py:924: unused variable 'dataYAlt' (60% confidence) +wqflask/utility/Plot.py:929: unused variable 'dataXAlt' (60% confidence) +wqflask/utility/Plot.py:930: unused variable 'dataYAlt' (60% confidence) +wqflask/utility/Plot.py:1030: unused attribute 'argv' (60% confidence) +wqflask/utility/Plot.py:1117: unused variable 'bufferSpace' (60% confidence) +wqflask/utility/Plot.py:1156: unused function 'colorSpectrumOld' (60% confidence) +wqflask/utility/Plot.py:1234: unused function 'colorSpectrumSVG' (60% confidence) +wqflask/utility/Plot.py:1257: unused function 'BWSpectrum' (60% confidence) +wqflask/utility/svg.py:116: unused attribute 'setrecursionlimit' (60% confidence) +wqflask/utility/svg.py:174: unused function '_pointlist' (60% confidence) +wqflask/utility/svg.py:186: unused function 'closepath' (60% confidence) +wqflask/utility/svg.py:189: unused function 'move' (60% confidence) +wqflask/utility/svg.py:192: unused function 'relmove' (60% confidence) +wqflask/utility/svg.py:198: unused function 'relline' (60% confidence) +wqflask/utility/svg.py:201: unused function 'hline' (60% confidence) +wqflask/utility/svg.py:204: unused function 'relhline' (60% confidence) +wqflask/utility/svg.py:207: unused function 'vline' (60% confidence) +wqflask/utility/svg.py:210: unused function 'relvline' (60% confidence) +wqflask/utility/svg.py:213: unused function 'bezier' (60% confidence) +wqflask/utility/svg.py:216: unused function 'relbezier' (60% confidence) +wqflask/utility/svg.py:219: unused function 'smbezier' (60% confidence) +wqflask/utility/svg.py:225: unused function 'qbezier' (60% confidence) +wqflask/utility/svg.py:228: unused function 'relqbezier' (60% confidence) +wqflask/utility/svg.py:231: unused function 'smqbezier' (60% confidence) +wqflask/utility/svg.py:234: unused function 'relsmqbezier' (60% confidence) +wqflask/utility/svg.py:237: unused function 'ellarc' (60% confidence) +wqflask/utility/svg.py:240: unused function 'relellarc' (60% confidence) +wqflask/utility/svg.py:359: unused class 'spannedtext' (60% confidence) +wqflask/utility/svg.py:382: unused function 'addtext' (60% confidence) +wqflask/utility/svg.py:384: unused function 'addtspan' (60% confidence) +wqflask/utility/svg.py:386: unused function 'addtref' (60% confidence) +wqflask/utility/svg.py:494: unused class 'polyline' (60% confidence) +wqflask/utility/svg.py:508: unused class 'polygon' (60% confidence) +wqflask/utility/svg.py:560: unused class 'textpath' (60% confidence) +wqflask/utility/svg.py:612: unused class 'lineargradient' (60% confidence) +wqflask/utility/svg.py:631: unused class 'radialgradient' (60% confidence) +wqflask/utility/svg.py:652: unused class 'stop' (60% confidence) +wqflask/utility/svg.py:662: unused class 'style' (60% confidence) +wqflask/utility/svg.py:671: unused class 'image' (60% confidence) +wqflask/utility/svg.py:747: unused class 'defs' (60% confidence) +wqflask/utility/svg.py:755: unused class 'switch' (60% confidence) +wqflask/utility/svg.py:793: unused class 'view' (60% confidence) +wqflask/utility/svg.py:802: unused class 'script' (60% confidence) +wqflask/utility/svg.py:811: unused class 'animate' (60% confidence) +wqflask/utility/svg.py:837: unused class 'animateTransform' (60% confidence) +wqflask/utility/svg.py:853: unused class 'animateColor' (60% confidence) +wqflask/utility/svg.py:1022: unused function 'validate' (60% confidence) +wqflask/utility/temp_data.py:13: unused function 'store' (60% confidence) +wqflask/utility/tools.py:182: unused function 'locate_phewas' (60% confidence) +wqflask/utility/tools.py:235: unused variable 'HOME' (60% confidence) +wqflask/utility/tools.py:243: unused variable 'LOG_BENCH' (60% confidence) +wqflask/utility/tools.py:244: unused variable 'LOG_FORMAT' (60% confidence) +wqflask/utility/tools.py:248: unused variable 'GENENETWORK_FILES' (60% confidence) +wqflask/utility/tools.py:251: unused variable 'JS_GN_PATH' (60% confidence) +wqflask/utility/webqtlUtil.py:69: unused variable 'IMGSTEP1' (60% confidence) +wqflask/utility/webqtlUtil.py:70: unused variable 'IMGSTEP2' (60% confidence) +wqflask/utility/webqtlUtil.py:71: unused variable 'IMGSTEP3' (60% confidence) +wqflask/utility/webqtlUtil.py:72: unused variable 'IMGNEXT' (60% confidence) +wqflask/utility/webqtlUtil.py:87: unused variable 'PROGRESSBAR' (60% confidence) +wqflask/utility/webqtlUtil.py:157: unused function 'decodeEscape' (60% confidence) +wqflask/utility/webqtlUtil.py:203: unused function 'toInt' (60% confidence) +wqflask/utility/webqtlUtil.py:220: unused function 'transpose' (60% confidence) +wqflask/utility/webqtlUtil.py:225: unused function 'asymTranspose' (60% confidence) +wqflask/utility/webqtlUtil.py:241: unused function 'generate_session' (60% confidence) +wqflask/utility/webqtlUtil.py:245: unused function 'cvt2Dict' (60% confidence) +wqflask/utility/webqtlUtil.py:251: unused function 'dump_session' (60% confidence) +wqflask/utility/webqtlUtil.py:276: unused function 'FloatAsFloat' (60% confidence) +wqflask/utility/webqtlUtil.py:283: unused function 'RemoveZero' (60% confidence) +wqflask/utility/webqtlUtil.py:306: unused function 'FloatList2String' (60% confidence) +wqflask/utility/webqtlUtil.py:332: unused function 'FileDataProcess' (60% confidence) +wqflask/utility/webqtlUtil.py:372: unused function 'cmpScanResult' (60% confidence) +wqflask/utility/webqtlUtil.py:384: unused function 'cmpScanResult2' (60% confidence) +wqflask/utility/webqtlUtil.py:596: unused function 'calCorrelationRankText' (60% confidence) +wqflask/utility/webqtlUtil.py:715: unused function 'calCorrelationText' (60% confidence) +wqflask/utility/webqtlUtil.py:761: unused function 'cmpCorr' (60% confidence) +wqflask/utility/webqtlUtil.py:772: unused function 'cmpLitCorr' (60% confidence) +wqflask/utility/webqtlUtil.py:783: unused function 'cmpPValue' (60% confidence) +wqflask/utility/webqtlUtil.py:811: unused function 'cmpLRSFull' (60% confidence) +wqflask/utility/webqtlUtil.py:822: unused function 'cmpLRSInteract' (60% confidence) +wqflask/utility/webqtlUtil.py:834: unused function 'cmpPos' (60% confidence) +wqflask/utility/webqtlUtil.py:858: unused function 'cmpGenoPos' (60% confidence) +wqflask/utility/webqtlUtil.py:895: unused class 'VisualizeException' (60% confidence) +wqflask/utility/webqtlUtil.py:912: unused function 'safeFloat' (60% confidence) +wqflask/utility/webqtlUtil.py:917: unused function 'safeInt' (60% confidence) +wqflask/utility/webqtlUtil.py:923: unused function 'safeString' (60% confidence) +wqflask/utility/webqtlUtil.py:931: unused function 'yesNoToInt' (60% confidence) +wqflask/utility/webqtlUtil.py:941: unused function 'intToYesNo' (60% confidence) +wqflask/utility/webqtlUtil.py:949: unused function 'formatField' (60% confidence) +wqflask/utility/webqtlUtil.py:971: unused variable 'last_idx' (60% confidence) +wqflask/utility/webqtlUtil.py:981: unused variable 'last_idx' (60% confidence) +wqflask/wqflask/__init__.py:24: unused import 'wqflask' (90% confidence) +wqflask/wqflask/collect.py:43: unused function 'get_collection' (60% confidence) +wqflask/wqflask/collect.py:225: unused function 'collections_add' (60% confidence) +wqflask/wqflask/collect.py:247: unused function 'collections_new' (60% confidence) +wqflask/wqflask/collect.py:285: unused variable 'current_collections' (60% confidence) +wqflask/wqflask/collect.py:291: unused function 'list_collections' (60% confidence) +wqflask/wqflask/collect.py:368: unused function 'view_collection' (60% confidence) +wqflask/wqflask/correlation/corr_scatter_plot.py:22: unused attribute 'width' (60% confidence) +wqflask/wqflask/correlation/corr_scatter_plot.py:28: unused attribute 'height' (60% confidence) +wqflask/wqflask/correlation/corr_scatter_plot.py:34: unused attribute 'circle_color' (60% confidence) +wqflask/wqflask/correlation/corr_scatter_plot.py:40: unused attribute 'circle_radius' (60% confidence) +wqflask/wqflask/correlation/corr_scatter_plot.py:46: unused attribute 'line_color' (60% confidence) +wqflask/wqflask/correlation/corr_scatter_plot.py:52: unused attribute 'line_width' (60% confidence) +wqflask/wqflask/correlation/corr_scatter_plot.py:69: unused variable 'std_err' (60% confidence) +wqflask/wqflask/correlation/corr_scatter_plot.py:76: unused variable 'srstd_err' (60% confidence) +wqflask/wqflask/correlation/corr_scatter_plot.py:107: unused attribute 'jsdata' (60% confidence) +wqflask/wqflask/correlation/correlation_functions.py:45: unused function 'controlStrains' (60% confidence) +wqflask/wqflask/correlation/correlation_functions.py:81: unused function 'fixStrains' (60% confidence) +wqflask/wqflask/correlation/correlation_functions.py:124: unused function 'findIdenticalControlTraits' (60% confidence) +wqflask/wqflask/correlation/correlation_functions.py:150: unused function 'findIdenticalTraits' (60% confidence) +wqflask/wqflask/correlation/correlation_functions.py:185: unused function 'determinePartialsByR' (60% confidence) +wqflask/wqflask/correlation/correlation_functions.py:497: unused function 'calZeroOrderCorr' (60% confidence) +wqflask/wqflask/correlation/correlation_functions.py:502: unused variable 'primary_var' (60% confidence) +wqflask/wqflask/correlation/correlation_functions.py:681: unused function 'getTissueProbeSetXRefInfo' (60% confidence) +wqflask/wqflask/correlation/correlation_functions.py:727: unused variable 'resultCount' (60% confidence) +wqflask/wqflask/correlation/correlation_functions.py:759: unused function 'get_symbol_value_pairs' (60% confidence) +wqflask/wqflask/correlation/correlation_functions.py:881: unused function 'getCorrPvArray' (60% confidence) +wqflask/wqflask/correlation/correlation_functions.py:941: unused function 'calculateCorrOfAllTissueTrait' (60% confidence) +wqflask/wqflask/correlation/show_corr_results.py:26: unused import 'gc' (90% confidence) +wqflask/wqflask/correlation/show_corr_results.py:67: unused variable 'METHOD_SAMPLE_PEARSON' (60% confidence) +wqflask/wqflask/correlation/show_corr_results.py:68: unused variable 'METHOD_SAMPLE_RANK' (60% confidence) +wqflask/wqflask/correlation/show_corr_results.py:77: unused function 'print_mem' (60% confidence) +wqflask/wqflask/correlation/show_corr_results.py:81: unused class 'AuthException' (60% confidence) +wqflask/wqflask/correlation/show_corr_results.py:86: unused variable 'corr_min_informative' (60% confidence) +wqflask/wqflask/correlation/show_corr_results.py:178: unused variable 'cache_available' (60% confidence) +wqflask/wqflask/correlation/show_corr_results.py:264: unused attribute 'tissue_pvalue' (60% confidence) +wqflask/wqflask/correlation/show_corr_results.py:268: unused attribute 'tissue_pvalue' (60% confidence) +wqflask/wqflask/correlation/show_corr_results.py:282: unused attribute 'tissue_pvalue' (60% confidence) +wqflask/wqflask/correlation/show_corr_results.py:286: unused attribute 'tissue_pvalue' (60% confidence) +wqflask/wqflask/correlation/show_corr_results.py:301: unused attribute 'json_results' (60% confidence) +wqflask/wqflask/correlation/show_corr_results.py:356: unused attribute 'formatted_corr_type' (60% confidence) +wqflask/wqflask/correlation/show_corr_results.py:358: unused attribute 'formatted_corr_type' (60% confidence) +wqflask/wqflask/correlation/show_corr_results.py:360: unused attribute 'formatted_corr_type' (60% confidence) +wqflask/wqflask/correlation/show_corr_results.py:362: unused attribute 'formatted_corr_type' (60% confidence) +wqflask/wqflask/correlation/show_corr_results.py:365: unused attribute 'formatted_corr_type' (60% confidence) +wqflask/wqflask/correlation/show_corr_results.py:367: unused attribute 'formatted_corr_type' (60% confidence) +wqflask/wqflask/correlation/show_corr_results.py:399: unused attribute 'tissue_pvalue' (60% confidence) +wqflask/wqflask/correlation/show_corr_results.py:685: unused function 'do_tissue_corr_for_all_traits_2' (60% confidence) +wqflask/wqflask/correlation/show_corr_results.py:739: unused variable 'tissue_probesetfreeze_id' (60% confidence) +wqflask/wqflask/correlation/show_corr_results.py:784: unused variable 'primary_trait_value' (60% confidence) +wqflask/wqflask/correlation/show_corr_results.py:786: unused variable 'symbol_value_dict' (60% confidence) +wqflask/wqflask/correlation/show_corr_results.py:836: unused variable 'tissueProbeSetFreezeId' (60% confidence) +wqflask/wqflask/correlation/show_corr_results.py:930: unused attribute 'p_tissue' (60% confidence) +wqflask/wqflask/correlation/show_corr_results.py:975: unused variable 'mouse_geneid1' (60% confidence) +wqflask/wqflask/correlation/show_corr_results.py:1033: unused function 'get_traits' (60% confidence) +wqflask/wqflask/correlation/show_corr_results.py:1036: unsatisfiable 'if' condition (100% confidence) +wqflask/wqflask/correlation/show_corr_results.py:1039: unused variable 'use_lit' (60% confidence) +wqflask/wqflask/correlation/show_corr_results.py:1042: unused variable 'use_lit' (60% confidence) +wqflask/wqflask/correlation/show_corr_results.py:1044: unused variable 'use_tissue_corr' (60% confidence) +wqflask/wqflask/correlation/show_corr_results.py:1047: unused variable 'use_tissue_corr' (60% confidence) +wqflask/wqflask/correlation/show_corr_results.py:1081: unused attribute 'p_tissue' (60% confidence) +wqflask/wqflask/correlation/show_corr_results.py:1095: unused variable 'totalTraits' (60% confidence) +wqflask/wqflask/correlation/show_corr_results.py:1107: unused variable 'primary_trait_value' (60% confidence) +wqflask/wqflask/correlation/show_corr_results.py:1109: unused variable 'symbol_value_dict' (60% confidence) +wqflask/wqflask/correlation/show_corr_results.py:1125: unused function 'correlate' (60% confidence) +wqflask/wqflask/correlation/show_corr_results.py:1152: unused function 'do_parallel_correlation' (60% confidence) +wqflask/wqflask/correlation_matrix/show_corr_matrix.py:26: unused import 'gc' (90% confidence) +wqflask/wqflask/correlation_matrix/show_corr_matrix.py:177: unused attribute 'pca_works' (60% confidence) +wqflask/wqflask/correlation_matrix/show_corr_matrix.py:179: unused attribute 'loadings_array' (60% confidence) +wqflask/wqflask/correlation_matrix/show_corr_matrix.py:181: unused attribute 'pca_works' (60% confidence) +wqflask/wqflask/correlation_matrix/show_corr_matrix.py:218: unused attribute 'scores' (60% confidence) +wqflask/wqflask/correlation_matrix/show_corr_matrix.py:219: unused attribute 'scale' (60% confidence) +wqflask/wqflask/ctl/ctl_analysis.py:5: unused import 'sp' (90% confidence) +wqflask/wqflask/ctl/ctl_analysis.py:27: unused variable 'utils' (60% confidence) +wqflask/wqflask/ctl/ctl_analysis.py:32: unused variable 'r_read_csv' (60% confidence) +wqflask/wqflask/ctl/ctl_analysis.py:33: unused variable 'r_dim' (60% confidence) +wqflask/wqflask/ctl/ctl_analysis.py:37: unused variable 'r_paste' (60% confidence) +wqflask/wqflask/ctl/ctl_analysis.py:39: unused variable 'r_head' (60% confidence) +wqflask/wqflask/ctl/ctl_analysis.py:44: unused variable 'r_matrix' (60% confidence) +wqflask/wqflask/ctl/ctl_analysis.py:45: unused variable 'r_seq' (60% confidence) +wqflask/wqflask/ctl/ctl_analysis.py:47: unused variable 'r_names' (60% confidence) +wqflask/wqflask/ctl/ctl_analysis.py:48: unused variable 'r_sink' (60% confidence) +wqflask/wqflask/ctl/ctl_analysis.py:49: unused variable 'r_is_NA' (60% confidence) +wqflask/wqflask/ctl/ctl_analysis.py:50: unused variable 'r_file' (60% confidence) +wqflask/wqflask/ctl/ctl_analysis.py:53: unused variable 'r_save_image' (60% confidence) +wqflask/wqflask/ctl/ctl_analysis.py:54: unused variable 'r_class' (60% confidence) +wqflask/wqflask/ctl/ctl_analysis.py:55: unused variable 'r_save' (60% confidence) +wqflask/wqflask/ctl/ctl_analysis.py:56: unused variable 'r_write_table' (60% confidence) +wqflask/wqflask/ctl/ctl_analysis.py:57: unused variable 'r_read_table' (60% confidence) +wqflask/wqflask/ctl/ctl_analysis.py:58: unused variable 'r_as_data_frame' (60% confidence) +wqflask/wqflask/ctl/ctl_analysis.py:75: unused attribute 'r_CTLnetwork' (60% confidence) +wqflask/wqflask/ctl/ctl_analysis.py:76: unused attribute 'r_CTLprofiles' (60% confidence) +wqflask/wqflask/database.py:26: unused import 'wqflask' (90% confidence) +wqflask/wqflask/do_search.py:82: unused class 'QuickMrnaAssaySearch' (60% confidence) +wqflask/wqflask/do_search.py:178: unused function 'run_combined' (60% confidence) +wqflask/wqflask/do_search.py:286: unused function 'run_combined' (60% confidence) +wqflask/wqflask/do_search.py:314: unused class 'QuickPhenotypeSearch' (60% confidence) +wqflask/wqflask/do_search.py:433: unused class 'RifSearch' (60% confidence) +wqflask/wqflask/do_search.py:456: unused class 'WikiSearch' (60% confidence) +wqflask/wqflask/do_search.py:481: unused class 'GoSearch' (60% confidence) +wqflask/wqflask/do_search.py:588: unused class 'MrnaLrsSearch' (60% confidence) +wqflask/wqflask/do_search.py:601: unused class 'PhenotypeLrsSearch' (60% confidence) +wqflask/wqflask/do_search.py:685: unused class 'CisLrsSearch' (60% confidence) +wqflask/wqflask/do_search.py:715: unused class 'TransLrsSearch' (60% confidence) +wqflask/wqflask/do_search.py:745: unused class 'MeanSearch' (60% confidence) +wqflask/wqflask/do_search.py:770: unused function 'get_final_query' (60% confidence) +wqflask/wqflask/do_search.py:786: unused class 'RangeSearch' (60% confidence) +wqflask/wqflask/do_search.py:861: unused class 'MrnaPositionSearch' (60% confidence) +wqflask/wqflask/do_search.py:874: unused class 'GenotypePositionSearch' (60% confidence) +wqflask/wqflask/do_search.py:920: unused class 'AuthorSearch' (60% confidence) +wqflask/wqflask/docs.py:14: unused attribute 'entry' (60% confidence) +wqflask/wqflask/docs.py:16: unused attribute 'content' (60% confidence) +wqflask/wqflask/export_traits.py:3: unused import 'operator' (90% confidence) +wqflask/wqflask/heatmap/heatmap.py:6: unused import 'gc' (90% confidence) +wqflask/wqflask/heatmap/heatmap.py:19: unused import 'linalg' (90% confidence) +wqflask/wqflask/heatmap/heatmap.py:148: unused attribute 'lrs_array' (60% confidence) +wqflask/wqflask/heatmap/heatmap.py:225: unused function 'gen_pylmm_results' (60% confidence) +wqflask/wqflask/interval_analyst/GeneUtil.py:9: unused variable 'webqtlDb' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression.py:19: unused import 'linalg' (90% confidence) +wqflask/wqflask/marker_regression/marker_regression.py:84: unused attribute 'geno_db_exists' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression.py:87: unused variable 'geno_dataset' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression.py:88: unused attribute 'geno_db_exists' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression.py:90: unused attribute 'geno_db_exists' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression.py:116: unused attribute 'bootstrap_results' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression.py:120: unused attribute 'selected_chr' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression.py:123: unused attribute 'selected_chr' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression.py:125: unused attribute 'selected_chr' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression.py:135: unused attribute 'haplotypeAnalystCheck' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression.py:143: unused attribute 'LRSCheck' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression.py:146: unused attribute 'showSNP' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression.py:148: unused attribute 'showSNP' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression.py:151: unused attribute 'showGenes' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression.py:153: unused attribute 'showGenes' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression.py:156: unused attribute 'viewLegend' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression.py:158: unused attribute 'viewLegend' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression.py:170: unused attribute 'showSNP' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression.py:171: unused attribute 'showGenes' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression.py:172: unused attribute 'viewLegend' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression.py:203: unused attribute 'additiveCheck' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression.py:205: unused attribute 'additiveCheck' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression.py:213: unused attribute 'additiveCheck' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression.py:228: unused attribute 'bootstrap_results' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression.py:262: unused attribute 'trimmed_markers' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression.py:281: unused attribute 'cutoff' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression.py:293: unused attribute 'trimmed_markers' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression.py:500: unused function 'trim_results' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression.py:565: unused function 'get_lod_score_cutoff' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression.py:600: unused function 'create_snp_iterator_file' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression.py:605: unreachable code after 'raise' (100% confidence) +wqflask/wqflask/marker_regression/marker_regression.py:655: unused variable 'num_markers' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:33: unused import 'urllib' (90% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:55: unused variable 'maxBootStrap' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:84: unused variable 'MIN_PIXELS_BETWEEN_LABELS' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:96: unused variable 'ALEX_DEBUG_BOOL_COLORIZE_GENES' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:99: unused variable 'kWIDTH_DEFAULT' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:108: unused variable 'GENE_FILL_COLOR' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:109: unused variable 'GENE_OUTLINE_COLOR' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:112: unused variable 'LRS_LINE_WIDTH' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:119: unused variable 'ADDITIVE_COLOR' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:130: unused variable 'QMARK_EDGE_COLOR' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:131: unused variable 'QMARK_FILL_COLOR' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:134: unused variable 'X_AXIS_LABEL_COLOR' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:136: unused variable 'MINI_VIEW_MAGNIFIED_REGION_COLOR' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:137: unused variable 'MINI_VIEW_OUTSIDE_REGION_COLOR' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:138: unused variable 'MINI_VIEW_BORDER_COLOR' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:157: unused variable 'DRAW_UTR_LABELS' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:177: unused attribute 'geno_db_exists' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:185: unused attribute 'mapmethod_rqtl_geno' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:186: unused attribute 'mapmodel_rqtl_geno' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:191: unused attribute 'trimmed_markers' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:311: unused attribute 'cutoff' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:442: unused attribute 'dataSource' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:557: unused variable 'geneTableContainer' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:578: unused attribute 'gifmap' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:587: unused variable 'gifmapX2' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:622: unused attribute 'perm_filename' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:689: unused attribute 'body' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:695: unused function 'writeQTL2Text' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:801: unused variable 'startPixelX' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:802: unused variable 'endPixelX' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:1111: unused variable 'locLocation' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:1146: unused variable 'locLocation' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:1190: unused variable 'lod' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:1192: unused variable 'lod' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:1208: unused variable 'string3' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:1239: unused variable 'displayStartInBases' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:1240: unused variable 'displayEndInBases' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:1256: unused variable 'geneId' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:1310: unused variable 'geneId' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:1343: unreachable 'else' block (100% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:1347: unused variable 'utrColor' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:1453: unused variable 'widthMultiplier' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:1457: unused variable 'exprdrawn' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:1559: unreachable 'else' block (100% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:1691: unused variable 'bandWidth' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:1729: unused variable 'traitX' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:1737: unused variable 'traitX' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:1764: unused variable 'spacingFromLineToLabel' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:1770: unused variable 'graphMbWidth' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:2261: unused variable 'maxAdd' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:2353: unused function 'calculateAllResult' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:2365: unused attribute 'chromosome' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:2426: unused attribute 'chromosome' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:2459: unused attribute 'chromosome' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:2490: unused function 'traitRemapTD' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:2609: unused function 'traitInfoTD' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:2679: unused function 'permutationTextFile' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:2704: unused attribute 'gene_table_header' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:2705: unused attribute 'gene_table_body' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:2719: unused attribute 'gene_table_header' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:2720: unused attribute 'gene_table_body' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:2727: unused variable 'gene_tblobj_header' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:2731: unused variable 'col_class' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:2831: unused variable 'className' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:2884: unused variable 'mouseStartValue' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:2896: unused variable 'humanChrSort' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:2898: unused variable 'humanChrSort' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:2900: unused variable 'humanChrSort' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:2904: unused variable 'humanStartValue' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:2908: unused variable 'humanChrSort' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:2908: unused variable 'humanStartValue' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:2927: unused variable 'polymiRTS' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:2929: unused variable 'polymiRTS' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:2938: unused variable 'literatureCorrelation' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:2940: unused variable 'literatureCorrelation' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:3045: unused variable 'humanChrSort' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:3047: unused variable 'humanChrSort' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:3049: unused variable 'humanChrSort' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:3052: unused variable 'humanChrSort' (60% confidence) +wqflask/wqflask/marker_regression/marker_regression_gn1.py:3110: unused function 'getSortByValue' (60% confidence) +wqflask/wqflask/marker_regression/MarkerRegressionPage.py:31: unused import 'urllib' (90% confidence) +wqflask/wqflask/marker_regression/MarkerRegressionPage.py:48: unused class 'MarkerRegressionPage' (60% confidence) +wqflask/wqflask/marker_regression/MarkerRegressionPage.py:621: unused variable 'startPixelX' (60% confidence) +wqflask/wqflask/marker_regression/MarkerRegressionPage.py:622: unused variable 'endPixelX' (60% confidence) +wqflask/wqflask/marker_regression/MarkerRegressionPage.py:667: unused variable 'startPixelX' (60% confidence) +wqflask/wqflask/marker_regression/MarkerRegressionPage.py:668: unused variable 'endPixelX' (60% confidence) +wqflask/wqflask/marker_regression/MarkerRegressionPage.py:1001: unused variable 'maxAdd' (60% confidence) +wqflask/wqflask/marker_regression/MarkerRegressionPage.py:1164: unused variable 'spacingFromLineToLabel' (60% confidence) +wqflask/wqflask/marker_regression/MarkerRegressionPage.py:1170: unused variable 'graphMbWidth' (60% confidence) +wqflask/wqflask/marker_regression/MarkerRegressionPage.py:1245: unused variable 'spacingFromLineToLabel' (60% confidence) +wqflask/wqflask/marker_regression/MarkerRegressionPage.py:1251: unused variable 'graphMbWidth' (60% confidence) +wqflask/wqflask/marker_regression/plink_mapping.py:111: unused variable 'header_line' (60% confidence) +wqflask/wqflask/marker_regression/qtlreaper_mapping.py:29: unused variable 'highly_significant' (60% confidence) +wqflask/wqflask/marker_regression/rqtl_mapping.py:14: unused variable 'r_sum' (60% confidence) +wqflask/wqflask/marker_regression/rqtl_mapping.py:16: unused variable 'postscript' (60% confidence) +wqflask/wqflask/marker_regression/rqtl_mapping.py:26: unused variable 'read_cross' (60% confidence) +wqflask/wqflask/marker_regression/rqtl_mapping.py:27: unused variable 'write_cross' (60% confidence) +wqflask/wqflask/model.py:9: unused import 'SQLAlchemy' (90% confidence) +wqflask/wqflask/model.py:15: unused import 'Integer' (90% confidence) +wqflask/wqflask/model.py:15: unused import 'String' (90% confidence) +wqflask/wqflask/model.py:15: unused import 'Table' (90% confidence) +wqflask/wqflask/model.py:17: unused import 'backref' (90% confidence) +wqflask/wqflask/model.py:45: unused variable 'active' (60% confidence) +wqflask/wqflask/model.py:47: unused variable 'registration_info' (60% confidence) +wqflask/wqflask/model.py:65: unused function 'display_num_collections' (60% confidence) +wqflask/wqflask/model.py:99: unused property 'login_count' (60% confidence) +wqflask/wqflask/model.py:104: unused property 'confirmed_at' (60% confidence) +wqflask/wqflask/model.py:112: unused property 'superuser_info' (60% confidence) +wqflask/wqflask/model.py:119: unused property 'crowner' (60% confidence) +wqflask/wqflask/model.py:129: unused property 'most_recent_login' (60% confidence) +wqflask/wqflask/model.py:146: unused variable 'ip_address' (60% confidence) +wqflask/wqflask/model.py:147: unused variable 'successful' (60% confidence) +wqflask/wqflask/model.py:155: unused attribute 'ip_address' (60% confidence) +wqflask/wqflask/model.py:195: unused function 'user_uuid' (60% confidence) +wqflask/wqflask/model.py:197: unused variable 'user_uuid' (60% confidence) +wqflask/wqflask/network_graph/network_graph.py:26: unused import 'gc' (90% confidence) +wqflask/wqflask/network_graph/network_graph.py:98: unused attribute 'network_data' (60% confidence) +wqflask/wqflask/news.py:16: unused attribute 'newslist' (60% confidence) +wqflask/wqflask/search_results.py:121: unused attribute 'json_trait_list' (60% confidence) +wqflask/wqflask/send_mail.py:41: unused attribute 'From' (60% confidence) +wqflask/wqflask/send_mail.py:42: unused attribute 'To' (60% confidence) +wqflask/wqflask/send_mail.py:43: unused attribute 'Subject' (60% confidence) +wqflask/wqflask/send_mail.py:44: unused attribute 'Body' (60% confidence) +wqflask/wqflask/show_trait/export_trait_data.py:3: unused import 'operator' (90% confidence) +wqflask/wqflask/show_trait/SampleList.py:28: unused attribute 'sample_group_type' (60% confidence) +wqflask/wqflask/show_trait/SampleList.py:29: unused attribute 'header' (60% confidence) +wqflask/wqflask/show_trait/SampleList.py:66: unused attribute 'this_id' (60% confidence) +wqflask/wqflask/show_trait/SampleList.py:68: unused attribute 'this_id' (60% confidence) +wqflask/wqflask/show_trait/show_trait.py:27: unused import 'BasicStatisticsFunctions' (90% confidence) +wqflask/wqflask/show_trait/show_trait.py:123: unused attribute 'UCSC_BLAT_URL' (60% confidence) +wqflask/wqflask/show_trait/show_trait.py:124: unused attribute 'UTHSC_BLAT_URL' (60% confidence) +wqflask/wqflask/show_trait/show_trait.py:126: unused attribute 'UCSC_BLAT_URL' (60% confidence) +wqflask/wqflask/show_trait/show_trait.py:127: unused attribute 'UTHSC_BLAT_URL' (60% confidence) +wqflask/wqflask/show_trait/show_trait.py:129: unused attribute 'UCSC_BLAT_URL' (60% confidence) +wqflask/wqflask/show_trait/show_trait.py:130: unused attribute 'UTHSC_BLAT_URL' (60% confidence) +wqflask/wqflask/show_trait/show_trait.py:132: unused attribute 'UCSC_BLAT_URL' (60% confidence) +wqflask/wqflask/show_trait/show_trait.py:133: unused attribute 'UTHSC_BLAT_URL' (60% confidence) +wqflask/wqflask/show_trait/show_trait.py:135: unused attribute 'UCSC_BLAT_URL' (60% confidence) +wqflask/wqflask/show_trait/show_trait.py:136: unused attribute 'UTHSC_BLAT_URL' (60% confidence) +wqflask/wqflask/show_trait/show_trait.py:183: unused attribute 'hddn' (60% confidence) +wqflask/wqflask/show_trait/show_trait.py:198: unused attribute 'stats_table_width' (60% confidence) +wqflask/wqflask/show_trait/show_trait.py:198: unused attribute 'trait_table_width' (60% confidence) +wqflask/wqflask/show_trait/show_trait.py:232: unused attribute 'genofiles' (60% confidence) +wqflask/wqflask/show_trait/show_trait.py:233: unused attribute 'use_plink_gemma' (60% confidence) +wqflask/wqflask/show_trait/show_trait.py:234: unused attribute 'use_pylmm_rqtl' (60% confidence) +wqflask/wqflask/show_trait/show_trait.py:262: unused attribute 'corr_tools' (60% confidence) +wqflask/wqflask/show_trait/show_trait_page.py:41: unused class 'ShowTraitPage' (60% confidence) +wqflask/wqflask/show_trait/show_trait_page.py:44: unused attribute 'fd' (60% confidence) +wqflask/wqflask/show_trait/show_trait_page.py:67: unused variable 'indId' (60% confidence) +wqflask/wqflask/show_trait/show_trait_page.py:67: unused variable 'indName' (60% confidence) +wqflask/wqflask/show_trait/show_trait_page.py:138: unused attribute 'display_variance' (60% confidence) +wqflask/wqflask/show_trait/show_trait_page.py:139: unused attribute 'formID' (60% confidence) +wqflask/wqflask/tracer.py:37: unused function 'turn_on' (60% confidence) +wqflask/wqflask/user_manager.py:69: unused function 'add_collection' (60% confidence) +wqflask/wqflask/user_manager.py:123: unused function 'display_num_collections' (60% confidence) +wqflask/wqflask/user_manager.py:259: unused attribute 'thank_you_mode' (60% confidence) +wqflask/wqflask/user_manager.py:299: unused attribute 'registration_info' (60% confidence) +wqflask/wqflask/user_manager.py:305: unused attribute 'algorithm' (60% confidence) +wqflask/wqflask/user_manager.py:316: unused attribute 'created_ts' (60% confidence) +wqflask/wqflask/user_manager.py:411: unused function 'verify_email' (60% confidence) +wqflask/wqflask/user_manager.py:425: unused function 'password_reset' (60% confidence) +wqflask/wqflask/user_manager.py:456: unused function 'password_reset_step2' (60% confidence) +wqflask/wqflask/user_manager.py:497: unused function 'reencode_standalone' (60% confidence) +wqflask/wqflask/user_manager.py:519: unused function 'github_oauth2' (60% confidence) +wqflask/wqflask/user_manager.py:549: unused function 'orcid_oauth2' (60% confidence) +wqflask/wqflask/user_manager.py:606: unused attribute 'login_type' (60% confidence) +wqflask/wqflask/user_manager.py:691: unused attribute 'successful' (60% confidence) +wqflask/wqflask/user_manager.py:693: unused attribute 'assumed_by' (60% confidence) +wqflask/wqflask/user_manager.py:715: unused attribute 'successful' (60% confidence) +wqflask/wqflask/user_manager.py:719: unused function 'logout' (60% confidence) +wqflask/wqflask/user_manager.py:730: unused function 'forgot_password' (60% confidence) +wqflask/wqflask/user_manager.py:735: unused function 'forgot_password_submit' (60% confidence) +wqflask/wqflask/user_manager.py:755: unused function 'unauthorized' (60% confidence) +wqflask/wqflask/user_manager.py:770: unused function 'manage_users' (60% confidence) +wqflask/wqflask/user_manager.py:776: unused function 'manage_user' (60% confidence) +wqflask/wqflask/user_manager.py:782: unused function 'manage_groups' (60% confidence) +wqflask/wqflask/user_manager.py:788: unused function 'make_superuser' (60% confidence) +wqflask/wqflask/user_manager.py:801: unused function 'assume_identity' (60% confidence) +wqflask/wqflask/user_manager.py:811: unused function 'register' (60% confidence) +wqflask/wqflask/user_manager.py:921: unused class 'RolesManager' (60% confidence) +wqflask/wqflask/views.py:17: unused import 'gc' (90% confidence) +wqflask/wqflask/views.py:23: unused import 'yaml' (90% confidence) +wqflask/wqflask/views.py:70: unused import 'werkzeug' (90% confidence) +wqflask/wqflask/views.py:77: unused function 'connect_db' (60% confidence) +wqflask/wqflask/views.py:82: unused attribute '_database' (60% confidence) +wqflask/wqflask/views.py:85: unused function 'shutdown_session' (60% confidence) +wqflask/wqflask/views.py:86: unused variable 'exception' (60% confidence) +wqflask/wqflask/views.py:98: unused function 'handle_bad_request' (60% confidence) +wqflask/wqflask/views.py:104: unused variable 'exc_traceback' (60% confidence) +wqflask/wqflask/views.py:104: unused variable 'exc_type' (60% confidence) +wqflask/wqflask/views.py:104: unused variable 'exc_value' (60% confidence) +wqflask/wqflask/views.py:123: unused function 'index_page' (60% confidence) +wqflask/wqflask/views.py:140: unused function 'tmp_page' (60% confidence) +wqflask/wqflask/views.py:154: unused function 'cytoscape' (60% confidence) +wqflask/wqflask/views.py:158: unused function 'twitter' (60% confidence) +wqflask/wqflask/views.py:178: unused function 'search_page' (60% confidence) +wqflask/wqflask/views.py:219: unused function 'gsearchact' (60% confidence) +wqflask/wqflask/views.py:229: unused function 'gsearch_updating' (60% confidence) +wqflask/wqflask/views.py:241: unused function 'docedit' (60% confidence) +wqflask/wqflask/views.py:247: unused function 'generated_file' (60% confidence) +wqflask/wqflask/views.py:252: unused function 'help' (60% confidence) +wqflask/wqflask/views.py:258: unused function 'wcgna_setup' (60% confidence) +wqflask/wqflask/views.py:264: unused function 'wcgna_results' (60% confidence) +wqflask/wqflask/views.py:273: unused function 'ctl_setup' (60% confidence) +wqflask/wqflask/views.py:279: unused function 'ctl_results' (60% confidence) +wqflask/wqflask/views.py:288: unused function 'news_route' (60% confidence) +wqflask/wqflask/views.py:293: unused function 'references' (60% confidence) +wqflask/wqflask/views.py:299: unused function 'intro' (60% confidence) +wqflask/wqflask/views.py:304: unused function 'policies' (60% confidence) +wqflask/wqflask/views.py:309: unused function 'links' (60% confidence) +wqflask/wqflask/views.py:314: unused function 'environments' (60% confidence) +wqflask/wqflask/views.py:319: unused function 'submit_trait_form' (60% confidence) +wqflask/wqflask/views.py:325: unused function 'create_temp_trait' (60% confidence) +wqflask/wqflask/views.py:335: unused function 'export_trait_excel' (60% confidence) +wqflask/wqflask/views.py:361: unused function 'export_trait_csv' (60% confidence) +wqflask/wqflask/views.py:382: unused function 'export_traits_csv' (60% confidence) +wqflask/wqflask/views.py:394: unused function 'export_perm_data' (60% confidence) +wqflask/wqflask/views.py:418: unused function 'show_temp_trait_page' (60% confidence) +wqflask/wqflask/views.py:433: unused function 'show_trait_page' (60% confidence) +wqflask/wqflask/views.py:448: unused function 'heatmap_page' (60% confidence) +wqflask/wqflask/views.py:495: unused function 'mapping_results_container_page' (60% confidence) +wqflask/wqflask/views.py:499: unused function 'loading_page' (60% confidence) +wqflask/wqflask/views.py:556: unused function 'marker_regression_page' (60% confidence) +wqflask/wqflask/views.py:696: unused function 'export' (60% confidence) +wqflask/wqflask/views.py:706: unused function 'export_pdf' (60% confidence) +wqflask/wqflask/views.py:714: unused variable 'filepath' (60% confidence) +wqflask/wqflask/views.py:720: unused function 'network_graph_page' (60% confidence) +wqflask/wqflask/views.py:736: unused function 'corr_compute_page' (60% confidence) +wqflask/wqflask/views.py:744: unused function 'corr_matrix_page' (60% confidence) +wqflask/wqflask/views.py:761: unused function 'corr_scatter_plot_page' (60% confidence) +wqflask/wqflask/views.py:770: unused function 'submit_bnw' (60% confidence) +wqflask/wqflask/views.py:786: unused function 'get_temp_data' (60% confidence) +wqflask/wqflask/wgcna/wgcna_analysis.py:5: unused import 'sp' (90% confidence) +wqflask/wqflask/wgcna/wgcna_analysis.py:18: unused variable 'utils' (60% confidence) +wqflask/wqflask/wgcna/wgcna_analysis.py:23: unused variable 'r_read_csv' (60% confidence) +wqflask/wqflask/wgcna/wgcna_analysis.py:24: unused variable 'r_dim' (60% confidence) +wqflask/wqflask/wgcna/wgcna_analysis.py:27: unused variable 'r_paste' (60% confidence) +wqflask/wqflask/wgcna/wgcna_analysis.py:33: unused variable 'r_matrix' (60% confidence) +wqflask/wqflask/wgcna/wgcna_analysis.py:34: unused variable 'r_seq' (60% confidence) +wqflask/wqflask/wgcna/wgcna_analysis.py:36: unused variable 'r_names' (60% confidence) +wqflask/wqflask/wgcna/wgcna_analysis.py:37: unused variable 'r_sink' (60% confidence) +wqflask/wqflask/wgcna/wgcna_analysis.py:38: unused variable 'r_is_NA' (60% confidence) +wqflask/wqflask/wgcna/wgcna_analysis.py:39: unused variable 'r_file' (60% confidence) diff --git a/wqflask/utility/tools.py b/wqflask/utility/tools.py index 59bb49d8..ea216a35 100644 --- a/wqflask/utility/tools.py +++ b/wqflask/utility/tools.py @@ -285,10 +285,16 @@ TEMPDIR = tempdir() # defaults to UNIX TMPDIR assert_dir(TEMPDIR) # ---- Handle specific JS modules +JS_GUIX_PATH = get_setting("JS_GUIX_PATH") +assert_dir(JS_GUIX_PATH) +assert_dir(JS_GUIX_PATH+'/cytoscape-panzoom') +CSS_PATH = "UNKNOWN" +# assert_dir(JS_PATH) JS_TWITTER_POST_FETCHER_PATH = get_setting("JS_TWITTER_POST_FETCHER_PATH",js_path("Twitter-Post-Fetcher")) assert_dir(JS_TWITTER_POST_FETCHER_PATH) - -from six import string_types +assert_file(JS_TWITTER_POST_FETCHER_PATH+"/js/twitterFetcher_min.js") +JS_CYTOSCAPE_PATH = get_setting("JS_CYTOSCAPE_PATH",js_path("cytoscape")) +assert_dir(JS_CYTOSCAPE_PATH) +assert_file(JS_CYTOSCAPE_PATH+'/cytoscape.min.js') # assert_file(PHEWAS_FILES+"/auwerx/PheWAS_pval_EMMA_norm.RData") -assert_file(JS_TWITTER_POST_FETCHER_PATH+"/js/twitterFetcher_min.js") diff --git a/wqflask/wqflask/templates/ctl_results.html b/wqflask/wqflask/templates/ctl_results.html index 969ca18a..d85075a9 100644 --- a/wqflask/wqflask/templates/ctl_results.html +++ b/wqflask/wqflask/templates/ctl_results.html @@ -1,7 +1,7 @@ {% extends "base.html" %} {% block css %} - + {% endblock %} {% block content %} - + {{ header("Network Graph") }}
@@ -39,7 +39,7 @@ {% endfor %} - + Correlation Coefficient ? @@ -69,9 +69,9 @@ - + - +

Download

@@ -102,11 +102,19 @@ - - - - - + + + + + + + + {% endblock %} diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index a65924d8..3c2cca94 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -54,7 +54,7 @@ from wqflask.ctl import ctl_analysis #from wqflask.trait_submission import submit_trait 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 +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 from utility.helper_functions import get_species_groups from base import webqtlFormData @@ -151,6 +151,14 @@ def tmp_page(img_path): return render_template("show_image.html", img_base64 = bytesarray ) +@app.route("/js/") +def js(filename): + return send_from_directory(JS_GUIX_PATH, filename) + +@app.route("/css/") +def css(filename): + return send_from_directory(CSS_PATH, filename) + @app.route("/twitter/") def twitter(filename): return send_from_directory(JS_TWITTER_POST_FETCHER_PATH, filename) -- cgit v1.2.3