about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--uploader/__init__.py12
-rw-r--r--uploader/base_routes.py5
-rw-r--r--uploader/default_settings.py4
-rw-r--r--uploader/expression_data/views.py2
-rw-r--r--uploader/flask_extensions.py33
-rw-r--r--uploader/genotypes/views.py2
-rw-r--r--uploader/oauth2/views.py2
-rw-r--r--uploader/phenotypes/views.py4
-rw-r--r--uploader/platforms/views.py2
-rw-r--r--uploader/population/views.py2
-rw-r--r--uploader/publications/views.py2
-rw-r--r--uploader/route_utils.py2
-rw-r--r--uploader/samples/views.py2
-rw-r--r--uploader/species/views.py12
-rw-r--r--uploader/templates/base.html2
-rw-r--r--uploader/templates/macro-forms.html9
-rw-r--r--uploader/templates/populations/sui-base.html3
-rw-r--r--uploader/templates/populations/sui-view-population.html9
-rw-r--r--uploader/templates/species/sui-base.html2
-rw-r--r--uploader/templates/species/sui-view-species.html1
-rw-r--r--uploader/templates/sui-base.html2
-rw-r--r--uploader/templates/sui-index.html4
22 files changed, 82 insertions, 36 deletions
diff --git a/uploader/__init__.py b/uploader/__init__.py
index b7f0ab9..7425b38 100644
--- a/uploader/__init__.py
+++ b/uploader/__init__.py
@@ -22,6 +22,7 @@ from .files.views import files
 from .species import speciesbp
 from .publications import pubbp
 from .oauth2.views import oauth2
+from .flask_extensions import url_for
 from .expression_data import exprdatabp
 from .errors import register_error_handlers
 from .background_jobs import background_jobs_bp
@@ -109,17 +110,22 @@ def create_app(config: Optional[dict] = None):
     setup_logging(app)
     setup_modules_logging(app.logger, (
         "uploader.base_routes",
+        "uploader.flask_extensions",
         "uploader.publications.models",
         "uploader.publications.datatables",
         "uploader.phenotypes.models"))
 
     # setup jinja2 symbols
-    app.add_template_global(lambda : request.url, name="request_url")
+    app.add_template_global(user_logged_in)
+    app.add_template_global(url_for, name="url_for")
     app.add_template_global(authserver_authorise_uri)
+    app.add_template_global(lambda : request.url, name="request_url")
     app.add_template_global(lambda: app.config["GN2_SERVER_URL"],
                             name="gn2server_uri")
-    app.add_template_global(user_logged_in)
-    app.add_template_global(lambda : session.user_details()["email"], name="user_email")
+    app.add_template_global(lambda : session.user_details()["email"],
+                            name="user_email")
+    app.add_template_global(lambda: app.config["FEATURE_FLAGS_HTTP"],
+                            name="http_feature_flags")
 
     Session(app)
 
diff --git a/uploader/base_routes.py b/uploader/base_routes.py
index 3d0e1b2..80a15a0 100644
--- a/uploader/base_routes.py
+++ b/uploader/base_routes.py
@@ -6,12 +6,12 @@ from urllib.parse import urljoin
 from gn_libs.mysqldb import database_connection
 from flask import (flash,
                    request,
-                   url_for,
                    redirect,
                    Blueprint,
                    current_app as app,
                    send_from_directory)
 
+from uploader.flask_extensions import url_for
 from uploader.ui import make_template_renderer
 from uploader.oauth2.client import user_logged_in
 from uploader.species.models import all_species, species_by_id
@@ -53,8 +53,7 @@ def index():
             return redirect(url_for("base.index", streamlined_ui=streamlined_ui))
 
         return redirect(url_for("species.view_species",
-                                species_id=species["SpeciesId"],
-                                streamlined_ui=streamlined_ui))
+                                species_id=species["SpeciesId"]))
 
 
 def appenv():
