"""Endpoints for publications"""
import json
from gn_libs.mysqldb import database_connection
from flask import (
flash,
request,
redirect,
Blueprint,
render_template,
current_app as app)
from uploader.flask_extensions import url_for
from uploader.authorisation import require_login
from uploader.route_utils import redirect_to_next
from .models import (
delete_publications,
update_publications,
fetch_publication_by_id,
create_new_publications,
fetch_publication_phenotypes)
from .datatables import fetch_publications
pubbp = Blueprint("publications", __name__)
@pubbp.route("/", methods=["GET"])
@require_login
def index():
"""Index page for publications."""
return render_template("publications/index.html")
@pubbp.route("/list", methods=["GET"])
@require_login
def list_publications():
"""Fetch publications that fulfill a specific search, or all of them, if
there is no search term."""
# request breakdown:
# https://datatables.net/manual/server-side
_page = int(request.args.get("draw"))
_length = int(request.args.get("length") or '-1')
_start = int(request.args.get("start") or '0')
_search = request.args["search[value]"]
with database_connection(app.config["SQL_URI"]) as conn:
_publications, _current_rows, _totalfiltered, _totalrows = fetch_publications(
conn,
_search,
offset=_start,
limit=_length)
return json.dumps({
"draw": _page,
"recordsTotal": _totalrows,
"recordsFiltered": _totalfiltered,
"publications": _publications,
"status": "success"
})
@pubbp.route("/view/<int:publication_id>", methods=["GET"])
@require_login
def view_publication(publication_id: int):
"""View more details on a particular publication."""
with database_connection(app.config["SQL_URI"]) as conn:
publication = fetch_publication_by_id(conn, publication_id)
if not bool(publication):
flash("Requested publication was not found!", "alert-warning")
return redirect(url_for('publications.index'))
return render_template(
"publications/view-publication.html",
publication=publication,
linked_phenotypes=tuple(fetch_publication_phenotypes(
conn, publication_id)))
@pubbp.route("/create", methods=["GET", "POST"])
@require_login
def create_publication():
"""Create a new publication."""
_get_args = {
key: request.args[key]
for key in ("species_id", "population_id", "dataset_id", "return_to")
if bool(request.args.get(key))
}
if request.method == "GET":
return render_template(
"publications/create-publication.html",
get_args=_get_args)
form = request.form
authors = form.get("publication-authors").encode("utf8")
if authors is None or authors == "":
flash("The publication's author(s) MUST be provided!", "alert alert-danger")
return redirect(url_for("publications.create"))
with database_connection(app.config["SQL_URI"]) as conn:
publications = create_new_publications(conn, ({
"pubmed_id": form.get("pubmed-id") or None,
"abstract": form.get("publication-abstract").encode("utf8") or None,
"authors": authors,
"title": form.get("publication-title").encode("utf8") or None,
"journal": form.get("publication-journal").encode("utf8") or None,
"volume": form.get("publication-volume").encode("utf8") or None,
"pages": form.get("publication-pages").encode("utf8") or None,
"month": (form.get("publication-month") or "").encode("utf8").capitalize() or None,
"year": form.get("publication-year").encode("utf8") or None
},))
flash("New publication created!", "alert alert-success")
return redirect(url_for(
request.args.get("return_to") or "publications.view_publication",
publication_id=publications[0]["publication_id"],
**_get_args))
flash("Publication creation failed!", "alert alert-danger")
app.logger.debug("Failed to create the new publication.", exc_info=True)
return redirect(url_for("publications.create_publication"))
@pubbp.route("/edit/<int:publication_id>", methods=["GET", "POST"])
@require_login
def edit_publication(publication_id: int):
"""Edit a publication's details."""
with database_connection(app.config["SQL_URI"]) as conn:
if request.method == "GET":
return render_template(
"publications/edit-publication.html",
publication=fetch_publication_by_id(conn, publication_id),
linked_phenotypes=tuple(fetch_publication_phenotypes(
conn, publication_id)),
publication_id=publication_id)
form = request.form
_pub = update_publications(conn, ({
"publication_id": publication_id,
"pubmed_id": form.get("pubmed-id") or None,
"abstract": (form.get("publication-abstract") or "").encode("utf8") or None,
"authors": (form.get("publication-authors") or "").encode("utf8"),
"title": (form.get("publication-title") or "").encode("utf8") or None,
"journal": (form.get("publication-journal") or "").encode("utf8") or None,
"volume": (form.get("publication-volume") or "").encode("utf8") or None,
"pages": (form.get("publication-pages") or "").encode("utf8") or None,
"month": (form.get("publication-month") or "").encode("utf8").capitalize() or None,
"year": (form.get("publication-year") or "").encode("utf8") or None
},))
if not _pub:
flash("There was an error updating the publication details.",
"alert-danger")
return redirect(url_for(
"publications.edit_publication", publication_id=publication_id))
flash("Successfully updated the publication details.",
"alert-success")
return redirect_to_next({
"uri": "publications.view_publication",
"publication_id": publication_id
})
@pubbp.route("/delete/<int:publication_id>", methods=["GET", "POST"])
@require_login
def delete_publication(publication_id: int):
"""Delete a particular publication."""
with database_connection(app.config["SQL_URI"]) as conn:
publication = fetch_publication_by_id(conn, publication_id)
linked_phenotypes=tuple(fetch_publication_phenotypes(
conn, publication_id))
if not bool(publication):
flash("Requested publication was not found!", "alert-warning")
return redirect(url_for('publications.index'))
if len(linked_phenotypes) > 0:
flash("Cannot delete publication with linked phenotypes!",
"alert-warning")
return redirect(url_for(
"publications.view_publication",
publication_id=publication_id))
if request.method == "GET":
return render_template(
"publications/delete-publication.html",
publication=publication,
linked_phenotypes=linked_phenotypes,
publication_id=publication_id)
delete_publications(conn, (publication,))
flash("Deleted the publication successfully.", "alert-success")
return redirect(url_for("publications.index"))