Module control.api

Overview page of contributions.

  • Country selection
  • Grouping by categories
  • Statistics
Expand source code
"""Overview page of contributions.

*   Country selection
*   Grouping by categories
*   Statistics
"""

from flask import make_response

from config import Names as N
from control.utils import mjson, mktsv, pick as G, serverprint
from control.table import Table, SENSITIVE_TABLES, SENSITIVE_FIELDS
from control.typ.related import castObjectId


REVIEWED1 = "reviewed1"
REVIEWED2 = "reviewed2"
R1RANK = "r1Rank"
R2RANK = "r2Rank"

ASSESSED_STATUS = {
    None: ("no assessment", "a-none"),
    N.incomplete: ("started", "a-started"),
    N.incompleteRevised: ("revision", "a-started"),
    N.incompleteWithdrawn: ("withdrawn", "a-none"),
    N.complete: ("filled-in", "a-self"),
    N.completeRevised: ("revised", "a-self"),
    N.completeWithdrawn: ("withdrawn", "a-none"),
    N.submitted: ("in review", "a-inreview"),
    N.submittedRevised: ("in review", "a-inreview"),
    N.reviewReject: ("rejected", "a-rejected"),
    N.reviewAccept: ("accepted", "a-accepted"),
}
ASSESSED_LABELS = {stage: info[0] for (stage, info) in ASSESSED_STATUS.items()}
ASSESSED_CLASS = {stage: info[1] for (stage, info) in ASSESSED_STATUS.items()}
ASSESSED_CLASS1 = {info[0]: info[1] for info in ASSESSED_STATUS.values()}
ASSESSED_DEFAULT_CLASS = ASSESSED_STATUS[None][1]
ASSESSED_RANK = {stage: i for (i, stage) in enumerate(ASSESSED_STATUS)}

NO_REVIEW = {
    N.incomplete,
    N.incompleteRevised,
    N.incompleteWithdrawn,
    N.complete,
    N.completeRevised,
    N.completeWithdrawn,
}
IN_REVIEW = {
    N.submitted,
    N.submittedRevised,
}
ADVISORY_REVIEW = {
    N.reviewAdviseAccept,
    N.reviewAdviseReject,
    N.reviewAdviseRevise,
}
FINAL_REVIEW = {
    N.reviewAccept,
    N.reviewReject,
    N.reviewRevise,
}


REVIEWED_STATUS = {
    None: ("", "r-none"),
    "noReview": ("not reviewable", "r-noreview"),
    "inReview": ("in review", "r-inreview"),
    "skipReview": ("review skipped", "r-skipreview"),
    N.reviewAdviseReject: ("rejected", "r-rejected"),
    N.reviewAdviseAccept: ("accepted", "r-accepted"),
    N.reviewAdviseRevise: ("revise", "r-revised"),
    N.reviewReject: ("rejected", "r-rejected"),
    N.reviewAccept: ("accepted", "r-accepted"),
    N.reviewRevise: ("revise", "r-revised"),
}
REVIEW_LABELS = {stage: info[0] for (stage, info) in REVIEWED_STATUS.items()}
REVIEW_CLASS = {stage: info[1] for (stage, info) in REVIEWED_STATUS.items()}
REVIEW_CLASS1 = {info[0]: info[1] for info in REVIEWED_STATUS.values()}
REVIEW_DEFAULT_CLASS = REVIEWED_STATUS[None][1]
REVIEW_RANK = {stage: i for (i, stage) in enumerate(REVIEWED_STATUS)}