diff --git a/uploader/default_settings.py b/uploader/default_settings.py
index c5986ab..bb3a967 100644
--- a/uploader/default_settings.py
+++ b/uploader/default_settings.py
@@ -29,3 +29,7 @@ SESSION_FILESYSTEM_CACHE_HASH_METHOD = None # default: hashlib.md5
 
 JWKS_ROTATION_AGE_DAYS = 7 # Days (from creation) to keep a JWK in use.
 JWKS_DELETION_AGE_DAYS = 14 # Days (from creation) to keep a JWK around before deleting it.
+
+
+## --- Feature flags ---
+FEATURE_FLAGS_HTTP = []
diff --git a/uploader/expression_data/views.py b/uploader/expression_data/views.py
index 7629f3e..0b318b7 100644
--- a/uploader/expression_data/views.py
+++ b/uploader/expression_data/views.py
@@ -11,7 +11,6 @@ from werkzeug.utils import secure_filename
 from gn_libs.mysqldb import database_connection
 from flask import (flash,
                    request,
-                   url_for,
                    redirect,
                    Blueprint,
                    current_app as app)
@@ -19,6 +18,7 @@ from flask import (flash,
 from quality_control.errors import InvalidValue, DuplicateHeading
 
 from uploader import jobs
+from uploader.flask_extensions import url_for
 from uploader.datautils import order_by_family
 from uploader.ui import make_template_renderer
 from uploader.authorisation import require_login
diff --git a/uploader/flask_extensions.py b/uploader/flask_extensions.py
new file mode 100644
index 0000000..30fbad7
--- /dev/null
+++ b/uploader/flask_extensions.py
@@ -0,0 +1,33 @@
+"""Custom extensions to the default flask functions/classes."""
+import logging
+from typing import Any, Optional
+
+from flask import (request, current_app as app, url_for as flask_url_for)
+
+logger = logging.getLogger(__name__)
+
+
+def url_for(
+        endpoint: str,
+        _anchor: Optional[str] = None,
+        _method: Optional[str] = None,
+        _scheme: Optional[str] = None,
+        _external: Optional[bool] = None,
+        **values: Any) -> str:
+    """Extension to flask's `url_for` function."""
+    flags = {}
+    for flag in app.config["FEATURE_FLAGS_HTTP"]:
+        flag_value = (request.args.get(flag) or request.form.get(flag) or "").strip()
+        if bool(flag_value):
+            flags[flag] = flag_value
+            continue
+        continue
+
+    logger.debug("HTTP FEATURE FLAGS: %s, other variables: %s", flags, values)
+    return flask_url_for(endpoint=endpoint,
+                         _anchor=_anchor,
+                         _method=_method,
+                         _scheme=_scheme,
+                         _external=_external,
+                         **values,
+                         **flags)
diff --git a/uploader/genotypes/views.py b/uploader/genotypes/views.py
index 54c2444..d991614 100644
--- a/uploader/genotypes/views.py
+++ b/uploader/genotypes/views.py
@@ -3,12 +3,12 @@ from MySQLdb.cursors import DictCursor
 from gn_libs.mysqldb import database_connection
 from flask import (flash,
                    request,
-                   url_for,
                    redirect,
                    Blueprint,
                    render_template,
                    current_app as app)
 
+from uploader.flask_extensions import url_for
 from uploader.ui import make_template_renderer
 from uploader.oauth2.client import oauth2_post
 from uploader.authorisation import require_login
diff --git a/uploader/oauth2/views.py b/uploader/oauth2/views.py
index 1ee4257..05f8542 100644
--- a/uploader/oauth2/views.py
+++ b/uploader/oauth2/views.py
@@ -4,13 +4,13 @@ from urllib.parse import urljoin, urlparse, urlunparse
 from flask import (
     flash,
     jsonify,
-    url_for,
     request,
     redirect,
     Blueprint,
     current_app as app)
 
 from uploader import session
+from uploader.flask_extensions import url_for
 from uploader import monadic_requests as mrequests
 from uploader.monadic_requests import make_error_handler
 
diff --git a/uploader/phenotypes/views.py b/uploader/phenotypes/views.py
index 15d2b6c..2afd8a3 100644
--- a/uploader/phenotypes/views.py
+++ b/uploader/phenotypes/views.py
@@ -23,7 +23,6 @@ from gn_libs.mysqldb import database_connection
 
 from flask import (flash,
                    request,
-                   url_for,
                    jsonify,
                    redirect,
                    Blueprint,
@@ -35,7 +34,8 @@ from r_qtl import exceptions as rqe
 
 from uploader import jobs
 from uploader import session
-from uploader.files import save_file#, fullpath
+from uploader.files import save_file
+from uploader.flask_extensions import url_for
 from uploader.ui import make_template_renderer
 from uploader.oauth2.client import oauth2_post
 from uploader.oauth2.tokens import request_token
diff --git a/uploader/platforms/views.py b/uploader/platforms/views.py
index d12a9ef..ba0f0ef 100644
--- a/uploader/platforms/views.py
+++ b/uploader/platforms/views.py
@@ -4,11 +4,11 @@ from gn_libs.mysqldb import database_connection
 from flask import (
     flash,
     request,
-    url_for,
     redirect,
     Blueprint,
     current_app as app)
 
+from uploader.flask_extensions import url_for
 from uploader.ui import make_template_renderer
 from uploader.authorisation import require_login
 from uploader.species.models import all_species, species_by_id
diff --git a/uploader/population/views.py b/uploader/population/views.py
index cfc3b70..8d4ceb7 100644
--- a/uploader/population/views.py
+++ b/uploader/population/views.py
@@ -7,12 +7,12 @@ from MySQLdb.cursors import DictCursor
 from gn_libs.mysqldb import database_connection
 from flask import (flash,
                    request,
-                   url_for,
                    redirect,
                    Blueprint,
                    current_app as app)
 
 from uploader.samples.views import samplesbp
+from uploader.flask_extensions import url_for
 from uploader.oauth2.client import oauth2_post
 from uploader.ui import make_template_renderer
 from uploader.authorisation import require_login
diff --git a/uploader/publications/views.py b/uploader/publications/views.py
index 805d6f0..4ec832f 100644
--- a/uploader/publications/views.py
+++ b/uploader/publications/views.py
@@ -5,12 +5,12 @@ from gn_libs.mysqldb import database_connection
 from flask import (
     flash,
     request,
-    url_for,
     redirect,
     Blueprint,
     render_template,
     current_app as app)
 
+from uploader.flask_extensions import url_for
 from uploader.authorisation import require_login
 from uploader.route_utils import redirect_to_next
 
diff --git a/uploader/route_utils.py b/uploader/route_utils.py
index 53247e6..4449475 100644
--- a/uploader/route_utils.py
+++ b/uploader/route_utils.py
@@ -3,7 +3,6 @@ import logging
 from json.decoder import JSONDecodeError
 
 from flask import (flash,
-                   url_for,
                    request,
                    redirect,
                    render_template,
@@ -11,6 +10,7 @@ from flask import (flash,
 
 from gn_libs.mysqldb import database_connection
 
+from uploader.flask_extensions import url_for
 from uploader.datautils import base64_encode_dict, base64_decode_to_dict
 from uploader.population.models import (populations_by_species,
                                         population_by_species_and_id)
diff --git a/uploader/samples/views.py b/uploader/samples/views.py
index 4705a96..f8baf7e 100644
--- a/uploader/samples/views.py
+++ b/uploader/samples/views.py
@@ -7,13 +7,13 @@ from pathlib import Path
 from redis import Redis
 from flask import (flash,
                    request,
-                   url_for,
                    redirect,
                    Blueprint,
                    current_app as app)
 
 from uploader import jobs
 from uploader.files import save_file
+from uploader.flask_extensions import url_for
 from uploader.ui import make_template_renderer
 from uploader.authorisation import require_login
 from uploader.input_validation import is_integer_input
diff --git a/uploader/species/views.py b/uploader/species/views.py
index a490b0f..20acd01 100644
--- a/uploader/species/views.py
+++ b/uploader/species/views.py
@@ -4,13 +4,13 @@ from pymonad.either import Left, Right, Either
 from gn_libs.mysqldb import database_connection
 from flask import (flash,
                    request,
-                   url_for,
                    redirect,
                    Blueprint,
                    current_app as app)
 
 from uploader.population import popbp
 from uploader.platforms import platformsbp
+from uploader.flask_extensions import url_for
 from uploader.ui import make_template_renderer
 from uploader.oauth2.client import oauth2_get, oauth2_post
 from uploader.authorisation import require_login, require_token
@@ -52,21 +52,19 @@ def view_species(species_id: int):
             if bool(population):
                 return redirect(url_for("species.populations.view_population",
                                         species_id=species_id,
-                                        population_id=population["Id"],
-                                        streamlined_ui=streamlined_ui))
+                                        population_id=population["Id"]))
             return render_template(
                 ("species/sui-view-species.html"
                  if bool(streamlined_ui)
                  else "species/view-species.html"),
                 species=species,
                 activelink="view-species",
-                streamlined_ui=streamlined_ui,
                 populations=populations_by_species(conn, species["SpeciesId"]))
         flash("Could not find a species with the given identifier.",
               "alert-danger")
-        return redirect(url_for(
-            ("base.index" if streamlined_ui else "species.view_species"),
-            streamlined_ui=streamlined_ui))
+        return redirect(url_for("base.index"
+                                if streamlined_ui
+                                else "species.view_species"))
 
 @speciesbp.route("/create", methods=["GET", "POST"])
 @require_login
diff --git a/uploader/templates/base.html b/uploader/templates/base.html
index 3c0d0d4..d521ccb 100644
--- a/uploader/templates/base.html
+++ b/uploader/templates/base.html
@@ -45,7 +45,7 @@
     <aside id="nav-sidebar">
       <ul class="nav flex-column">
         <li {%if activemenu=="home"%}class="activemenu"{%endif%}>
-          <a href="/" >Home</a></li>
+          <a href="{{url_for('base.index')}}" >Home</a></li>
         <li {%if activemenu=="publications"%}class="activemenu"{%endif%}>
           <a href="{{url_for('publications.index')}}"
              title="View and manage publications.">Publications</a></li>
diff --git a/uploader/templates/macro-forms.html b/uploader/templates/macro-forms.html
new file mode 100644
index 0000000..0ccab32
--- /dev/null
+++ b/uploader/templates/macro-forms.html
@@ -0,0 +1,9 @@
+{%macro add_http_feature_flags()%}
+{%for flag in http_feature_flags():%}
+{%if (request.args.get(flag) or request.form.get(flag) or ""):%}
+<input type="hidden"
+       name="{{flag}}"
+       value="{{(request.args.get(flag) or request.form.get(flag))}}" />
+{%endif%}
+{%endfor%}
+{%endmacro%}
diff --git a/uploader/templates/populations/sui-base.html b/uploader/templates/populations/sui-base.html
index 88d3f54..cc01c9e 100644
--- a/uploader/templates/populations/sui-base.html
+++ b/uploader/templates/populations/sui-base.html
@@ -5,8 +5,7 @@
 <li class="breadcrumb-item">
   <a href="{{url_for('species.populations.view_population',
            species_id=species['SpeciesId'],
-           population_id=population['Id'],
-           streamlined_ui=streamlined_ui)}}">
+           population_id=population['Id'])}}">
     {{population["FullName"]}}
   </a>
 </li>
