diff options
author | Frederick Muriuki Muriithi | 2024-08-29 15:21:27 -0500 |
---|---|---|
committer | Frederick Muriuki Muriithi | 2024-08-30 15:06:24 -0500 |
commit | e49b4367f1dab1c3acb3cd5d71ba09359c5ab4ee (patch) | |
tree | 63035669dd9a82bccee60b572a565d028cf3ef38 /uploader/species | |
parent | f95037b93329d5a4953b81ba1b58e4028a6274e8 (diff) | |
download | gn-uploader-e49b4367f1dab1c3acb3cd5d71ba09359c5ab4ee.tar.gz |
Initialise package for dealing with Species.
Diffstat (limited to 'uploader/species')
-rw-r--r-- | uploader/species/__init__.py | 2 | ||||
-rw-r--r-- | uploader/species/models.py | 22 | ||||
-rw-r--r-- | uploader/species/views.py | 91 |
3 files changed, 115 insertions, 0 deletions
diff --git a/uploader/species/__init__.py b/uploader/species/__init__.py new file mode 100644 index 0000000..83f2165 --- /dev/null +++ b/uploader/species/__init__.py @@ -0,0 +1,2 @@ +"""Package to handle creation and management of species.""" +from .views import speciesbp diff --git a/uploader/species/models.py b/uploader/species/models.py new file mode 100644 index 0000000..98337a3 --- /dev/null +++ b/uploader/species/models.py @@ -0,0 +1,22 @@ +"""Database functions for species.""" +import MySQLdb as mdb +from MySQLdb.cursors import DictCursor + +def all_species(conn: mdb.Connection) -> tuple: + "Retrieve the species from the database." + with conn.cursor(cursorclass=DictCursor) as cursor: + cursor.execute( + "SELECT SpeciesId, SpeciesName, LOWER(Name) AS Name, MenuName, " + "FullName, TaxonomyId FROM Species") + return tuple(cursor.fetchall()) + + return tuple() + +def species_by_id(conn: mdb.Connection, speciesid) -> dict: + "Retrieve the species from the database by id." + with conn.cursor(cursorclass=DictCursor) as cursor: + cursor.execute( + "SELECT SpeciesId, SpeciesName, LOWER(Name) AS Name, MenuName, " + "FullName FROM Species WHERE SpeciesId=%s", + (speciesid,)) + return cursor.fetchone() diff --git a/uploader/species/views.py b/uploader/species/views.py new file mode 100644 index 0000000..af66de3 --- /dev/null +++ b/uploader/species/views.py @@ -0,0 +1,91 @@ +"""Endpoints handling species.""" +from flask import (flash, + request, + url_for, + redirect, + Blueprint, + current_app as app, + render_template as flask_render_template) + +from uploader.db_utils import database_connection + +from .models import all_species, save_species, species_by_id + + +speciesbp = Blueprint("species", __name__) + + +def render_template(template, **kwargs): + """Render template for species.""" + return flask_render_template(template, **kwargs, activelink="species") + + +@speciesbp.route("/", methods=["GET"]) +def list_species(): + """List and display all the species in the database.""" + with database_connection(app.config["SQL_URI"]) as conn: + return render_template("species/list-species.html", + allspecies=all_species(conn)) + +@speciesbp.route("/<int:species_id>", methods=["GET"]) +def view_species(species_id: int): + """View details of a particular species and menus to act upon it.""" + with database_connection(app.config["SQL_URI"]) as conn: + return species_by_id(conn, species_id) + +@speciesbp.route("/create", methods=["GET", "POST"]) +def create_species(): + """Create a new species.""" + # We can use uniprot's API to fetch the details with something like + # https://rest.uniprot.org/taxonomy/<taxonID> e.g. + # https://rest.uniprot.org/taxonomy/6239 + if request.method == "GET": + return render_template("species/create-species.html") + + with (database_connection(app.config["SQL_URI"]) as conn, + conn.cursor() as cursor): + error = False + taxon_id = request.form.get("taxon_id", "").strip() or None + + common_name = request.form.get("common_name", "").strip() + if not bool(common_name): + flash("The common species name MUST be provided.", "alert-danger") + error = True + + scientific_name = request.form.get("scientific_name", "").strip() + if not bool(scientific_name): + flash("The species' scientific name MUST be provided.", + "alert-danger") + error = True + + parts = tuple(name.strip() for name in scientific_name.split(" ")) + if len(parts) != 2 or not all(bool(name) for name in parts): + flash("The scientific name you provided is invalid.", "alert-danger") + error = True + + cursor.execute( + "SELECT * FROM Species WHERE FullName=%s", (scientific_name,)) + res = cursor.fetchone() + if bool(res): + flash("A species already exists with the provided scientific name.", + "alert-danger") + error = True + + if bool(taxon_id): + cursor.execute( + "SELECT * FROM Species WHERE TaxonomyId=%s", (taxon_id,)) + res = cursor.fetchone() + if bool(res): + flash("A species already exists with the provided scientific name.", + "alert-danger") + error = True + + if error: + return redirect(url_for("species.create_species", + common_name=common_name, + scientific_name=scientific_name, + taxon_id=taxon_id)) + + species = save_species(conn, common_name, scientific_name, taxon_id) + flash("Species saved successfully!", "alert-success") + return redirect(url_for("species.view_species", species_id=species["species_id"])) |