aboutsummaryrefslogtreecommitdiff
path: root/uploader/genotypes/views.py
blob: 2ff9965db2113c0bacf922646d7ff5ce416e98d3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
"""Views for the genotypes."""
from flask import (flash,
                   request,
                   url_for,
                   redirect,
                   Blueprint,
                   render_template,
                   current_app as app)

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 uploader.population.models import (populations_by_species,
                                        population_by_species_and_id)

from .models import (genotype_markers,
                     genotype_markers_count,
                     genocode_by_population)

genotypesbp = Blueprint("genotypes", __name__)

@genotypesbp.route("populations/genotypes", methods=["GET"])
@require_login
def index():
    """Direct entry-point for genotypes."""
    with database_connection(app.config["SQL_URI"]) as conn:
        if not bool(request.args.get("species_id")):
            return render_template("genotypes/index.html",
                                   species=order_by_family(all_species(conn)),
                                   activelink="genotypes")
        species = species_by_id(conn, request.args.get("species_id"))
        if not bool(species):
            flash(f"Could not find species with ID '{request.args.get('species_id')}'!",
                  "alert-danger")
            return redirect(url_for("species.populations.genotypes.index"))
        return redirect(url_for("species.populations.genotypes.select_population",
                                species_id=species["SpeciesId"]))


@genotypesbp.route("/<int:species_id>/populations/genotypes/select-population",
                   methods=["GET"])
@require_login
def select_population(species_id: int):
    """Select the population under which the genotypes go."""
    with database_connection(app.config["SQL_URI"]) as conn:
        species = species_by_id(conn, species_id)
        if not bool(species):
            flash("Invalid species provided!", "alert-danger")
            return redirect(url_for("species.populations.genotypes.index"))

        if not bool(request.args.get("population_id")):
            return render_template("genotypes/select-population.html",
                                   species=species,
                                   populations=order_by_family(
                                       populations_by_species(conn, species_id),
                                       order_key="FamilyOrder"),
                                   activelink="genotypes")

        population = population_by_species_and_id(
            conn, species_id, request.args.get("population_id"))
        if not bool(population):
            flash("Invalid population selected!", "alert-danger")
            return redirect(url_for(
                "species.populations.genotypes.select_population",
                species_id=species_id))

        return redirect(url_for("species.populations.genotypes.list_genotypes",
                                species_id=species_id,
                                population_id=population["Id"]))


@genotypesbp.route(
    "/<int:species_id>/populations/<int:population_id>/genotypes",
    methods=["GET"])
@require_login
def list_genotypes(species_id: int, population_id: int):
    """List genotype details for species and population."""
    with database_connection(app.config["SQL_URI"]) as conn:
        species = species_by_id(conn, species_id)
        if not bool(species):
            flash("Invalid species provided!", "alert-danger")
            return redirect(url_for("species.populations.genotypes.index"))

        population = population_by_species_and_id(
            conn, species_id, population_id)
        if not bool(population):
            flash("Invalid population selected!", "alert-danger")
            return redirect(url_for(
                "species.populations.genotypes.select_population",
                species_id=species_id))

        return render_template("genotypes/list-genotypes.html",
                               species=species,
                               population=population,
                               genocode=genocode_by_population(
                                   conn, population_id),
                               total_markers=genotype_markers_count(
                                   conn, species_id),
                               activelink="list-genotypes")


@genotypesbp.route("/<int:species_id>/genotypes/list-markers", methods=["GET"])
@require_login
def list_markers(species_id: int):
    """List a species' genetic markers."""
    with database_connection(app.config["SQL_URI"]) as conn:
        species = species_by_id(conn, species_id)
        if not bool(species):
            flash("Invalid species provided!", "alert-danger")
            return redirect(url_for("species.populations.genotypes.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)
        markers = enumerate_sequence(
            genotype_markers(conn, species_id, offset=start_from, limit=count),
            start=start_from+1)
        return render_template("genotypes/list-markers.html",
                               species=species,
                               total_markers=genotype_markers_count(
                                   conn, species_id),
                               start_from=start_from,
                               count=count,
                               markers=markers,
                               activelink="list-markers")