diff --git a/uploader/templates/populations/sui-view-population.html b/uploader/templates/populations/sui-view-population.html
index a9f506a..9b10ad4 100644
--- a/uploader/templates/populations/sui-view-population.html
+++ b/uploader/templates/populations/sui-view-population.html
@@ -68,8 +68,7 @@
         in your data.</p>
       <a href="{{url_for('species.populations.samples.list_samples',
                species_id=species.SpeciesId,
-               population_id=population.Id,
-               streamlined_ui=streamlined_ui)}}"
+               population_id=population.Id)}}"
          title="Upload samples for population '{{population['Name']}}'"
          class="btn btn-primary">Upload Samples</a>
     </div>
@@ -88,8 +87,7 @@
       <a href="{{url_for('species.populations.phenotypes.view_dataset',
            species_id=species.SpeciesId,
            population_id=population.Id,
-           dataset_id=dataset.Id,
-           streamlined_ui=streamlined_ui)}}"
+           dataset_id=dataset.Id)}}"
          title="Upload phenotype data for population '{{population['Name']}}'"
          class="btn btn-primary">Upload Phenotypes</a>
     </div>
@@ -102,8 +100,7 @@
         system will be added. This does not delete any existing data.</p>
       <a href="{{url_for('species.populations.genotypes.list_genotypes',
                species_id=species.SpeciesId,
