diff options
author | Frederick Muriuki Muriithi | 2024-09-04 12:32:27 -0500 |
---|---|---|
committer | Frederick Muriuki Muriithi | 2024-09-04 12:32:27 -0500 |
commit | cd5f5e2e7a4cb91f00e3227922daab40c30b35bf (patch) | |
tree | 2156d67ca395084c395735f61001745d0a8e4c66 | |
parent | c4b6c239ca2652da5aa48eede31c2a400915c316 (diff) | |
download | gn-uploader-cd5f5e2e7a4cb91f00e3227922daab40c30b35bf.tar.gz |
Create populations (InbredSet groups) under Species.
-rw-r--r-- | uploader/population/views.py | 55 | ||||
-rw-r--r-- | uploader/templates/populations/create-population.html | 118 | ||||
-rw-r--r-- | uploader/templates/populations/view-population.html | 2 |
3 files changed, 164 insertions, 11 deletions
diff --git a/uploader/population/views.py b/uploader/population/views.py index e21465c..fe318e1 100644 --- a/uploader/population/views.py +++ b/uploader/population/views.py @@ -1,4 +1,8 @@ """Views dealing with populations/inbredsets""" +import re +import json +import base64 + from flask import (flash, request, url_for, @@ -54,12 +58,30 @@ def list_species_populations(species_id: int): 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…") +def valid_population_name(population_name: str) -> bool: + """ + Check whether the given name is a valid population name. + + Parameters + ---------- + population_name: a string of characters. + + Checks For + ---------- + * The name MUST start with an alphabet [a-zA-Z] + * The name MUST end with an alphabet [a-zA-Z] or number [0-9] + * The name MUST be composed of alphabets [a-zA-Z], numbers [0-9], + underscores (_) and/or hyphens (-). + + Returns + ------- + Boolean indicating whether or not the name is valid. + """ + pattern = re.compile(r"^[a-zA-Z]+[a-zA-Z0-9_-]*[a-zA-Z0-9]$") + return bool(pattern.match(population_name)) -@popbp.route("/<int:species_id>/create-population/", methods=["GET", "POST"]) +@popbp.route("/<int:species_id>/populations/create", methods=["GET", "POST"]) @require_login def create_population(species_id: int): """Create a new population.""" @@ -67,10 +89,18 @@ def create_population(species_id: int): species = species_by_id(conn, species_id) if request.method == "GET": + error_values = request.args.get("error_values") + if bool(error_values): + base64.b64encode( + json.dumps(dict(request.form)).encode("utf8")) + error_values = json.loads( + base64.b64decode( + error_values.encode("utf8")).decode("utf8")) return render_template( "populations/create-population.html", species=species, - continue_to=request.args.get("continue_uri")) + activelink="create-population", + **error_values) error = False @@ -78,7 +108,8 @@ def create_population(species_id: int): flash("You must select a species.", "alert-danger") error = True - population_name = request.form.get("population_name", "").strip() + population_name = (request.form.get( + "population_name") or "").strip() if not bool(population_name): flash("You must provide a name for the population!", "alert-danger") error = True @@ -89,15 +120,19 @@ def create_population(species_id: int): "alert-danger") error = True - population_fullname = request.form.get("inbredset_fullname", "").strip() + population_fullname = (request.form.get( + "population_fullname") or "").strip() if not bool(population_fullname): - flash("You MUST provide a Full Name for the population." + flash("You MUST provide a Full Name for the population.", "alert-danger") error = True if error: + values = base64.b64encode( + json.dumps(dict(request.form)).encode("utf8")) return redirect(url_for("species.populations.create_population", - **dict(request.args))) + species_id=species["SpeciesId"], + error_values=values)) new_population = save_population(conn, { "SpeciesId": species["SpeciesId"], @@ -105,7 +140,7 @@ def create_population(species_id: int): "InbredSetName": population_fullname, "FullName": population_fullname, "Family": request.form.get("inbredset_family") or None, - "Description": request.form.get("description") or None + "Description": request.form.get("population_description") or None }) return redirect(url_for("species.populations.view_population", diff --git a/uploader/templates/populations/create-population.html b/uploader/templates/populations/create-population.html new file mode 100644 index 0000000..a27a134 --- /dev/null +++ b/uploader/templates/populations/create-population.html @@ -0,0 +1,118 @@ +{%extends "populations/base.html"%} +{%from "flash_messages.html" import flash_all_messages%} +{%from "species/macro-select-species.html" import select_species_form%} + +{%block title%}Create Population{%endblock%} + +{%block pagetitle%}Create Population{%endblock%} + +{%block lvl3_breadcrumbs%} +<li {%if activelink=="create-population"%} + class="breadcrumb-item active" + {%else%} + class="breadcrumb-item" + {%endif%}> + <a href="{{url_for('species.populations.create_population', + species_id=species.SpeciesId)}}">create population</a> +</li> +{%endblock%} + + +{%block contents%} +<div class="row"> + <p>The population is the next hierarchical node under Species. Data is grouped under a specific population, under a particular species.</p> + <p> + This page enables you to create a new population, in the case that you + cannot find the population you want in the + <a + href="{{url_for('species.populations.list_species_populations', + species_id=species.SpeciesId)}}" + title="Population for species '{{species.FullName}}'."> + list of species populations + </a> + </p> +</div> + +<div class="row"> + <form method="POST" + action="{{url_for('species.populations.create_population', + species_id=species.SpeciesId)}}"> + + <legend>Create Population</legend> + + <div class="form-group"> + <label for="txt-population-fullname" class="form-label">Full Name</label> + <input type="text" + id="txt-population-fullname" + name="population_fullname" + required="required" + minLength="3" + maxLength="100" + value="{{population_fullname or ''}}" + class="form-control" /> + <small class="form-text text-muted"> + <p> + This is a descriptive name for your population — useful for + humans. + </p> + </small> + </div> + + <div class="form-group"> + <label for="txt-population-name" class="form-label">Name</label> + <input type="text" + id="txt-population-name" + name="population_name" + required="required" + minLength="3" + maxLength="30" + value="{{population_name or ''}}" + class="form-control" /> + <small class="form-text text-muted"> + <p> + This is a short representative, but constrained name for your + population. + </p> + <p> + The field will only accept letters ('A-Za-z'), numbers (0-9), hyphens + and underscores. Any other character will cause the name to be + rejected. + </p> + </small> + </div> + + <div class="form-group"> + <label for="txt-population-description" class="form-label"> + Description + </label> + <textarea id="txt-population-description" + name="population_description" + required="required" + class="form-control" + rows="5">{{population_description or ''}}</textarea> + <small class="form-text text-muted"> + <p> + This is a more detailed description for your population. This is + useful to communicate with other researchers some details regarding + your population, and what its about. + </p> + <p> + Put, here, anything that describes your population but does not go + cleanly under metadata. + </p> + </small> + </div> + + <div class="form-group"> + <input type="submit" + value="create population" + class="btn btn-primary" /> + </div> + + </form> +</div> +{%endblock%} + +{%block sidebarcontents%} +<p>… maybe provide species details here, perhaps? …</p> +{%endblock%} diff --git a/uploader/templates/populations/view-population.html b/uploader/templates/populations/view-population.html index 2ab7ca3..7eb1362 100644 --- a/uploader/templates/populations/view-population.html +++ b/uploader/templates/populations/view-population.html @@ -30,7 +30,7 @@ <dd>{{population.FullName}}</dd> <dt>Description</dt> - <dd>{{population.Description or "-"}}</dd> + <dd><pre>{{population.Description or "-"}}</pre></dd> </dl> </div> |