diff options
author | Frederick Muriuki Muriithi | 2023-06-16 10:53:08 +0300 |
---|---|---|
committer | Frederick Muriuki Muriithi | 2023-06-20 13:36:50 +0300 |
commit | 883a7cba581f34eba48978746e2ff8bbb93020d8 (patch) | |
tree | 433c1b0b6db451b841810b2fdb4f2fd07bc9377b | |
parent | 7127095f2b2c54175d1360c1ddb3e0f87b6ede98 (diff) | |
download | genenetwork2-883a7cba581f34eba48978746e2ff8bbb93020d8.tar.gz |
Add `create_app()` application factory
Create the application and set up configs and other things within an
application factory function.
Fix obvious egregious errors preventing the application from starting
up correctly.
-rw-r--r-- | wqflask/base/data_set/__init__.py | 2 | ||||
-rw-r--r-- | wqflask/base/data_set/datasetgroup.py | 3 | ||||
-rw-r--r-- | wqflask/gn2_main.py | 60 | ||||
-rw-r--r-- | wqflask/run_gunicorn.py | 2 | ||||
-rw-r--r-- | wqflask/runserver.py | 2 | ||||
-rw-r--r-- | wqflask/utility/authentication_tools.py | 4 | ||||
-rw-r--r-- | wqflask/utility/startup_config.py | 4 | ||||
-rw-r--r-- | wqflask/wqflask/__init__.py | 172 | ||||
-rw-r--r-- | wqflask/wqflask/app_errors.py | 5 | ||||
-rw-r--r-- | wqflask/wqflask/oauth2/client.py | 34 | ||||
-rw-r--r-- | wqflask/wqflask/oauth2/request_utils.py | 7 | ||||
-rw-r--r-- | wqflask/wqflask/templates/base.html | 18 | ||||
-rw-r--r-- | wqflask/wqflask/templates/search_result_page.html | 24 | ||||
-rw-r--r-- | wqflask/wqflask/templates/show_trait.html | 30 | ||||
-rw-r--r-- | wqflask/wqflask/templates/tool_buttons.html | 2 | ||||
-rw-r--r-- | wqflask/wqflask/views.py | 1 |
16 files changed, 188 insertions, 182 deletions
diff --git a/wqflask/base/data_set/__init__.py b/wqflask/base/data_set/__init__.py index ad51e47e..c2c0aef1 100644 --- a/wqflask/base/data_set/__init__.py +++ b/wqflask/base/data_set/__init__.py @@ -115,7 +115,7 @@ def datasets(group_name, this_group=None, redis_conn=Redis()): dataset_menu.append(dict(tissue=tissue_name, datasets=[(dataset, dataset_short)])) - if get_setting_bool("USE_REDIS"): + if get_setting_bool(app, "USE_REDIS"): redis_conn.set(key, pickle.dumps(dataset_menu, pickle.HIGHEST_PROTOCOL)) redis_conn.expire(key, 60 * 5) diff --git a/wqflask/base/data_set/datasetgroup.py b/wqflask/base/data_set/datasetgroup.py index 90c59a1e..a44cf18d 100644 --- a/wqflask/base/data_set/datasetgroup.py +++ b/wqflask/base/data_set/datasetgroup.py @@ -15,6 +15,7 @@ from wqflask.database import database_connection from utility.configuration import ( locate, flat_files, + get_setting, flat_file_exists, get_setting_bool, locate_ignore_error) @@ -128,7 +129,7 @@ class DatasetGroup: return study_samples def get_genofiles(self): - jsonfile = "%s/%s.json" % (webqtlConfig.GENODIR, self.name) + jsonfile = "%s/%s.json" % (get_setting(app, "WEBQTL_GENODIR"), self.name) try: f = open(jsonfile) except: diff --git a/wqflask/gn2_main.py b/wqflask/gn2_main.py new file mode 100644 index 00000000..923a35d3 --- /dev/null +++ b/wqflask/gn2_main.py @@ -0,0 +1,60 @@ +"""Main app creation module""" +import time + +from flask import g, session, request + +from wqflask import create_app +from wqflask.user_session import UserSession +from gn3.authentication import DataRole, AdminRole + +app = create_app() + +@app.before_request +def before_request(): + g.request_start_time = time.time() + g.request_time = lambda: "%.5fs" % (time.time() - g.request_start_time) + + token = session.get("oauth2_token", False) + if token and not bool(session.get("user_details", False)): + config = current_app.config + client = OAuth2Session( + config["OAUTH2_CLIENT_ID"], config["OAUTH2_CLIENT_SECRET"], + token=token) + resp = client.get( + urljoin(config["GN_SERVER_URL"], "oauth2/user")) + user_details = resp.json() + session["user_details"] = user_details + + if user_details.get("error") == "invalid_token": + flash(user_details["error_description"], "alert-danger") + flash("You are now logged out.", "alert-info") + session.pop("user_details", None) + session.pop("oauth2_token", None) + +@app.context_processor +def include_admin_role_class(): + return {'AdminRole': AdminRole} + + +@app.context_processor +def include_data_role_class(): + return {'DataRole': DataRole} + +@app.before_request +def get_user_session(): + g.user_session = UserSession() + # I think this should solve the issue of deleting the cookie and redirecting to the home page when a user's session has expired + if not g.user_session: + response = make_response(redirect(url_for('login'))) + response.set_cookie('session_id_v2', '', expires=0) + return response + +@app.after_request +def set_user_session(response): + if hasattr(g, 'user_session'): + if not request.cookies.get(g.user_session.cookie_name): + response.set_cookie(g.user_session.cookie_name, + g.user_session.cookie) + else: + response.set_cookie('session_id_v2', '', expires=0) + return response diff --git a/wqflask/run_gunicorn.py b/wqflask/run_gunicorn.py index 03f310eb..af117466 100644 --- a/wqflask/run_gunicorn.py +++ b/wqflask/run_gunicorn.py @@ -9,7 +9,7 @@ print("===> Starting up Gunicorn process") -from wqflask import app +from gn2_main import app from utility.startup_config import app_config app_config() diff --git a/wqflask/runserver.py b/wqflask/runserver.py index 8f01425e..fed3d356 100644 --- a/wqflask/runserver.py +++ b/wqflask/runserver.py @@ -7,7 +7,7 @@ # # /sbin/iptables -A INPUT -p tcp -i eth0 -s ! 71.236.239.43 --dport 5003 -j DROP -from wqflask import app +from gn2_main import app from utility.startup_config import app_config from utility.configuration import get_setting, get_setting_int diff --git a/wqflask/utility/authentication_tools.py b/wqflask/utility/authentication_tools.py index 3d732228..0f48d26f 100644 --- a/wqflask/utility/authentication_tools.py +++ b/wqflask/utility/authentication_tools.py @@ -37,7 +37,7 @@ def check_resource_availability(dataset, user_id, trait_id=None): return webqtlConfig.SUPER_PRIVILEGES response = None - the_url = f"{get_setting('GN_PROXY_URL')}available?resource={resource_id}&user={user_id}" + the_url = f"{get_setting(app, 'GN_PROXY_URL')}available?resource={resource_id}&user={user_id}" try: response = json.loads(requests.get(the_url).content) except: @@ -94,7 +94,7 @@ def get_group_code(dataset): def check_admin(resource_id=None): the_url = ( - f"{get_setting('GN_PROXY_URL')}available?resource={resource_id}" + f"{get_setting(app, 'GN_PROXY_URL')}available?resource={resource_id}" f"&user={g.user_session.user_id}") try: response = json.loads(requests.get(the_url).content)['admin'] diff --git a/wqflask/utility/startup_config.py b/wqflask/utility/startup_config.py index 5ab43b1a..59f78d55 100644 --- a/wqflask/utility/startup_config.py +++ b/wqflask/utility/startup_config.py @@ -1,6 +1,4 @@ - -from wqflask import app - +"""Utility to print out some startup messages.""" from utility.configuration import show_settings from utility.configuration import get_setting_int from utility.configuration import get_setting diff --git a/wqflask/wqflask/__init__.py b/wqflask/wqflask/__init__.py index 86370183..3b7551e6 100644 --- a/wqflask/wqflask/__init__.py +++ b/wqflask/wqflask/__init__.py @@ -17,8 +17,6 @@ from utility.tools import set_mandatory_settings from utility.hmac import data_hmac, url_for_hmac from utility.configuration import tempdir, override_from_envvars -from gn3.authentication import DataRole, AdminRole - from wqflask.database import parse_db_url from wqflask.user_session import UserSession from wqflask.group_manager import group_management @@ -42,115 +40,6 @@ from wqflask.oauth2.request_utils import user_details, authserver_authorise_uri from wqflask.jupyter_notebooks import jupyter_notebooks -app = Flask(__name__) - - -# See http://flask.pocoo.org/docs/config/#configuring-from-files -# Note no longer use the badly named WQFLASK_OVERRIDES (nyi) -app.config.from_envvar('GN2_SETTINGS') - -DB_HOST, DB_USER, DB_PASS, DB_NAME, DB_PORT = parse_db_url(app.config.get('SQL_URI')) -app.config["DB_HOST"] = DB_HOST -app.config["DB_USER"] = DB_USER -app.config["DB_PASS"] = DB_PASS -app.config["DB_NAME"] = DB_NAME -app.config["DB_PORT"] = DB_PORT - -app.jinja_env.globals.update( - undefined=jinja2.StrictUndefined, - numify=formatting.numify, - logged_in=user_logged_in, - authserver_authorise_uri=authserver_authorise_uri, - user_details=user_details, - num_collections=num_collections, - url_for_hmac=url_for_hmac, - data_hmac=data_hmac) - -app.config["SESSION_REDIS"] = redis.from_url(app.config["REDIS_URL"]) - -# Override settings -app = override_from_envvars(app) -app = set_mandatory_settings(app) -app = webqtlConfig.init_app(app) - -# Registering blueprints -app.register_blueprint(toplevel) -app.register_blueprint(glossary_blueprint, url_prefix="/glossary") -app.register_blueprint(references_blueprint, url_prefix="/references") -app.register_blueprint(links_blueprint, url_prefix="/links") -app.register_blueprint(policies_blueprint, url_prefix="/policies") -app.register_blueprint(environments_blueprint, url_prefix="/environments") -app.register_blueprint(facilities_blueprint, url_prefix="/facilities") -app.register_blueprint(blogs_blueprint, url_prefix="/blogs") -app.register_blueprint(news_blueprint, url_prefix="/news") -app.register_blueprint(jupyter_notebooks, url_prefix="/jupyter_notebooks") - -app.register_blueprint(resource_management, url_prefix="/resource-management") -app.register_blueprint(metadata_edit, url_prefix="/datasets/") -app.register_blueprint(group_management, url_prefix="/group-management") -app.register_blueprint(jobs_bp, url_prefix="/jobs") -app.register_blueprint(oauth2, url_prefix="/oauth2") - -from wqflask.decorators import AuthorisationError -from wqflask.app_errors import ( - handle_generic_exceptions, handle_authorisation_error) -app.register_error_handler(Exception, handle_generic_exceptions) -app.register_error_handler(AuthorisationError, handle_authorisation_error) - -server_session = Session(app) - -@app.before_request -def before_request(): - g.request_start_time = time.time() - g.request_time = lambda: "%.5fs" % (time.time() - g.request_start_time) - - token = session.get("oauth2_token", False) - if token and not bool(session.get("user_details", False)): - config = current_app.config - client = OAuth2Session( - config["OAUTH2_CLIENT_ID"], config["OAUTH2_CLIENT_SECRET"], - token=token) - resp = client.get( - urljoin(config["GN_SERVER_URL"], "oauth2/user")) - user_details = resp.json() - session["user_details"] = user_details - - if user_details.get("error") == "invalid_token": - flash(user_details["error_description"], "alert-danger") - flash("You are now logged out.", "alert-info") - session.pop("user_details", None) - session.pop("oauth2_token", None) - -@app.context_processor -def include_admin_role_class(): - return {'AdminRole': AdminRole} - - -@app.context_processor -def include_data_role_class(): - return {'DataRole': DataRole} - -@app.before_request -def get_user_session(): - g.user_session = UserSession() - # I think this should solve the issue of deleting the cookie and redirecting to the home page when a user's session has expired - if not g.user_session: - response = make_response(redirect(url_for('login'))) - response.set_cookie('session_id_v2', '', expires=0) - return response - - -@app.after_request -def set_user_session(response): - if hasattr(g, 'user_session'): - if not request.cookies.get(g.user_session.cookie_name): - response.set_cookie(g.user_session.cookie_name, - g.user_session.cookie) - else: - response.set_cookie('session_id_v2', '', expires=0) - return response - - from wqflask import group_manager from wqflask import resource_manager from wqflask import search_results @@ -160,5 +49,62 @@ from wqflask import update_search_results from wqflask import docs from wqflask import db_info -import wqflask.views -import wqflask.partial_correlations_views +def create_app(): + """Create the application object.""" + app = Flask(__name__) + + + # See http://flask.pocoo.org/docs/config/#configuring-from-files + # Note no longer use the badly named WQFLASK_OVERRIDES (nyi) + app.config.from_envvar('GN2_SETTINGS') + + DB_HOST, DB_USER, DB_PASS, DB_NAME, DB_PORT = parse_db_url(app.config.get('SQL_URI')) + app.config["DB_HOST"] = DB_HOST + app.config["DB_USER"] = DB_USER + app.config["DB_PASS"] = DB_PASS + app.config["DB_NAME"] = DB_NAME + app.config["DB_PORT"] = DB_PORT + + app.jinja_env.globals.update( + undefined=jinja2.StrictUndefined, + numify=formatting.numify, + logged_in=user_logged_in, + authserver_authorise_uri=authserver_authorise_uri, + user_details=user_details, + num_collections=num_collections, + url_for_hmac=url_for_hmac, + data_hmac=data_hmac) + + app.config["SESSION_REDIS"] = redis.from_url(app.config["REDIS_URL"]) + + # Override settings + app = override_from_envvars(app) + app = set_mandatory_settings(app) + app = webqtlConfig.init_app(app) + + # Registering blueprints + app.register_blueprint(toplevel) + app.register_blueprint(glossary_blueprint, url_prefix="/glossary") + app.register_blueprint(references_blueprint, url_prefix="/references") + app.register_blueprint(links_blueprint, url_prefix="/links") + app.register_blueprint(policies_blueprint, url_prefix="/policies") + app.register_blueprint(environments_blueprint, url_prefix="/environments") + app.register_blueprint(facilities_blueprint, url_prefix="/facilities") + app.register_blueprint(blogs_blueprint, url_prefix="/blogs") + app.register_blueprint(news_blueprint, url_prefix="/news") + app.register_blueprint(jupyter_notebooks, url_prefix="/jupyter_notebooks") + + app.register_blueprint(resource_management, url_prefix="/resource-management") + app.register_blueprint(metadata_edit, url_prefix="/datasets/") + app.register_blueprint(group_management, url_prefix="/group-management") + app.register_blueprint(jobs_bp, url_prefix="/jobs") + app.register_blueprint(oauth2, url_prefix="/oauth2") + + from wqflask.decorators import AuthorisationError + from wqflask.app_errors import ( + handle_generic_exceptions, handle_authorisation_error) + app.register_error_handler(Exception, handle_generic_exceptions) + app.register_error_handler(AuthorisationError, handle_authorisation_error) + + server_session = Session(app) + return app diff --git a/wqflask/wqflask/app_errors.py b/wqflask/wqflask/app_errors.py index c24fc9be..0a1f87ec 100644 --- a/wqflask/wqflask/app_errors.py +++ b/wqflask/wqflask/app_errors.py @@ -1,9 +1,12 @@ """Handle errors at the application's top-level""" +import os +import sys +import random import datetime import traceback import werkzeug -from flask import request, render_template, current_app as app +from flask import request, make_response, render_template, current_app as app from wqflask.decorators import AuthorisationError diff --git a/wqflask/wqflask/oauth2/client.py b/wqflask/wqflask/oauth2/client.py index 2a06b156..91cbb3e9 100644 --- a/wqflask/wqflask/oauth2/client.py +++ b/wqflask/wqflask/oauth2/client.py @@ -9,6 +9,8 @@ from pymonad.maybe import Just, Maybe, Nothing from pymonad.either import Left, Right, Either from authlib.integrations.requests_client import OAuth2Session +from utility.configuration import get_setting + from wqflask.oauth2 import session from wqflask.oauth2.checks import user_logged_in @@ -17,10 +19,9 @@ SCOPE = ("profile group role resource register-client user masquerade " def oauth2_client(): def __client__(token) -> OAuth2Session: - from utility.tools import ( - GN_SERVER_URL, OAUTH2_CLIENT_ID, OAUTH2_CLIENT_SECRET) return OAuth2Session( - OAUTH2_CLIENT_ID, OAUTH2_CLIENT_SECRET, + get_setting(app, "OAUTH2_CLIENT_ID"), + get_setting(app, "OAUTH2_CLIENT_SECRET"), scope=SCOPE, token_endpoint_auth_method="client_secret_post", token=token) return session.user_token().either( @@ -39,13 +40,12 @@ def __no_token__(_err) -> Left: def oauth2_get(uri_path: str, data: dict = {}, **kwargs) -> Either: def __get__(token) -> Either: - from utility.tools import ( - GN_SERVER_URL, OAUTH2_CLIENT_ID, OAUTH2_CLIENT_SECRET) client = OAuth2Session( - OAUTH2_CLIENT_ID, OAUTH2_CLIENT_SECRET, + get_setting(app, "OAUTH2_CLIENT_ID"), + get_setting(app, "OAUTH2_CLIENT_SECRET"), token=token, scope=SCOPE) resp = client.get( - urljoin(GN_SERVER_URL, uri_path), + urljoin(get_setting(app, "GN_SERVER_URL"), uri_path), data=data, **kwargs) if resp.status_code == 200: @@ -59,13 +59,13 @@ def oauth2_post( uri_path: str, data: Optional[dict] = None, json: Optional[dict] = None, **kwargs) -> Either: def __post__(token) -> Either: - from utility.tools import ( - GN_SERVER_URL, OAUTH2_CLIENT_ID, OAUTH2_CLIENT_SECRET) client = OAuth2Session( - OAUTH2_CLIENT_ID, OAUTH2_CLIENT_SECRET, + get_setting(app, "OAUTH2_CLIENT_ID"), + get_setting(app, "OAUTH2_CLIENT_SECRET"), token=token, scope=SCOPE) resp = client.post( - urljoin(GN_SERVER_URL, uri_path), data=data, json=json, + urljoin(get_setting(app, "GN_SERVER_URL"), uri_path), + data=data, json=json, **kwargs) if resp.status_code == 200: return Right(resp.json()) @@ -75,22 +75,20 @@ def oauth2_post( return session.user_token().either(__no_token__, __post__) def no_token_get(uri_path: str, **kwargs) -> Either: - from utility.tools import GN_SERVER_URL - resp = requests.get(urljoin(GN_SERVER_URL, uri_path), **kwargs) + resp = requests.get(urljoin( + get_setting(app, "GN_SERVER_URL"), uri_path), **kwargs) if resp.status_code == 200: return Right(resp.json()) return Left(resp) def no_token_post(uri_path: str, **kwargs) -> Either: - from utility.tools import ( - GN_SERVER_URL, OAUTH2_CLIENT_ID, OAUTH2_CLIENT_SECRET) data = kwargs.get("data", {}) the_json = kwargs.get("json", {}) request_data = { **data, **the_json, - "client_id": OAUTH2_CLIENT_ID, - "client_secret": OAUTH2_CLIENT_SECRET + "client_id": get_setting(app, "OAUTH2_CLIENT_ID"), + "client_secret": get_setting(app, "OAUTH2_CLIENT_SECRET") } new_kwargs = { **{ @@ -99,7 +97,7 @@ def no_token_post(uri_path: str, **kwargs) -> Either: }, ("data" if bool(data) else "json"): request_data } - resp = requests.post(urljoin(GN_SERVER_URL, uri_path), + resp = requests.post(urljoin(get_setting(app, "GN_SERVER_URL"), uri_path), **new_kwargs) if resp.status_code == 200: return Right(resp.json()) diff --git a/wqflask/wqflask/oauth2/request_utils.py b/wqflask/wqflask/oauth2/request_utils.py index 992720f1..b7d57ad8 100644 --- a/wqflask/wqflask/oauth2/request_utils.py +++ b/wqflask/wqflask/oauth2/request_utils.py @@ -7,16 +7,17 @@ from flask import ( flash, request, session, url_for, redirect, Response, render_template, current_app as app) +from utility.configuration import get_setting + from .client import SCOPE, oauth2_get def authserver_authorise_uri(): - from utility.tools import GN_SERVER_URL, OAUTH2_CLIENT_ID req_baseurl = urlparse(request.base_url) host_uri = f"{req_baseurl.scheme}://{req_baseurl.netloc}/" return urljoin( - GN_SERVER_URL, + get_setting(app, "GN_SERVER_URL"), "oauth2/authorise?response_type=code" - f"&client_id={OAUTH2_CLIENT_ID}" + f"&client_id={get_setting(app, 'OAUTH2_CLIENT_ID')}" f"&redirect_uri={urljoin(host_uri, 'oauth2/code')}") def raise_unimplemented(): diff --git a/wqflask/wqflask/templates/base.html b/wqflask/wqflask/templates/base.html index 1328d229..5a881f51 100644 --- a/wqflask/wqflask/templates/base.html +++ b/wqflask/wqflask/templates/base.html @@ -12,7 +12,7 @@ </script> <link rel="icon" type="image/png" sizes="64x64" href="/static/new/images/CITGLogo.png"> <link rel="apple-touch-icon" type="image/png" sizes="64x64" href="/static/new/images/CITGLogo.png"> - <link REL="stylesheet" TYPE="text/css" href="{{ url_for('css', filename='bootstrap/css/bootstrap.css') }}" /> + <link REL="stylesheet" TYPE="text/css" href="{{ url_for('toplevel.main_views.css', filename='bootstrap/css/bootstrap.css') }}" /> <link REL="stylesheet" TYPE="text/css" href="/static/new/css/bootstrap-custom.css" /> <link REL="stylesheet" TYPE="text/css" href="/static/new/css/non-responsive.css" /> <link REL="stylesheet" TYPE="text/css" href="/static/new/css/docs.css" /> @@ -30,10 +30,10 @@ border-radius: 1rem; } table.dataTable thead .sorting_asc { - background-image: url({{ url_for("js", filename="DataTables/images/sort_asc_disabled.png") }}); + background-image: url({{ url_for("toplevel.main_views.js", filename="DataTables/images/sort_asc_disabled.png") }}); } table.dataTable thead .sorting_desc { - background-image: url({{ url_for("js", filename="DataTables/images/sort_desc_disabled.png") }}); + background-image: url({{ url_for("toplevel.main_views.js", filename="DataTables/images/sort_desc_disabled.png") }}); } @@ -336,8 +336,8 @@ <!-- <button class="btn btn-primary">Save changes</button>--> <!--</div>--> </div> - <script src="{{ url_for('js', filename='jquery/jquery.min.js') }}" type="text/javascript"></script> - <script src="{{ url_for('js', filename='bootstrap/js/bootstrap.min.js') }}" type="text/javascript"></script> + <script src="{{ url_for('toplevel.main_views.js', filename='jquery/jquery.min.js') }}" type="text/javascript"></script> + <script src="{{ url_for('toplevel.main_views.js', filename='bootstrap/js/bootstrap.min.js') }}" type="text/javascript"></script> <script src="/static/new/javascript/search_autocomplete.js"></script> <script> //http://stackoverflow.com/questions/11521763/bootstrap-scrollspy-not-working @@ -389,11 +389,11 @@ }); </script> - <script src="{{ url_for('js', filename='jquery-cookie/jquery.cookie.js') }}" type="text/javascript"></script> + <script src="{{ url_for('toplevel.main_views.js', filename='jquery-cookie/jquery.cookie.js') }}" type="text/javascript"></script> <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script> - <!-- <script src="{{ url_for('js', filename='jquery-ui/jquery-ui.min.js') }}" type="text/javascript"></script> --> - <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='colorbox/jquery.colorbox-min.js') }}"></script> - <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='js_alt/parsley.min.js') }}"></script> + <!-- <script src="{{ url_for('toplevel.main_views.js', filename='jquery-ui/jquery-ui.min.js') }}" type="text/javascript"></script> --> + <script language="javascript" type="text/javascript" src="{{ url_for('toplevel.main_views.js', filename='colorbox/jquery.colorbox-min.js') }}"></script> + <script language="javascript" type="text/javascript" src="{{ url_for('toplevel.main_views.js', filename='js_alt/parsley.min.js') }}"></script> {% block js %} {% endblock %} <script type="text/javascript"> diff --git a/wqflask/wqflask/templates/search_result_page.html b/wqflask/wqflask/templates/search_result_page.html index 495c5669..fb92b9ed 100644 --- a/wqflask/wqflask/templates/search_result_page.html +++ b/wqflask/wqflask/templates/search_result_page.html @@ -1,10 +1,10 @@ {% extends "base.html" %} {% block title %}Search Results{% endblock %} {% block css %} - <link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='DataTables/css/jquery.dataTables.css') }}" /> - <link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='fontawesome/css/font-awesome.min.css') }}" /> - <link rel="stylesheet" type="text/css" href="{{ url_for('js', filename='DataTablesExtensions/buttonStyles/css/buttons.dataTables.min.css') }}"> - <link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='fontawesome/css/all.min.css') }}"/> + <link rel="stylesheet" type="text/css" href="{{ url_for('toplevel.main_views.css', filename='DataTables/css/jquery.dataTables.css') }}" /> + <link rel="stylesheet" type="text/css" href="{{ url_for('toplevel.main_views.css', filename='fontawesome/css/font-awesome.min.css') }}" /> + <link rel="stylesheet" type="text/css" href="{{ url_for('toplevel.main_views.js', filename='DataTablesExtensions/buttonStyles/css/buttons.dataTables.min.css') }}"> + <link rel="stylesheet" type="text/css" href="{{ url_for('toplevel.main_views.css', filename='fontawesome/css/all.min.css') }}"/> <link href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet" type="text/css" /> <link rel="stylesheet" type="text/css" href="/static/new/css/show_trait.css" /> <link rel="stylesheet" type="text/css" href="static/new/css/trait_list.css" /> @@ -153,14 +153,14 @@ {% endblock %} {% block js %} - <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='js_alt/md5.min.js') }}"></script> - <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTables/js/jquery.dataTables.min.js') }}"></script> - <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/scroller/js/dataTables.scroller.min.js') }}"></script> - <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='jszip/jszip.min.js') }}"></script> - <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/plugins/sorting/natural.js') }}"></script> - <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/buttons/js/dataTables.buttons.min.js') }}"></script> - <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/buttons/js/buttons.colVis.min.js') }}"></script> - <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='fontawesome/js/all.min.js') }}"></script> + <script language="javascript" type="text/javascript" src="{{ url_for('toplevel.main_views.js', filename='js_alt/md5.min.js') }}"></script> + <script language="javascript" type="text/javascript" src="{{ url_for('toplevel.main_views.js', filename='DataTables/js/jquery.dataTables.min.js') }}"></script> + <script language="javascript" type="text/javascript" src="{{ url_for('toplevel.main_views.js', filename='DataTablesExtensions/scroller/js/dataTables.scroller.min.js') }}"></script> + <script language="javascript" type="text/javascript" src="{{ url_for('toplevel.main_views.js', filename='jszip/jszip.min.js') }}"></script> + <script language="javascript" type="text/javascript" src="{{ url_for('toplevel.main_views.js', filename='DataTablesExtensions/plugins/sorting/natural.js') }}"></script> + <script language="javascript" type="text/javascript" src="{{ url_for('toplevel.main_views.js', filename='DataTablesExtensions/buttons/js/dataTables.buttons.min.js') }}"></script> + <script language="javascript" type="text/javascript" src="{{ url_for('toplevel.main_views.js', filename='DataTablesExtensions/buttons/js/buttons.colVis.min.js') }}"></script> + <script language="javascript" type="text/javascript" src="{{ url_for('toplevel.main_views.js', filename='fontawesome/js/all.min.js') }}"></script> <script language="javascript" type="text/javascript" src="/static/new/javascript/search_results.js"></script> <script language="javascript" type="text/javascript" src="/static/new/javascript/table_functions.js"></script> diff --git a/wqflask/wqflask/templates/show_trait.html b/wqflask/wqflask/templates/show_trait.html index 84231d34..3b3a8ac7 100644 --- a/wqflask/wqflask/templates/show_trait.html +++ b/wqflask/wqflask/templates/show_trait.html @@ -8,9 +8,9 @@ <link rel="stylesheet" type="text/css" href="/static/new/css/box_plot.css" /> <link rel="stylesheet" type="text/css" href="/static/new/css/prob_plot.css" /> <link rel="stylesheet" type="text/css" href="/static/new/css/scatter-matrix.css" /> - <link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='d3-tip/d3-tip.css') }}" /> - <link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='DataTables/css/jquery.dataTables.css') }}" /> - <link rel="stylesheet" type="text/css" href="{{ url_for('css', filename='nouislider/nouislider.min.css') }}" /> + <link rel="stylesheet" type="text/css" href="{{ url_for('toplevel.main_views.css', filename='d3-tip/d3-tip.css') }}" /> + <link rel="stylesheet" type="text/css" href="{{ url_for('toplevel.main_views.css', filename='DataTables/css/jquery.dataTables.css') }}" /> + <link rel="stylesheet" type="text/css" href="{{ url_for('toplevel.main_views.css', filename='nouislider/nouislider.min.css') }}" /> <link href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet" type="text/css" /> <link rel="stylesheet" type="text/css" href="/static/new/css/trait_list.css" /> <link rel="stylesheet" type="text/css" href="/static/new/css/show_trait.css" /> @@ -139,13 +139,13 @@ $('.collapse').collapse() </script> - <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='d3js/d3.min.js') }}"></script> - <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='js_alt/underscore.min.js') }}"></script> - <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='underscore-string/underscore.string.min.js') }}"></script> - <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='d3-tip/d3-tip.js') }}"></script> - <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='js_alt/jstat.min.js') }}"></script> - <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='shapiro-wilk/shapiro-wilk.js') }}"></script> - <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='plotly/plotly.min.js') }}"></script> + <script language="javascript" type="text/javascript" src="{{ url_for('toplevel.main_views.js', filename='d3js/d3.min.js') }}"></script> + <script language="javascript" type="text/javascript" src="{{ url_for('toplevel.main_views.js', filename='js_alt/underscore.min.js') }}"></script> + <script language="javascript" type="text/javascript" src="{{ url_for('toplevel.main_views.js', filename='underscore-string/underscore.string.min.js') }}"></script> + <script language="javascript" type="text/javascript" src="{{ url_for('toplevel.main_views.js', filename='d3-tip/d3-tip.js') }}"></script> + <script language="javascript" type="text/javascript" src="{{ url_for('toplevel.main_views.js', filename='js_alt/jstat.min.js') }}"></script> + <script language="javascript" type="text/javascript" src="{{ url_for('toplevel.main_views.js', filename='shapiro-wilk/shapiro-wilk.js') }}"></script> + <script language="javascript" type="text/javascript" src="{{ url_for('toplevel.main_views.js', filename='plotly/plotly.min.js') }}"></script> <script language="javascript" type="text/javascript" src="/static/new/javascript/colorbrewer.js"></script> <script language="javascript" type="text/javascript" src="/static/new/javascript/stats.js"></script> @@ -154,11 +154,11 @@ <script language="javascript" type="text/javascript" src="/static/new/javascript/compare_traits_scatterplot.js"></script> - <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTables/js/jquery.dataTables.js') }}"></script> - <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/plugins/sorting/scientific.js') }}"></script> - <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/plugins/sorting/natural.js') }}"></script> - <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='DataTablesExtensions/scroller/js/dataTables.scroller.min.js') }}"></script> - <script language="javascript" type="text/javascript" src="{{ url_for('js', filename='nouislider/nouislider.js') }}"></script> + <script language="javascript" type="text/javascript" src="{{ url_for('toplevel.main_views.js', filename='DataTables/js/jquery.dataTables.js') }}"></script> + <script language="javascript" type="text/javascript" src="{{ url_for('toplevel.main_views.js', filename='DataTablesExtensions/plugins/sorting/scientific.js') }}"></script> + <script language="javascript" type="text/javascript" src="{{ url_for('toplevel.main_views.js', filename='DataTablesExtensions/plugins/sorting/natural.js') }}"></script> + <script language="javascript" type="text/javascript" src="{{ url_for('toplevel.main_views.js', filename='DataTablesExtensions/scroller/js/dataTables.scroller.min.js') }}"></script> + <script language="javascript" type="text/javascript" src="{{ url_for('toplevel.main_views.js', filename='nouislider/nouislider.js') }}"></script> <script language="javascript" type="text/javascript" src="/static/new/javascript/table_functions.js"></script> <script language="javascript" type="text/javascript" src="/static/new/javascript/create_datatable.js"></script> <script language="javascript" type="text/javascript" src="/static/new/javascript/initialize_show_trait_tables.js"></script> diff --git a/wqflask/wqflask/templates/tool_buttons.html b/wqflask/wqflask/templates/tool_buttons.html index c6d1476c..95064dbb 100644 --- a/wqflask/wqflask/templates/tool_buttons.html +++ b/wqflask/wqflask/templates/tool_buttons.html @@ -32,7 +32,7 @@ <button id="partial-correlations" class="btn btn-primary submit_special" - data-url="{{url_for('partial_correlations')}}" + data-url="{{url_for('toplevel.partial_correlations.partial_correlations')}}" title="Run partial correlations with the selected traits"> Partial Correlations </button> diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py index ebd273af..689e3436 100644 --- a/wqflask/wqflask/views.py +++ b/wqflask/wqflask/views.py @@ -30,7 +30,6 @@ from flask import current_app as app from flask import g from flask import Response from flask import request -from flask import make_response from flask import render_template from flask import send_from_directory from flask import redirect |