-               population_id=population.Id,
-               streamlined_ui=streamlined_ui)}}"
+               population_id=population.Id)}}"
          title="Upload genotype information for the '{{population.FullName}}' population of the '{{species.FullName}}' species."
          class="btn btn-primary">upload genotypes</a>
     </div>
diff --git a/uploader/templates/species/sui-base.html b/uploader/templates/species/sui-base.html
index 5d2e6e3..f7b4fef 100644
--- a/uploader/templates/species/sui-base.html
+++ b/uploader/templates/species/sui-base.html
@@ -3,7 +3,7 @@
 {%block breadcrumbs%}
 {{super()}}
 <li class="breadcrumb-item">
-  <a href="{{url_for('species.view_species', species_id=species['SpeciesId'], streamlined_ui=streamlined_ui)}}">
+  <a href="{{url_for('species.view_species', species_id=species['SpeciesId'])}}">
     {{species["Name"]|title}}
   </a>
 </li>
diff --git a/uploader/templates/species/sui-view-species.html b/uploader/templates/species/sui-view-species.html
index 5373766..c7ac956 100644
--- a/uploader/templates/species/sui-view-species.html
+++ b/uploader/templates/species/sui-view-species.html
@@ -1,5 +1,6 @@
 {%extends "species/sui-base.html"%}
 {%from "flash_messages.html" import flash_all_messages%}
