about summary refs log tree commit diff
path: root/uploader/platforms
diff options
context:
space:
mode:
authorFrederick Muriuki Muriithi2024-09-23 16:29:25 -0500
committerFrederick Muriuki Muriithi2024-09-23 16:35:39 -0500
commit480ee0b657b762f1dd0b1164f98ab13bc9a11f56 (patch)
tree28c7e8e450112039bb764a6fe967838369aba937 /uploader/platforms
parent4285cc10e24d6410206329ba079406e9aa21cc30 (diff)
downloadgn-uploader-480ee0b657b762f1dd0b1164f98ab13bc9a11f56.tar.gz
Initialise "Platforms" section.
Diffstat (limited to 'uploader/platforms')
-rw-r--r--uploader/platforms/__init__.py2
-rw-r--r--uploader/platforms/models.py41
-rw-r--r--uploader/platforms/views.py86
3 files changed, 129 insertions, 0 deletions
diff --git a/uploader/platforms/__init__.py b/uploader/platforms/__init__.py
new file mode 100644
index 0000000..8cb89c9
--- /dev/null
+++ b/uploader/platforms/__init__.py
@@ -0,0 +1,2 @@
+"""Module to handle management of genetic platforms."""
+from .views import platformsbp
diff --git a/uploader/platforms/models.py b/uploader/platforms/models.py
new file mode 100644
index 0000000..adad0b2
--- /dev/null
+++ b/uploader/platforms/models.py
@@ -0,0 +1,41 @@
+"""Handle db interactions for platforms."""
+from typing import Optional
+
+import MySQLdb as mdb
+from MySQLdb.cursors import DictCursor
+
+def platforms_by_species(
+        conn: mdb.Connection,
+        speciesid: int,
+        offset: int = 0,
+        limit: Optional[int] = None
+) -> tuple[dict, ...]:
+    """Retrieve platforms by the species"""
+    _query = ("SELECT * FROM GeneChip WHERE SpeciesId=%s "
+              "ORDER BY GeneChipName ASC")
+    if bool(limit) and limit > 0:
+        _query = f"{_query} LIMIT {limit} OFFSET {offset}"
+    with conn.cursor(cursorclass=DictCursor) as cursor:
+        cursor.execute(_query, (speciesid,))
+        return tuple(dict(row) for row in cursor.fetchall())
+
+
+def species_platforms_count(conn: mdb.Connection, species_id: int) -> int:
+    """Get the number of platforms in the database for a particular species."""
+    with conn.cursor(cursorclass=DictCursor) as cursor:
+        cursor.execute(
+            "SELECT COUNT(GeneChipName) AS count FROM GeneChip "
+            "WHERE SpeciesId=%s",
+            (species_id,))
+        return int(cursor.fetchone()["count"])
+
+def platform_by_id(conn: mdb.Connection, platformid: int) -> Optional[dict]:
+    """Retrieve a platform by its ID"""
+    with conn.cursor(cursorclass=DictCursor) as cursor:
+        cursor.execute("SELECT * FROM GeneChip WHERE Id=%s",
+                       (platformid,))
+        result = cursor.fetchone()
+        if bool(result):
+            return dict(result)
+
+    return None
diff --git a/uploader/platforms/views.py b/uploader/platforms/views.py
new file mode 100644
index 0000000..56390ab
--- /dev/null
+++ b/uploader/platforms/views.py
@@ -0,0 +1,86 @@
+"""The endpoints for the platforms"""
+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
+from uploader.datautils import safe_int, order_by_family, enumerate_sequence
+
+from .models import platforms_by_species, species_platforms_count
+
+platformsbp = Blueprint("platforms", __name__)
+render_template = make_template_renderer("platforms")
+
+@platformsbp.route("platforms", methods=["GET"])
+@require_login
+def index():
+    """Entry-point to the platforms feature."""
+    with database_connection(app.config["SQL_URI"]) as conn:
+        if not bool(request.args.get("species_id")):
+            return render_template(
+                "platforms/index.html",
+                species=order_by_family(all_species(conn)),
+                activelink="platforms")
+
+        species = species_by_id(conn, request.args["species_id"])
+        if not bool(species):
+            flash("No species selected.", "alert-danger")
+            return redirect(url_for("species.platforms.index"))
+
+        return redirect(url_for("species.platforms.list_platforms",
+                                species_id=species["SpeciesId"]))
+
+
+@platformsbp.route("<int:species_id>/platforms", methods=["GET"])
+@require_login
+def list_platforms(species_id: int):
+    """List all the available genetic sequencing platforms."""
+    with database_connection(app.config["SQL_URI"]) as conn:
+        species = species_by_id(conn, species_id)
+        if not bool(species):
+            flash("No species provided.", "alert-danger")
+            return redirect(url_for("species.platforms.index"))
+
+        start_from = safe_int(request.args.get("start_from") or 0)
+        if start_from < 0:
+            start_from = 0
+        count = safe_int(request.args.get("count") or 20)
+        return render_template(
+            "platforms/list-platforms.html",
+            species=species,
+            platforms=enumerate_sequence(
+                platforms_by_species(conn,
+                                     species_id,
+                                     offset=start_from,
+                                     limit=count),
+                start=start_from+1),
+            start_from=start_from,
+            count=count,
+            total_platforms=species_platforms_count(conn, species_id),
+            activelink="list-platforms")
+
+
+@platformsbp.route("<int:species_id>/platforms/create", methods=["GET", "POST"])
+@require_login
+def create_platform(species_id: int):
+    """Create a new genetic sequencing platform."""
+    with database_connection(app.config["SQL_URI"]) as conn:
+        species = species_by_id(conn, species_id)
+        if not bool(species):
+            flash("No species provided.", "alert-danger")
+            return redirect(url_for("species.platforms.index"))
+
+        if request.method == "GET":
+            return render_template(
+                "platforms/create-platform.html",
+                species=species,
+                activelink="create-platform")
+
+        raise NotImplementedError("This still needs to be implemented.")