about summary refs log tree commit diff
path: root/qc_app
diff options
context:
space:
mode:
authorFrederick Muriuki Muriithi2022-07-12 08:51:20 +0300
committerFrederick Muriuki Muriithi2022-07-19 04:59:59 +0300
commitee44431de6cf860fe89e796eab2bb0d555d90105 (patch)
tree79b80c7577044a0b79296ca460d989d6fa53975c /qc_app
parent3038c5166aad408d7255f83668b78d635878d3d3 (diff)
downloadgn-uploader-ee44431de6cf860fe89e796eab2bb0d555d90105.tar.gz
Add 'group' and 'tissue' selection.
- Build code to populate the "Group" and "Tissue" dropdown lists
- Enable redirect with POST data (code 307) in case there is input
  error to enable the user fix their errors
- Move hidden fields to macro to reduce repetition
Diffstat (limited to 'qc_app')
-rw-r--r--qc_app/dbinsert.py103
-rw-r--r--qc_app/templates/dbupdate_hidden_fields.html14
-rw-r--r--qc_app/templates/select_study.html55
3 files changed, 120 insertions, 52 deletions
diff --git a/qc_app/dbinsert.py b/qc_app/dbinsert.py
index e506175..18bc7c2 100644
--- a/qc_app/dbinsert.py
+++ b/qc_app/dbinsert.py
@@ -6,7 +6,9 @@ from functools import reduce
 import requests
 from redis import Redis
 from MySQLdb.cursors import DictCursor
-from flask import request, Blueprint, render_template, current_app as app
+from flask import (
+    flash, request, url_for, Blueprint, redirect, render_template,
+    current_app as app)
 
 from . import jobs
 from .db_utils import database_connection
@@ -70,6 +72,32 @@ def studies_by_species_and_platform(speciesid:int, genechipid:int) -> tuple:
 
     return tuple()
 
+def groups_by_species(speciesid:int) -> tuple:
+    "Retrieve group (InbredSet) information from the database."
+    with database_connection() as conn:
+        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 organise_groups_by_family(acc:dict, group:dict) -> dict:
+    "Organise the group (InbredSet) information by the group field"
+    family = group["Family"]
+    if acc.get(family):
+        return {**acc, family: acc[family] + (group,)}
+    return {**acc, family: (group,)}
+
+def tissues() -> tuple:
+    "Retrieve type (Tissue) information from the database."
+    with database_connection() as conn:
+        with conn.cursor(cursorclass=DictCursor) as cursor:
+            cursor.execute("SELECT * FROM Tissue ORDER BY Name")
+            return tuple(cursor.fetchall())
+
+    return tuple()
+
 @dbinsertbp.route("/platform", methods=["POST"])
 def select_platform():
     "Select the platform (GeneChipId) used for the data."
@@ -105,54 +133,49 @@ def select_study():
         genechipid = form["genechipid"]
 
         the_studies = studies_by_species_and_platform(speciesid, genechipid)
+        the_groups = reduce(
+            organise_groups_by_family, groups_by_species(speciesid), {})
         return render_template(
             "select_study.html", filename=form["filename"],
             filetype=form["filetype"], species=speciesid, genechipid=genechipid,
-            studies=the_studies)
+            studies=the_studies, groups=the_groups, tissues = tissues(),
+            selected_group=int(form.get("inbredsetid", -13)),
+            selected_tissue=int(form.get("tissueid", -13)))
     except AssertionError as aserr:
         return render_error(f"Missing data: {aserr.args[0]}")
 
-@dbinsertbp.route("/select-dataset", methods=["POST"])
+@dbinsertbp.route("/create-study", methods=["POST"])
+def create_study():
+    "Create a new study (ProbeFreeze)."
+    form = request.form
+    try:
+        assert form.get("studyname"), "study name"
+        assert form.get("inbredsetid"), "group"
+        assert form.get("tissueid"), "type/tissue"
+    except AssertionError as aserr:
+        flash(f"Missing data: {aserr.args[0]}", "alert-error")
+        return redirect(url_for("dbinsert.select_study"), code=307)
+
+@dbinsertbp.route("/dataset", methods=["POST"])
 def select_dataset():
     "Select the dataset to add the file contents against"
-    job_id = request.form["job_id"]
-    with Redis.from_url(app.config["REDIS_URL"], decode_responses=True) as rconn:
-        job = jobs.job(rconn, job_id)
-        if job:
-            filename = job["filename"]
-            filepath = f"{app.config['UPLOAD_FOLDER']}/{filename}"
-            if os.path.exists(filepath):
-                req = requests.get(
-                    "https://genenetwork.org/api3/api/menu/generate/json")
-                menu_contents = req.json()
-                default_species = "mouse"
-                mouse_groups = reduce(
-                    make_menu_items_grouper(
-                        lambda item: item.strip()[7:].strip()),
-                    menu_contents["groups"][default_species], {})
-                default_group = "BXD"
-                group_types = reduce(
-                    make_menu_items_grouper(),
-                    menu_contents["types"][default_species][default_group], {})
-                default_type = group_types[tuple(group_types)[0]][0][0]
-                datasets = menu_contents[
-                    "datasets"][default_species][default_group][
-                        default_type]
-
-                gchips = genechips()
+    form = request.form
+    try:
+        assert form.get("filename"), "filename"
+        assert form.get("filetype"), "filetype"
+        assert form.get("species"), "species"
+        assert form.get("genechipid"), "platform"
+        assert (form.get("studyid") or form.get(studyname)), ""
+        assert form.get(""), ""
+        assert form.get(""), ""
+        assert form.get(""), ""
+        assert form.get(""), ""
 
