swh:1:snp:7ce5f1105410d5ee1ad6abfdc873986c25b579e5
Tip revision: 96d581ac25e4425f701ec19e1ba60fa475dfe1fd authored by Dirk Roorda on 12 May 2020, 15:10:36 UTC
various enhancements
various enhancements
Tip revision: 96d581a
serve.py
import pickle
import markdown
from flask import jsonify, redirect, render_template, make_response
from ..core.helpers import console, wrapMessages
from ..applib.helpers import RESULT
from .wrap import (
pageLinks,
passageLinks,
wrapOptions,
wrapBase,
wrapCondense,
wrapFormats,
wrapProvenance,
)
from .servelib import getAbout, getFormData, zipData
TIMEOUT = 180
def serveTable(web, kind, getx=None, asDict=False):
kernelApi = web.kernelApi
aContext = web.context
interfaceDefaults = aContext.interfaceDefaults
form = getFormData(interfaceDefaults)
textFormat = form["textformat"] or None
task = form[kind].strip()
openedKey = f"{kind}Opened"
openedSet = (
{int(n) for n in form[openedKey].split(",")} if form[openedKey] else set()
)
method = dict if asDict else jsonify
messages = ""
table = None
if task:
options = {
k: form.get(k, v) for (k, v) in interfaceDefaults.items() if v is not None
}
(table, messages) = kernelApi.table(
kind,
task,
form["features"],
opened=openedSet,
fmt=textFormat,
baseTypes=form["baseTps"],
getx=int(getx) if getx else None,
**options,
)
if messages:
messages = wrapMessages(messages)
return method(table=table, messages=messages)
def serveQuery(web, getx, asDict=False):
kernelApi = web.kernelApi
aContext = web.context
interfaceDefaults = aContext.interfaceDefaults
wildQueries = web.wildQueries
kind = "query"
form = getFormData(interfaceDefaults)
task = form[kind]
condenseType = form["condenseTp"] or None
resultKind = condenseType if form["condensed"] else RESULT
textFormat = form["textformat"] or None
openedKey = f"{kind}Opened"
openedSet = (
{int(n) for n in form[openedKey].split(",")} if form[openedKey] else set()
)
pages = ""
features = ""
method = dict if asDict else jsonify
total = 0
if task:
messages = ""
table = None
if task in wildQueries:
messages = (
f"Aborted because query is known to take longer than {TIMEOUT} second"
+ ("" if TIMEOUT == 1 else "s")
)
else:
options = {
k: form.get(k, v)
for (k, v) in interfaceDefaults.items()
if v is not None
}
try:
(table, messages, features, start, total) = kernelApi.search(
task,
form["batch"],
position=form["position"],
opened=openedSet,
condensed=form["condensed"],
condenseType=condenseType,
fmt=textFormat,
baseTypes=form["baseTps"],
getx=int(getx) if getx else None,
**options,
)
except TimeoutError:
messages = (
f"Aborted because query takes longer than {TIMEOUT} second"
+ ("" if TIMEOUT == 1 else "s")
)
console(f"{task}\n{messages}", error=True)
wildQueries.add(task)
total = 0
if table is not None:
pages = pageLinks(total, form["position"])
# messages have already been shaped by search
# if messages:
# messages = wrapMessages(messages)
else:
table = f"no {resultKind}s"
messages = ""
return method(
pages=pages, table=table, nResults=total, messages=messages, features=features,
)
def servePassage(web, getx):
kernelApi = web.kernelApi
aContext = web.context
interfaceDefaults = aContext.interfaceDefaults
form = getFormData(interfaceDefaults)
textFormat = form["textformat"] or None
passages = ""
openedKey = "passageOpened"
openedSet = set(form[openedKey].split(",")) if form[openedKey] else set()
sec0 = form["sec0"]
sec1 = form["sec1"]
sec2 = form["sec2"]
options = {
k: form.get(k, v) for (k, v) in interfaceDefaults.items() if v is not None
}
(table, sec0Type, passages, browseNavLevel) = kernelApi.passage(
form["features"],
form["query"],
sec0,
sec1=sec1,
sec2=sec2,
opened=openedSet,
fmt=textFormat,
baseTypes=form["baseTps"],
getx=getx,
**options,
)
passages = pickle.loads(passages)
passages = passageLinks(passages, sec0Type, sec0, sec1, browseNavLevel)
return jsonify(table=table, passages=passages)
def serveExport(web):
aContext = web.context
interfaceDefaults = aContext.interfaceDefaults
appName = aContext.appName
kernelApi = web.kernelApi
sectionsData = serveTable(web, "sections", None, asDict=True)
tuplesData = serveTable(web, "tuples", None, asDict=True)
queryData = serveQuery(web, None, asDict=True)
form = getFormData(interfaceDefaults)
(header, appLogo, tfLogo) = kernelApi.header()
css = kernelApi.css()
provenance = kernelApi.provenance()
setNames = kernelApi.setNames()
setNamesRep = ", ".join(setNames)
setNameHtml = (
f'<p class="setnames">Sets: <span class="setnames">{setNamesRep}</span></p>'
if setNames
else ""
)
(provenanceHtml, provenanceMd) = wrapProvenance(form, provenance, setNames)
descriptionMd = markdown.markdown(
form["description"],
extensions=["markdown.extensions.tables", "markdown.extensions.fenced_code"],
)
sectionsMessages = sectionsData["messages"]
sectionsTable = sectionsData["table"]
tuplesMessages = tuplesData["messages"]
tuplesTable = tuplesData["table"]
queryMessages = queryData["messages"]
queryTable = queryData["table"]
return render_template(
"export.html",
appName=appName,
css=css,
descriptionMd=descriptionMd,
sectionsTable=(
sectionsMessages
if sectionsMessages or sectionsTable is None
else sectionsTable
),
tuplesTable=(
tuplesMessages if tuplesMessages or tuplesTable is None else tuplesTable
),
queryTable=(
queryMessages if queryMessages or queryTable is None else queryTable
),
colofon=f"{appLogo}{header}{tfLogo}",
provenance=provenanceHtml,
setNames=setNameHtml,
**form,
)
def serveDownload(web):
aContext = web.context
interfaceDefaults = aContext.interfaceDefaults
form = getFormData(interfaceDefaults)
kernelApi = web.kernelApi
wildQueries = web.wildQueries
task = form["query"]
condenseType = form["condenseTp"] or None
textFormat = form["textformat"] or None
csvs = None
resultsX = None
messages = ""
if task in wildQueries:
messages = (
f"Aborted because query is known to take longer than {TIMEOUT} second"
+ ("" if TIMEOUT == 1 else "s")
)
else:
try:
(queryMessages, csvs, resultsX) = kernelApi.csvs(
task,
form["tuples"],
form["sections"],
condensed=form["condensed"],
condenseType=condenseType,
fmt=textFormat,
)
except TimeoutError:
messages = f"Aborted because query takes longer than {TIMEOUT} second" + (
"" if TIMEOUT == 1 else "s"
)
console(f"{task}\n{messages}", error=True)
wildQueries.add(task)
return jsonify(messages=messages)
if queryMessages:
redirect("/")
return jsonify(messages=queryMessages)
(header, appLogo, tfLogo) = kernelApi.header()
provenance = kernelApi.provenance()
setNames = kernelApi.setNames()
(provenanceHtml, provenanceMd) = wrapProvenance(form, provenance, setNames)
csvs = pickle.loads(csvs)
resultsX = pickle.loads(resultsX)
about = getAbout(header, provenanceMd, form)
(fileName, zipBuffer) = zipData(csvs, resultsX, about, form)
headers = {
"Expires": "0",
"Cache-Control": "no-cache, no-store, must-revalidate",
"Content-Type": "application/octet-stream",
"Content-Disposition": f'attachment; filename="{fileName}"',
"Content-Encoding": "identity",
}
return make_response(zipBuffer, headers)
def serveAll(web, anything):
aContext = web.context
interfaceDefaults = aContext.interfaceDefaults
appName = aContext.appName
defaultBaseTypes = aContext.baseTypes
defaultCondenseType = aContext.condenseType
exampleSection = aContext.exampleSection
exampleSectionHtml = aContext.exampleSectionHtml
allowedBaseTypes = aContext.allowedBaseTypes
condenseTypes = aContext.condenseTypes
defaultFormat = aContext.defaultFormat
allFormats = aContext.allFormats
kernelApi = web.kernelApi
form = getFormData(interfaceDefaults)
condensedAtt = " checked " if form["condensed"] else ""
pages = ""
passages = ""
(header, appLogo, tfLogo) = kernelApi.header()
css = kernelApi.css()
provenance = kernelApi.provenance()
setNames = kernelApi.setNames()
setNamesRep = ", ".join(setNames)
setNameHtml = (
f'<p class="setnames">Sets: <span class="setnames">{setNamesRep}</span></p>'
if setNames
else ""
)
(provenanceHtml, provenanceMd) = wrapProvenance(form, provenance, setNames)
baseTypes = form["baseTps"]
baseOpts = wrapBase(allowedBaseTypes, baseTypes)
condenseType = form["condenseTp"] or defaultCondenseType
condenseOpts = wrapCondense(condenseTypes, condenseType)
textFormat = form["textformat"] or defaultFormat
textFormatOpts = wrapFormats(allFormats, textFormat)
(options, optionsHelp) = wrapOptions(aContext, form)
templateData = dict(
appName=appName,
css=css,
header=f"{appLogo}{header}{tfLogo}",
setNames=setNameHtml,
options=options,
optionsHelp=optionsHelp,
condensedAtt=condensedAtt,
baseOpts=baseOpts,
defaultBaseTypes=defaultBaseTypes,
condenseOpts=condenseOpts,
defaultCondenseType=defaultCondenseType,
textFormatOpts=textFormatOpts,
defaultFormat=defaultFormat,
exampleSectionHtml=exampleSectionHtml,
exampleSection=exampleSection,
pages=pages,
passages=passages,
)
templateData.update(form)
return render_template(
"index.html",
**templateData,
)