about summary refs log tree commit diff
path: root/uploader
diff options
context:
space:
mode:
Diffstat (limited to 'uploader')
-rw-r--r--uploader/request_checks.py75
1 files changed, 75 insertions, 0 deletions
diff --git a/uploader/request_checks.py b/uploader/request_checks.py
new file mode 100644
index 0000000..a24b2f7
--- /dev/null
+++ b/uploader/request_checks.py
@@ -0,0 +1,75 @@
+"""Functions to perform common checks.
+
+These are useful for reusability, and hence maintainability of the code.
+"""
+from functools import wraps
+
+from flask import flash, url_for, redirect, current_app as app
+
+from uploader.species.models import species_by_id
+from uploader.db_utils import database_connection
+from uploader.population.models import population_by_species_and_id
+
+def with_species(redirect_uri: str):
+    """Ensure the species actually exists."""
+    def __decorator__(function):
+        @wraps(function)
+        def __with_species__(**kwargs):
+            try:
+                species_id = int(kwargs.get("species_id"))
+                if not bool(species_id):
+                    flash("Expected species_id value to be present!",
+                          "alert-danger")
+                    return redirect(url_for(redirect_uri))
+                with database_connection(app.config["SQL_URI"]) as conn:
+                    species = species_by_id(conn, species_id)
+                    if not bool(species):
+                        flash("Could not find species with that ID",
+                              "alert-danger")
+                        return redirect(url_for(redirect_uri))
+            except ValueError as _verr:
+                app.logger.debug(
+                    "Exception converting value to integer: %s",
+                    kwargs.get("species_id"),
+                    exc_info=True)
+                flash("Expected an integer for 'species_id' value.",
+                      "alert-danger")
+                return redirect(url_for(redirect_uri))
+            return function(**{**kwargs, "species": species})
+        return __with_species__
+    return __decorator__
+
+
+def with_population(species_redirect_uri: str, redirect_uri: str):
+    """Ensure the population actually exists."""
+    def __decorator__(function):
+        @wraps(function)
+        @with_species(redirect_uri=species_redirect_uri)
+        def __with_population__(**kwargs):
+            try:
+                species_id = int(kwargs["species_id"])
+                population_id = int(kwargs.get("population_id"))
+                select_population_uri = redirect(url_for(
+                    redirect_uri, species_id=species_id))
+                if not bool(population_id):
+                    flash("Expected population_id value to be present!",
+                          "alert-danger")
+                    return select_population_uri
+                with database_connection(app.config["SQL_URI"]) as conn:
+                    population = population_by_species_and_id(
+                        conn, species_id, population_id)
+                    if not bool(population):
+                        flash("Could not find population with that ID",
+                              "alert-danger")
+                        return select_population_uri
+            except ValueError as _verr:
+                app.logger.debug(
+                    "Exception converting value to integer: %s",
+                    kwargs.get("population_id"),
+                    exc_info=True)
+                flash("Expected an integer for 'population_id' value.",
+                      "alert-danger")
+                return select_population_uri
+            return function(**{**kwargs, "population": population})
+        return __with_population__
+    return __decorator__