swh:1:snp:7ce5f1105410d5ee1ad6abfdc873986c25b579e5
Tip revision: 654c41a7c75454ea2b22dc83a6ec5d19a21e8d49 authored by Dirk Roorda on 14 December 2018, 15:19:47 UTC
import glitch
import glitch
Tip revision: 654c41a
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,
getValues,
wrapOptions,
wrapCondense,
wrapFormats,
wrapProvenance,
)
from .servelib import getAbout, getFormData, zipData
TIMEOUT = 180
def serveTable(setup, kind, getx=None, asDict=False):
form = getFormData(setup.config)
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()
optionSpecs = setup.config.OPTIONS
options = getValues(optionSpecs, form)
method = dict if asDict else jsonify
kernelApi = setup.TF.connect()
messages = ''
table = None
if task:
(
table,
messages,
) = kernelApi.table(
kind,
task,
form['features'],
opened=openedSet,
fmt=textFormat,
withNodes=form['withNodes'],
getx=int(getx) if getx else None,
**options,
)
if messages:
messages = wrapMessages(messages)
return method(
table=table,
messages=messages,
)
def serveQuery(setup, getx, asDict=False):
kind = 'query'
form = getFormData(setup.config)
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()
optionSpecs = setup.config.OPTIONS
options = getValues(optionSpecs, form)
pages = ''
features = ''
kernelApi = setup.TF.connect()
method = dict if asDict else jsonify
if task:
messages = ''
table = None
if task in setup.wildQueries:
messages = (
f'Aborted because query is known to take longer than {TIMEOUT} second'
+ ('' if TIMEOUT == 1 else 's')
)
else:
try:
(
table,
messages,
features,
start,
total,
) = kernelApi.search(
task,
form['batch'],
position=form['position'],
opened=openedSet,
condensed=form['condensed'],
condenseType=condenseType,
fmt=textFormat,
withNodes=form['withNodes'],
linked=form['linked'],
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)
setup.wildQueries.add(task)
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,
messages=messages,
features=features,
)
def servePassage(setup, getx):
form = getFormData(setup.config)
textFormat = form['textformat'] or None
optionSpecs = setup.config.OPTIONS
options = getValues(optionSpecs, form)
passages = ''
kernelApi = setup.TF.connect()
openedKey = 'passageOpened'
openedSet = {int(n) for n in form[openedKey].split(',')} if form[openedKey] else set()
sec0 = form['sec0']
sec1 = form['sec1']
sec2 = form['sec2']
(
table,
passages,
) = kernelApi.passage(
sec0,
sec1,
form['features'],
form['query'],
sec2=sec2,
opened=openedSet,
fmt=textFormat,
withNodes=form['withNodes'],
getx=getx,
**options,
)
passages = passageLinks(passages, sec0, sec1)
return jsonify(
table=table,
passages=passages,
)
def serveExport(setup):
sectionsData = serveTable(setup, 'sections', None, asDict=True)
tuplesData = serveTable(setup, 'tuples', None, asDict=True)
queryData = serveQuery(setup, None, asDict=True)
form = getFormData(setup.config)
kernelApi = setup.TF.connect()
(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',
dataSource=setup.dataSource,
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(setup):
form = getFormData(setup.config)
kernelApi = setup.TF.connect()
task = form['query']
condenseType = form['condenseTp'] or None
textFormat = form['textformat'] or None
csvs = None
resultsX = None
messages = ''
if task in setup.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)
setup.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(setup, anything):
form = getFormData(setup.config)
condensedAtt = ' checked ' if form['condensed'] else ''
withNodesAtt = ' checked ' if form['withNodes'] else ''
optionSpecs = setup.config.OPTIONS
options = getValues(optionSpecs, form)
pages = ''
passages = ''
kernelApi = setup.TF.connect()
(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)
(
defaultCondenseType,
exampleSection,
exampleSectionText,
condenseTypes,
defaultTextFormat,
textFormats,
) = kernelApi.condenseTypes()
condenseType = form['condenseTp'] or defaultCondenseType
condenseOpts = wrapCondense(condenseTypes, condenseType)
textFormat = form['textformat'] or defaultTextFormat
textFormatOpts = wrapFormats(textFormats, textFormat)
return render_template(
'index.html',
dataSource=setup.dataSource,
css=css,
header=f'{appLogo}{header}{tfLogo}',
setNames=setNameHtml,
options=wrapOptions(optionSpecs, options),
condensedAtt=condensedAtt,
condenseOpts=condenseOpts,
defaultCondenseType=defaultCondenseType,
textFormatOpts=textFormatOpts,
defaultTextFormat=defaultTextFormat,
exampleSection=exampleSection,
exampleSectionText=exampleSectionText,
withNodesAtt=withNodesAtt,
pages=pages,
passages=passages,
**form,
)