+{%from "macro-forms.html" import add_http_feature_flags%}
 {%from "macro-step-indicator.html" import step_indicator%}
 {%from "species/macro-display-species-card.html" import display_sui_species_card%}
 
diff --git a/uploader/templates/sui-base.html b/uploader/templates/sui-base.html
index 4aec354..719a646 100644
--- a/uploader/templates/sui-base.html
+++ b/uploader/templates/sui-base.html
@@ -52,7 +52,7 @@
         <ol class="breadcrumb">
           {%block breadcrumbs%}
           <li class="breadcrumb-item">
-            <a href="{{url_for('base.index', streamlined_ui='true')}}">Home</a></li>
+            <a href="{{url_for('base.index')}}">Home</a></li>
           {%endblock%}
         </ol>
       </nav>
diff --git a/uploader/templates/sui-index.html b/uploader/templates/sui-index.html
index e6873e2..260ec30 100644
--- a/uploader/templates/sui-index.html
+++ b/uploader/templates/sui-index.html
@@ -1,5 +1,6 @@
 {%extends "sui-base.html"%}
 {%from "flash_messages.html" import flash_all_messages%}
+{%from "macro-forms.html" import add_http_feature_flags%}
 {%from "macro-step-indicator.html" import step_indicator%}
 
 {%block title%}Home{%endblock%}
@@ -25,8 +26,7 @@
 
 <div class="row">
   <form method="GET" action="{{url_for('base.index')}}" class="form-horizontal">
-    <input type="hidden" name="streamlined_ui", value="{{streamlined_ui}}" />
-
+    {{add_http_feature_flags()}}
     {%if species | length != 0%}
     <div style="margin-top:3em;">
       <table id="tbl-select-species" class="table compact stripe"