-                return render_template(
-                    "select_dataset.html", filename=filename,
-                    species=menu_contents["species"],
-                    default_species=default_species, groups=mouse_groups,
-                    types=group_types, datasets=datasets,
-                    menu_contents=json.dumps(menu_contents),
-                    genechips_data=json.dumps(gchips),
-                    genechips=gchips.get(default_species, []),
-                    filetype=job["filetype"])
-            return render_error(f"File '{filename}' no longer exists.")
-        return render_error(f"Job '{job_id}' no longer exists.")
-    return render_error("Unknown error")
+        return render_template(
+            "select_dataset.html", filename=form["filename"],
+            filetype=form["filetype"], species=speciesid, genechipid=genechipid)
+    except AssertionError as aserr:
+        return render_error(f"Missing data: {aserr.args[0]}")
 
 
 @dbinsertbp.route("/insert_data", methods=["POST"])
diff --git a/qc_app/templates/dbupdate_hidden_fields.html b/qc_app/templates/dbupdate_hidden_fields.html
new file mode 100644
index 0000000..cdebeab
--- /dev/null
+++ b/qc_app/templates/dbupdate_hidden_fields.html
@@ -0,0 +1,14 @@
+{%macro hidden_fields(filename, filetype):%}
+
+<!-- {{kwargs}}: mostly for accessing the kwargs in macro -->
+
+<input type="hidden" name="filename" value="{{filename}}" />
+<input type="hidden" name="filetype" value="{{filetype}}" />
+{%if kwargs.get("species"):%}
+<input type="hidden" name="species" value="{{species}}" />
+{%endif%}
+{%if kwargs.get("genechipid"):%}
+<input type="hidden" name="genechipid" value="{{genechipid}}" />
+{%endif%}
+
+{%endmacro%}
diff --git a/qc_app/templates/select_study.html b/qc_app/templates/select_study.html
index 8d7a98b..e4b629c 100644
--- a/qc_app/templates/select_study.html
+++ b/qc_app/templates/select_study.html
@@ -1,4 +1,5 @@
 {%extends "base.html"%}
+{%from "dbupdate_hidden_fields.html" import hidden_fields%}
 
 {%block title%}Select Dataset{%endblock%}
 
@@ -14,10 +15,7 @@
 	id="select-platform-form" data-genechips="{{genechips_data}}"
 	class="two-col-sep-col1">
     <legend>Select from existing study</legend>
-    <input type="hidden" name="filename" value="{{filename}}" />
-    <input type="hidden" name="filetype" value="{{filetype}}" />
-    <input type="hidden" name="species" value="{{species}}" />
-    <input type="hidden" name="genechipid" value="{{genechipid}}" />
+    {{hidden_fields(filename, filetype, species=species, genechipid=genechipid)}}
 
     <fieldset>
       <label for="study" class="form-col-1">study:</label>
@@ -39,19 +37,28 @@
 
   <p class="two-col-sep-separator">OR</p>
 
-  <form method="POST" action="{{url_for('dbinsert.select_study')}}"
+  <form method="POST" action="{{url_for('dbinsert.create_study')}}"
 	id="select-platform-form" data-genechips="{{genechips_data}}"
 	class="two-col-sep-col2">
+    {%with messages = get_flashed_messages(with_categories=true)%}
+    {%if messages:%}
+    <ul>
+      {%for category, message in messages:%}
+      <li class="{{category}}">{{message}}</li>
+      {%endfor%}
+    </ul>
+    {%endif%}
+    {%endwith%}
     <legend>Create new study</legend>
-    <input type="hidden" name="filename" value="{{filename}}" />
-    <input type="hidden" name="filetype" value="{{filetype}}" />
-    <input type="hidden" name="species" value="{{species}}" />
-    <input type="hidden" name="genechipid" value="{{genechipid}}" />
+    {{hidden_fields(filename, filetype, species=species, genechipid=genechipid)}}
 
     <fieldset>
       <label for="studyname" class="form-col-1">name:</label>
       <input type="text" id="studyname" name="studyname" class="form-col-2"
-	     required="required" />
+	     required="required"
+	     {%if studyname:%}
+	     value="{{studyname}}"
+	     {%endif%} />
     </fieldset>
 
     <fieldset>
@@ -68,13 +75,37 @@
 
     <fieldset>
       <label for="group" class="form-col-1">group:</label>
-      <select id="group" name="inbredsetid" class="form-col-2">
+      <select id="group" name="inbredsetid" class="form-col-2"
+	      required="required">
+	<option value="">Select group</option>
+	{%for family in groups:%}
+	<optgroup label="{{family}}">
+	  {%for group in groups[family]:%}
+	  <option value="{{group['InbredSetId']}}"
+		  {%if group["InbredSetId"] == selected_group:%}
+		  selected="selected"
+		  {%endif%}>
+	    {{group["FullName"]}}
+	  </option>
+	  {%endfor%}
+	</optgroup>
+	{%endfor%}
       </select>
     </fieldset>
 
     <fieldset>
       <label for="tissue" class="form-col-1">tissue:</label>
-      <select id="tissue" name="tissueid" class="form-col-2">
+      <select id="tissue" name="tissueid" class="form-col-2"
+	      required="required">
+	<option value="">Select type</option>
+	{%for tissue in tissues:%}
+	<option value="{{tissue['TissueId']}}"
+		{%if tissue["TissueId"] == selected_tissue:%}
+		selected="selected"
+		{%endif%}>
+	  {{tissue["Name"]}}
+	</option>
+	{%endfor%}
       </select>
     </fieldset>