class Api:
    def __init__(self, context):
        self.context = context

        types = context.types
        self.countryType = types.country
        self.yearType = types.year
        self.typeType = types.typeContribution
        self.headers = dict(
            json={
                "Expires": "0",
                "Cache-Control": "no-cache, no-store, must-revalidate",
                "Content-Type": "application/json",
                "Content-Encoding": "utf-8",
            },
            tsv={
                "Expires": "0",
                "Cache-Control": "no-cache, no-store, must-revalidate",
                "Content-Type": "text/tab-separated-values",
                "Content-Encoding": "utf-8",
            },
        )

    def notimplemented(self, verb):
        serverprint(f"Invalid api call requested: {verb}")
        return make_response(mjson(None), self.headers["json"])

    def list(self, givenTable):
        parts = givenTable.rsplit(".", 1)
        if len(parts) == 1:
            table = givenTable
            ext = "json"
        else:
            (table, ext) = parts
        if ext not in {"json", "tsv"}:
            serverprint(f"Invalid extension: {ext} in {givenTable}")
            return make_response(mjson(None), self.headers["json"])

        data = None
        if table is not None and table not in SENSITIVE_TABLES:
            if table == "contrib":
                data = self.getContribs(ext)
            else:
                context = self.context
                tableObj = Table(context, table)
                data = tableObj.wrap(None, logical=True)
        if data is None:
            serverprint(f"Non existing table requested: {table}")
        return make_response(
            mjson(data) if ext == "json" else mktsv(data), self.headers[ext]
        )

    def view(self, table, givenEid):
        record = None
        eid = castObjectId(givenEid)
        if table is not None and eid is not None and table not in SENSITIVE_TABLES:
            context = self.context
            tableObj = Table(context, table)
            recordObj = tableObj.record(eid=eid)
            record = recordObj.wrapLogical()
            if table == "contrib":
                extra = self.getExtra(record)
                for (k, v) in extra.items():
                    record[k] = v
                for k in SENSITIVE_FIELDS:
                    if k in record:
                        del record[k]
                k = "typeContribution"
                if k in record:
                    record["type"] = record[k]
                    del record[k]
        if record is None:
            serverprint(f"Non existing record requested: {table}/{givenEid}")
        return make_response(mjson(record), self.headers["json"])

    def getExtra(self, record):
        context = self.context
        wf = context.wf
        workflow = wf.computeWorkflow(record)

        selected = G(workflow, N.selected)
        aStage = G(workflow, N.aStage)
        r2Stage = G(workflow, N.r2Stage)
        if r2Stage in {N.reviewAccept, N.reviewReject}:
            aStage = r2Stage
        score = G(workflow, N.score)
        assessed = ASSESSED_STATUS[aStage][0]
        aRank = (G(ASSESSED_RANK, aStage, default=0), score or 0)
        if aStage != N.reviewAccept:
            score = None

        extra = {
            N.assessed: assessed,
            N.arank: aRank,
            N.astage: aStage,
            N.score: score,
            N.selected: selected,
        }
        preR1Stage = G(workflow, N.r1Stage)
        noReview = aStage is None or aStage in NO_REVIEW
        inReview = aStage in IN_REVIEW
        advReview = preR1Stage in ADVISORY_REVIEW
        r1Stage = (
            "noReview"
            if noReview
            else preR1Stage
            if advReview
            else "inReview"
            if inReview
            else "skipReview"
        )
        r2Stage = (
            "noReview"
            if noReview
            else "inReview"
            if inReview
            else G(workflow, N.r2Stage)
        )
        reviewed1 = REVIEWED_STATUS[r1Stage][0]
        reviewed2 = REVIEWED_STATUS[r2Stage][0]
        r1Rank = G(REVIEW_RANK, r1Stage, default=0)
        r2Rank = G(REVIEW_RANK, r2Stage, default=0)
        extra.update(
            {
                REVIEWED1: reviewed1,
                REVIEWED2: reviewed2,
                R1RANK: r1Rank,
                R2RANK: r2Rank,
                N.r1Stage: r1Stage,
                N.r2Stage: r2Stage,
            }
        )
        return extra

    def getContribs(self, ext):
        context = self.context
        db = context.db
        countryType = self.countryType
        yearType = self.yearType
        typeType = self.typeType

        asTsv = ext == "tsv"

        contribs = []

        if asTsv:
            contribsFull = {G(r, N._id): r for r in db.getList(N.contrib)}
            context = self.context
            tableObj = Table(context, N.contrib)

        for record in db.bulkContribWorkflow(None, False):
            title = G(record, N.title)
            contribId = G(record, N._id)

            selected = G(record, N.selected)
            aStage = G(record, N.aStage)
            r2Stage = G(record, N.r2Stage)
            if r2Stage in {N.reviewAccept, N.reviewReject}:
                aStage = r2Stage
            score = G(record, N.score)
            assessed = ASSESSED_STATUS[aStage][0]
            aRank = (G(ASSESSED_RANK, aStage, default=0), score or 0)
            if aStage != N.reviewAccept:
                score = None

            countryRep = countryType.titleStr(
                G(db.country, G(record, N.country)), markup=None
            )
            yearRep = yearType.titleStr(G(db.year, G(record, N.year)), markup=None)
            typeRep = typeType.titleStr(
                G(db.typeContribution, G(record, N.type)), markup=None
            )

            contribRecord = {
                N._id: contribId,
                N.country: countryRep,
                N.year: yearRep,
                N.type: typeRep,
                N.title: title,
                N.assessed: assessed,
                N.arank: aRank,
                N.astage: aStage,
                N.score: score,
                N.selected: selected,
            }
            preR1Stage = G(record, N.r1Stage)
            noReview = aStage is None or aStage in NO_REVIEW
            inReview = aStage in IN_REVIEW
            advReview = preR1Stage in ADVISORY_REVIEW
            r1Stage = (
                "noReview"
                if noReview
                else preR1Stage
                if advReview
                else "inReview"
                if inReview
                else "skipReview"
            )
            r2Stage = (
                "noReview"
                if noReview
                else "inReview"
                if inReview
                else G(record, N.r2Stage)
            )
            reviewed1 = REVIEWED_STATUS[r1Stage][0]
            reviewed2 = REVIEWED_STATUS[r2Stage][0]
            r1Rank = G(REVIEW_RANK, r1Stage, default=0)
            r2Rank = G(REVIEW_RANK, r2Stage, default=0)
            contribRecord.update(
                {
                    REVIEWED1: reviewed1,
                    REVIEWED2: reviewed2,
                    R1RANK: r1Rank,
                    R2RANK: r2Rank,
                    N.r1Stage: r1Stage,
                    N.r2Stage: r2Stage,
                }
            )
            if asTsv:
                fullObj = tableObj.record(record=G(contribsFull, contribId, {}))
                full = fullObj.wrapLogical()
                contribRecord.update({
                    N.dateDecided: G(full, N.dateDecided),
                    N.vcc: G(full, N.vcc),
                    N.description: G(full, N.description),
                    N.contactPersonName: G(full, N.contactPersonName),
                    N.contactPersonEmail: G(full, N.contactPersonEmail),
                    N.urlContribution: G(full, N.urlContribution),
                    N.urlAcademic: G(full, N.urlAcademic),
                    N.tadirahObject: G(full, N.tadirahObject),
                    N.tadirahActivity: G(full, N.tadirahActivity),
                    N.tadirahTechnique: G(full, N.tadirahTechnique),
                    N.keyword: G(full, N.keyword),
                    N.discipline: G(full, N.discipline),
                })
            contribs.append(contribRecord)

        return contribs

