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'

Sets: {setNamesRep}

' 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'

Sets: {setNamesRep}

' 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, )