diff options
author | Frederick Muriuki Muriithi | 2024-09-03 14:55:48 -0500 |
---|---|---|
committer | Frederick Muriuki Muriithi | 2024-09-03 16:51:26 -0500 |
commit | 61688c00e8734adee4d825571a9c43d926dca001 (patch) | |
tree | 0a53c7eff5ec2bb1376be2eb2bdd2333c606ba11 /uploader/population | |
parent | 2876fe6251bd4dfceef06f638ee74c2728ad1207 (diff) | |
download | gn-uploader-61688c00e8734adee4d825571a9c43d926dca001.tar.gz |
Initialise the populations package and update references.
Diffstat (limited to 'uploader/population')
-rw-r--r-- | uploader/population/__init__.py | 3 | ||||
-rw-r--r-- | uploader/population/models.py | 54 | ||||
-rw-r--r-- | uploader/population/views.py | 120 |
3 files changed, 177 insertions, 0 deletions
diff --git a/uploader/population/__init__.py b/uploader/population/__init__.py new file mode 100644 index 0000000..bf6bf3c --- /dev/null +++ b/uploader/population/__init__.py @@ -0,0 +1,3 @@ +"""Package to handle creation and management of Populations/InbredSets""" + +from .views import popbp diff --git a/uploader/population/models.py b/uploader/population/models.py new file mode 100644 index 0000000..4485e52 --- /dev/null +++ b/uploader/population/models.py @@ -0,0 +1,54 @@ +"""Functions for accessing the database relating to species populations.""" +import MySQLdb as mdb +from MySQLdb.cursors import DictCursor + +def population_by_id(conn: mdb.Connection, population_id) -> dict: + """Get the grouping/population by id.""" + with conn.cursor(cursorclass=DictCursor) as cursor: + cursor.execute("SELECT * FROM InbredSet WHERE InbredSetId=%s", + (population_id,)) + return cursor.fetchone() + +def population_by_species_and_id( + conn: mdb.Connection, species_id, population_id) -> dict: + """Retrieve a population by its identifier and species.""" + with conn.cursor(cursorclass=DictCursor) as cursor: + cursor.execute("SELECT * FROM InbredSet WHERE SpeciesId=%s AND Id=%s", + (species_id, population_id)) + return cursor.fetchone() + +def populations_by_species(conn: mdb.Connection, speciesid) -> tuple: + "Retrieve group (InbredSet) information from the database." + with conn.cursor(cursorclass=DictCursor) as cursor: + query = "SELECT * FROM InbredSet WHERE SpeciesId=%s" + cursor.execute(query, (speciesid,)) + return tuple(cursor.fetchall()) + + return tuple() + +def save_population(conn: mdb.Connection, population_details: dict) -> dict: + """Save the population details to the db.""" + with conn.cursor(cursorclass=DictCursor) as cursor: + cursor.execute( + "INSERT INTO InbredSet(" + "InbredSetId, InbredSetName, Name, SpeciesId, FullName, " + "MenuOrderId, Description" + ") " + "VALUES (" + "%(InbredSetId)s, %(InbredSetName)s, %(Name)s, %(SpeciesId)s, " + "%(FullName)s, %(MenuOrderId)s, %(Description)s" + ")", + { + "MenuOrderId": 0, + "InbredSetId": 0, + **population_details + }) + new_id = cursor.lastrowid + cursor.execute("UPDATE InbredSet SET InbredSetId=%s WHERE Id=%s", + (new_id, new_id)) + return { + **population_details, + "Id": new_id, + "InbredSetId": new_id, + "population_id": new_id + } diff --git a/uploader/population/views.py b/uploader/population/views.py new file mode 100644 index 0000000..cd5e20b --- /dev/null +++ b/uploader/population/views.py @@ -0,0 +1,120 @@ +"""Views dealing with populations/inbredsets""" +from flask import (flash, + request, + url_for, + redirect, + Blueprint, + current_app as app) + +from uploader.ui import make_template_renderer +from uploader.authorisation import require_login +from uploader.db_utils import database_connection +from uploader.species.models import (all_species, + species_by_id, + order_species_by_family) + +from .models import (save_population, + populations_by_species) + +__active_link__ = "populations" +popbp = Blueprint("populations", __name__) +render_template = make_template_renderer("populations") + + +@popbp.route("/", methods=["GET", "POST"]) +@require_login +def index(): + """Entry point for populations.""" + with database_connection(app.config["SQL_URI"]) as conn: + if not bool(request.args.get("species_id")): + return render_template( + "populations/index.html", + species=order_species_by_family(all_species(conn))) + species = species_by_id(conn, request.args.get("species_id")) + if not bool(species): + flash("Invalid species identifier provided!", "alert-danger") + return redirect(url_for("populations.index")) + return redirect(url_for("populations.list_species_populations", + species_id=species["SpeciesId"])) + +@popbp.route("/<int:species_id>", methods=["GET"]) +@require_login +def list_species_populations(species_id: int): + """List a particular species' populations.""" + with database_connection(app.config["SQL_URI"]) as conn: + species = species_by_id(conn, species_id) + if not bool(species): + flash("No species was found for given ID.", "alert-danger") + return redirect(url_for("populations.index")) + return render_template( + "populations/list-populations.html", + species=species, + populations=populations_by_species(conn, species_id), + activelink="list-populations") + + +def valid_population_name(population_name) -> bool: + """Check whether the given name is a valid population name.""" + raise NotImplementedError("Please implement this…") + + +@popbp.route("/<int:species_id>/create-population/", methods=["GET", "POST"]) +@require_login +def create_population(species_id: int): + """Create a new population.""" + with database_connection(app.config["SQL_URI"]) as conn: + species = species_by_id(conn, species_id) + + if request.method == "GET": + return render_template( + "populations/create-population.html", + species=species, + continue_to=request.args.get("continue_uri")) + + error = False + + if not bool(species): + flash("You must select a species.", "alert-danger") + error = True + + population_name = request.form.get("population_name", "").strip() + if not bool(population_name): + flash("You must provide a name for the population!", "alert-danger") + error = True + + if not valid_population_name(population_name): + flash("The population name can only contain letters, numbers, " + "hyphens and underscores.", + "alert-danger") + error = True + + population_fullname = request.form.get("inbredset_fullname", "").strip() + if not bool(population_fullname): + flash("You MUST provide a Full Name for the population." + "alert-danger") + error = True + + if error: + return redirect(url_for("populations.create_population", + **dict(request.args))) + + new_population = save_population(conn, { + "SpeciesId": species["SpeciesId"], + "Name": population_name, + "InbredSetName": population_fullname, + "FullName": population_fullname, + "Family": request.form.get("inbredset_family") or None, + "Description": request.form.get("description") or None + }) + + return redirect(url_for("populations.view_population", + species_id=species["SpeciesId"], + population_id=new_population["InbredSetId"])) + + +@popbp.route("/<int:species_id>/populations/<int:population_id>", + methods=["GET"]) +@require_login +def view_population(species_id: int, population_id: int): + """View the details of a population.""" + raise NotImplementedError("Please implement this too …") |