Classes

class Api (context)
Expand source code
class Api:
    def __init__(self, context):
        self.context = context

        types = context.types
        self.countryType = types.country
        self.yearType = types.year
        self.typeType = types.typeContribution
        self.headers = dict(
            json={
                "Expires": "0",
                "Cache-Control": "no-cache, no-store, must-revalidate",
                "Content-Type": "application/json",
                "Content-Encoding": "utf-8",
            },
            tsv={
                "Expires": "0",
                "Cache-Control": "no-cache, no-store, must-revalidate",
                "Content-Type": "text/tab-separated-values",
                "Content-Encoding": "utf-8",
            },
        )

    def notimplemented(self, verb):
        serverprint(f"Invalid api call requested: {verb}")
        return make_response(mjson(None), self.headers["json"])

    def list(self, givenTable):
        parts = givenTable.rsplit(".", 1)
        if len(parts) == 1:
            table = givenTable
            ext = "json"
        else:
            (table, ext) = parts
        if ext not in {"json", "tsv"}:
            serverprint(f"Invalid extension: {ext} in {givenTable}")
            return make_response(mjson(None), self.headers["json"])

        data = None
        if table is not None and table not in SENSITIVE_TABLES:
            if table == "contrib":
                data = self.getContribs(ext)
            else:
                context = self.context
                tableObj = Table(context, table)
                data = tableObj.wrap(None, logical=True)
        if data is None:
            serverprint(f"Non existing table requested: {table}")
        return make_response(
            mjson(data) if ext == "json" else mktsv(data), self.headers[ext]
        )

    def view(self, table, givenEid):
        record = None
        eid = castObjectId(givenEid)
        if table is not None and eid is not None and table not in SENSITIVE_TABLES:
            context = self.context
            tableObj = Table(context, table)
            recordObj = tableObj.record(eid=eid)
            record = recordObj.wrapLogical()
            if table == "contrib":
                extra = self.getExtra(record)
                for (k, v) in extra.items():
                    record[k] = v
                for k in SENSITIVE_FIELDS:
                    if k in record:
                        del record[k]
                k = "typeContribution"
                if k in record:
                    record["type"] = record[k]
                    del record[k]
        if record is None:
            serverprint(f"Non existing record requested: {table}/{givenEid}")
        return make_response(mjson(record), self.headers["json"])

    def getExtra(self, record):
        context = self.context
        wf = context.wf
        workflow = wf.computeWorkflow(record)

        selected = G(workflow, N.selected)
        aStage = G(workflow, N.aStage)
        r2Stage = G(workflow, N.r2Stage)
        if r2Stage in {N.reviewAccept, N.reviewReject}:
            aStage = r2Stage
        score = G(workflow, N.score)
        assessed = ASSESSED_STATUS[aStage][0]
        aRank = (G(ASSESSED_RANK, aStage, default=0), score or 0)
        if aStage != N.reviewAccept:
            score = None

        extra = {
            N.assessed: assessed,
            N.arank: aRank,
            N.astage: aStage,
            N.score: score,
            N.selected: selected,
        }
        preR1Stage = G(workflow, N.r1Stage)
        noReview = aStage is None or aStage in NO_REVIEW
        inReview = aStage in IN_REVIEW
        advReview = preR1Stage in ADVISORY_REVIEW
        r1Stage = (
            "noReview"
            if noReview
            else preR1Stage
            if advReview
            else "inReview"
            if inReview
            else "skipReview"
        )
        r2Stage = (
            "noReview"
            if noReview
            else "inReview"
            if inReview
            else G(workflow, N.r2Stage)
        )
        reviewed1 = REVIEWED_STATUS[r1Stage][0]
        reviewed2 = REVIEWED_STATUS[r2Stage][0]
        r1Rank = G(REVIEW_RANK, r1Stage, default=0)
        r2Rank = G(REVIEW_RANK, r2Stage, default=0)
        extra.update(
            {
                REVIEWED1: reviewed1,
                REVIEWED2: reviewed2,
                R1RANK: r1Rank,
                R2RANK: r2Rank,
                N.r1Stage: r1Stage,
                N.r2Stage: r2Stage,
            }
        )
        return extra

    def getContribs(self, ext):
        context = self.context
        db = context.db
        countryType = self.countryType
        yearType = self.yearType
        typeType = self.typeType

        asTsv = ext == "tsv"

        contribs = []

        if asTsv:
            contribsFull = {G(r, N._id): r for r in db.getList(N.contrib)}
            context = self.context
            tableObj = Table(context, N.contrib)

        for record in db.bulkContribWorkflow(None, False):
            title = G(record, N.title)
            contribId = G(record, N._id)

            selected = G(record, N.selected)
            aStage = G(record, N.aStage)
            r2Stage = G(record, N.r2Stage)
            if r2Stage in {N.reviewAccept, N.reviewReject}:
                aStage = r2Stage
            score = G(record, N.score)
            assessed = ASSESSED_STATUS[aStage][0]
            aRank = (G(ASSESSED_RANK, aStage, default=0), score or 0)
            if aStage != N.reviewAccept:
                score = None

            countryRep = countryType.titleStr(
                G(db.country, G(record, N.country)), markup=None
            )
            yearRep = yearType.titleStr(G(db.year, G(record, N.year)), markup=None)
            typeRep = typeType.titleStr(
                G(db.typeContribution, G(record, N.type)), markup=None
            )

            contribRecord = {
                N._id: contribId,
                N.country: countryRep,
                N.year: yearRep,
                N.type: typeRep,
                N.title: title,
                N.assessed: assessed,
                N.arank: aRank,
                N.astage: aStage,
                N.score: score,
                N.selected: selected,
            }
            preR1Stage = G(record, N.r1Stage)
            noReview = aStage is None or aStage in NO_REVIEW
            inReview = aStage in IN_REVIEW
            advReview = preR1Stage in ADVISORY_REVIEW
            r1Stage = (
                "noReview"
                if noReview
                else preR1Stage
                if advReview
                else "inReview"
                if inReview
                else "skipReview"
            )
            r2Stage = (
                "noReview"
                if noReview
                else "inReview"
                if inReview
                else G(record, N.r2Stage)
            )
            reviewed1 = REVIEWED_STATUS[r1Stage][0]
            reviewed2 = REVIEWED_STATUS[r2Stage][0]
            r1Rank = G(REVIEW_RANK, r1Stage, default=0)
            r2Rank = G(REVIEW_RANK, r2Stage, default=0)
            contribRecord.update(
                {
                    REVIEWED1: reviewed1,
                    REVIEWED2: reviewed2,
                    R1RANK: r1Rank,
                    R2RANK: r2Rank,
                    N.r1Stage: r1Stage,
                    N.r2Stage: r2Stage,
                }
            )
            if asTsv:
                fullObj = tableObj.record(record=G(contribsFull, contribId, {}))
                full = fullObj.wrapLogical()
                contribRecord.update({
                    N.dateDecided: G(full, N.dateDecided),
                    N.vcc: G(full, N.vcc),
                    N.description: G(full, N.description),
                    N.contactPersonName: G(full, N.contactPersonName),
                    N.contactPersonEmail: G(full, N.contactPersonEmail),
                    N.urlContribution: G(full, N.urlContribution),
                    N.urlAcademic: G(full, N.urlAcademic),
                    N.tadirahObject: G(full, N.tadirahObject),
                    N.tadirahActivity: G(full, N.tadirahActivity),
                    N.tadirahTechnique: G(full, N.tadirahTechnique),
                    N.keyword: G(full, N.keyword),
                    N.discipline: G(full, N.discipline),
                })
            contribs.append(contribRecord)

        return contribs

