aboutsummaryrefslogtreecommitdiff
path: root/gn3/api/metadata_api/wiki.py
blob: 3dce729fc05be802afee6ff21f593902cba159a5 (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
128
129
130
131
132
133
134
135
136
137
138
139
"""API for accessing/editting wiki metadata"""

import datetime
from typing import Any, Dict

from flask import Blueprint, request, jsonify, current_app, make_response

from gn3 import db_utils
from gn3.auth.authorisation.oauth2.resource_server import require_oauth
from gn3.db import wiki
from gn3.db.rdf.wiki import (get_wiki_entries_by_symbol,
                             get_comment_history)


wiki_blueprint = Blueprint("wiki", __name__, url_prefix="wiki")


@wiki_blueprint.route("/<int:comment_id>/edit", methods=["POST"])
@require_oauth("profile")
def edit_wiki(comment_id: int):
    """Edit wiki comment. This is achieved by adding another entry with a new VersionId"""
    # FIXME: attempt to check and fix for types here with relevant errors
    payload: Dict[str, Any] = request.json  # type: ignore
    pubmed_ids = [str(x) for x in payload.get("pubmed_ids", [])]

    insert_dict = {
        "Id": comment_id,
        "symbol": payload["symbol"],
        "PubMed_ID": " ".join(pubmed_ids),
        "comment": payload["comment"],
        "email": payload["email"],
        "createtime": datetime.datetime.now(datetime.timezone.utc).strftime(
            "%Y-%m-%d %H:%M"
        ),
        "user_ip": request.environ.get("HTTP_X_REAL_IP", request.remote_addr),
        "weburl": payload.get("web_url"),
        "initial": payload.get("initial"),
        "reason": payload["reason"],
    }

    insert_query = """
    INSERT INTO GeneRIF (Id, versionId, symbol, PubMed_ID, SpeciesID, comment,
                         email, createtime, user_ip, weburl, initial, reason)
    VALUES (%(Id)s, %(versionId)s, %(symbol)s, %(PubMed_ID)s, %(SpeciesID)s, %(comment)s, %(email)s, %(createtime)s, %(user_ip)s, %(weburl)s, %(initial)s, %(reason)s)
    """
    with db_utils.database_connection(current_app.config["SQL_URI"]) as conn:
        cursor = conn.cursor()
        try:
            category_ids = wiki.get_categories_ids(
                cursor, payload["categories"])
            species_id = wiki.get_species_id(cursor, payload["species"])
            next_version = wiki.get_next_comment_version(cursor, comment_id)
        except wiki.MissingDBDataException as missing_exc:
            return jsonify(error=f"Error editting wiki entry, {missing_exc}"), 500
        insert_dict["SpeciesID"] = species_id
        insert_dict["versionId"] = next_version
        current_app.logger.debug(f"Running query: {insert_query}")
        cursor.execute(insert_query, insert_dict)
        category_addition_query = """
            INSERT INTO GeneRIFXRef (GeneRIFId, versionId, GeneCategoryId)
                VALUES (%s, %s, %s)
            """

        for cat_id in category_ids:
            current_app.logger.debug(
                f"Running query: {category_addition_query}")
            cursor.execute(
                category_addition_query, (comment_id,
                                          insert_dict["versionId"], cat_id)
            )
        return jsonify({"success": "ok"})
    return jsonify(error="Error editing wiki entry, most likely due to DB error!"), 500


@wiki_blueprint.route("/<string:symbol>", methods=["GET"])
def get_wiki_entries(symbol: str):
    """Fetch wiki entries"""
    status_code = 200
    response = get_wiki_entries_by_symbol(
        symbol=symbol,
        sparql_uri=current_app.config["SPARQL_ENDPOINT"])
    data = response.get("data")
    if not data:
        data = {}
        status_code = 404
    if request.headers.get("Accept") == "application/ld+json":
        payload = make_response(response)
        payload.headers["Content-Type"] = "application/ld+json"
        return payload, status_code
    return jsonify(data), status_code


@wiki_blueprint.route("/<int:comment_id>", methods=["GET"])
def get_wiki(comment_id: int):
    """
    Gets latest wiki comments.

    TODO: fetch this from RIF
    """
    with db_utils.database_connection(current_app.config["SQL_URI"]) as conn:
        return jsonify(wiki.get_latest_comment(conn, comment_id))
    return jsonify(error="Error fetching wiki entry, most likely due to DB error!"), 500


@wiki_blueprint.route("/categories", methods=["GET"])
def get_categories():
    """ Gets list of supported categories for RIF """
    with db_utils.database_connection(current_app.config["SQL_URI"]) as conn:
        cursor = conn.cursor()
        categories_dict = wiki.get_categories(cursor)
        return jsonify(categories_dict)
    return jsonify(error="Error getting categories, most likely due to DB error!"), 500


@wiki_blueprint.route("/species", methods=["GET"])
def get_species():
    """ Gets list of all species, contains name and SpeciesName """
    with db_utils.database_connection(current_app.config["SQL_URI"]) as conn:
        cursor = conn.cursor()
        species_dict = wiki.get_species(cursor)
        return jsonify(species_dict)
    return jsonify(error="Error getting species, most likely due to DB error!"), 500


@wiki_blueprint.route("/<int:comment_id>/history", methods=["GET"])
def get_history(comment_id):
    """Fetch all of a given comment's history given it's comment id"""
    status_code = 200
    response = get_comment_history(comment_id=comment_id,
                                   sparql_uri=current_app.config["SPARQL_ENDPOINT"])
    data = response.get("data")
    if not data:
        data = {}
        status_code = 404
    if request.headers.get("Accept") == "application/ld+json":
        payload = make_response(response)
        payload.headers["Content-Type"] = "application/ld+json"
        return payload, status_code
    return jsonify(data), status_code