Methods

def getContribs(self, ext)
Expand source code
def getContribs(self, ext):
    context = self.context
    db = context.db
    countryType = self.countryType
    yearType = self.yearType
    typeType = self.typeType

    asTsv = ext == "tsv"

    contribs = []

    if asTsv:
        contribsFull = {G(r, N._id): r for r in db.getList(N.contrib)}
        context = self.context
        tableObj = Table(context, N.contrib)

    for record in db.bulkContribWorkflow(None, False):
        title = G(record, N.title)
        contribId = G(record, N._id)

        selected = G(record, N.selected)
        aStage = G(record, N.aStage)
        r2Stage = G(record, N.r2Stage)
        if r2Stage in {N.reviewAccept, N.reviewReject}:
            aStage = r2Stage
        score = G(record, N.score)
        assessed = ASSESSED_STATUS[aStage][0]
        aRank = (G(ASSESSED_RANK, aStage, default=0), score or 0)
        if aStage != N.reviewAccept:
            score = None

        countryRep = countryType.titleStr(
            G(db.country, G(record, N.country)), markup=None
        )
        yearRep = yearType.titleStr(G(db.year, G(record, N.year)), markup=None)
        typeRep = typeType.titleStr(
            G(db.typeContribution, G(record, N.type)), markup=None
        )

        contribRecord = {
            N._id: contribId,
            N.country: countryRep,
            N.year: yearRep,
            N.type: typeRep,
            N.title: title,
            N.assessed: assessed,
            N.arank: aRank,
            N.astage: aStage,
            N.score: score,
            N.selected: selected,
        }
        preR1Stage = G(record, N.r1Stage)
        noReview = aStage is None or aStage in NO_REVIEW
        inReview = aStage in IN_REVIEW
        advReview = preR1Stage in ADVISORY_REVIEW
        r1Stage = (
            "noReview"
            if noReview
            else preR1Stage
            if advReview
            else "inReview"
            if inReview
            else "skipReview"
        )
        r2Stage = (
            "noReview"
            if noReview
            else "inReview"
            if inReview
            else G(record, N.r2Stage)
        )
        reviewed1 = REVIEWED_STATUS[r1Stage][0]
        reviewed2 = REVIEWED_STATUS[r2Stage][0]
        r1Rank = G(REVIEW_RANK, r1Stage, default=0)
        r2Rank = G(REVIEW_RANK, r2Stage, default=0)
        contribRecord.update(
            {
                REVIEWED1: reviewed1,
                REVIEWED2: reviewed2,
                R1RANK: r1Rank,
                R2RANK: r2Rank,
                N.r1Stage: r1Stage,
                N.r2Stage: r2Stage,
            }
        )
        if asTsv:
            fullObj = tableObj.record(record=G(contribsFull, contribId, {}))
            full = fullObj.wrapLogical()
            contribRecord.update({
                N.dateDecided: G(full, N.dateDecided),
                N.vcc: G(full, N.vcc),
                N.description: G(full, N.description),
                N.contactPersonName: G(full, N.contactPersonName),
                N.contactPersonEmail: G(full, N.contactPersonEmail),
                N.urlContribution: G(full, N.urlContribution),
                N.urlAcademic: G(full, N.urlAcademic),
                N.tadirahObject: G(full, N.tadirahObject),
                N.tadirahActivity: G(full, N.tadirahActivity),
                N.tadirahTechnique: G(full, N.tadirahTechnique),
                N.keyword: G(full, N.keyword),
                N.discipline: G(full, N.discipline),
            })
        contribs.append(contribRecord)

    return contribs
def getExtra(self, record)
Expand source code
def getExtra(self, record):
    context = self.context
    wf = context.wf
    workflow = wf.computeWorkflow(record)

    selected = G(workflow, N.selected)
    aStage = G(workflow, N.aStage)
    r2Stage = G(workflow, N.r2Stage)
    if r2Stage in {N.reviewAccept, N.reviewReject}:
        aStage = r2Stage
    score = G(workflow, N.score)
    assessed = ASSESSED_STATUS[aStage][0]
    aRank = (G(ASSESSED_RANK, aStage, default=0), score or 0)
    if aStage != N.reviewAccept:
        score = None

    extra = {
        N.assessed: assessed,
        N.arank: aRank,
        N.astage: aStage,
        N.score: score,
        N.selected: selected,
    }
    preR1Stage = G(workflow, N.r1Stage)
    noReview = aStage is None or aStage in NO_REVIEW
    inReview = aStage in IN_REVIEW
    advReview = preR1Stage in ADVISORY_REVIEW
    r1Stage = (
        "noReview"
        if noReview
        else preR1Stage
        if advReview
        else "inReview"
        if inReview
        else "skipReview"
    )
    r2Stage = (
        "noReview"
        if noReview
        else "inReview"
        if inReview
        else G(workflow, N.r2Stage)
    )
    reviewed1 = REVIEWED_STATUS[r1Stage][0]
    reviewed2 = REVIEWED_STATUS[r2Stage][0]
    r1Rank = G(REVIEW_RANK, r1Stage, default=0)
    r2Rank = G(REVIEW_RANK, r2Stage, default=0)
    extra.update(
        {
            REVIEWED1: reviewed1,
            REVIEWED2: reviewed2,
            R1RANK: r1Rank,
            R2RANK: r2Rank,
            N.r1Stage: r1Stage,
            N.r2Stage: r2Stage,
        }
    )
    return extra
def list(self, givenTable)
Expand source code
def list(self, givenTable):
    parts = givenTable.rsplit(".", 1)
    if len(parts) == 1:
        table = givenTable
        ext = "json"
    else:
        (table, ext) = parts
    if ext not in {"json", "tsv"}:
        serverprint(f"Invalid extension: {ext} in {givenTable}")
        return make_response(mjson(None), self.headers["json"])

    data = None
    if table is not None and table not in SENSITIVE_TABLES:
        if table == "contrib":
            data = self.getContribs(ext)
        else:
            context = self.context
            tableObj = Table(context, table)
            data = tableObj.wrap(None, logical=True)
    if data is None:
        serverprint(f"Non existing table requested: {table}")
    return make_response(
        mjson(data) if ext == "json" else mktsv(data), self.headers[ext]
    )
def notimplemented(self, verb)
Expand source code
def notimplemented(self, verb):
    serverprint(f"Invalid api call requested: {verb}")
    return make_response(mjson(None), self.headers["json"])
def view(self, table, givenEid)
Expand source code
def view(self, table, givenEid):
    record = None
    eid = castObjectId(givenEid)
    if table is not None and eid is not None and table not in SENSITIVE_TABLES:
        context = self.context
        tableObj = Table(context, table)
        recordObj = tableObj.record(eid=eid)
        record = recordObj.wrapLogical()
        if table == "contrib":
            extra = self.getExtra(record)
            for (k, v) in extra.items():
                record[k] = v
            for k in SENSITIVE_FIELDS:
                if k in record:
                    del record[k]
            k = "typeContribution"
            if k in record:
                record["type"] = record[k]
                del record[k]
    if record is None:
        serverprint(f"Non existing record requested: {table}/{givenEid}")
    return make_response(mjson(record), self.headers["json"])