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 = set(form[openedKey].split(',')) if form[openedKey] else set() sec0 = form['sec0'] sec1 = form['sec1'] sec2 = form['sec2'] ( table, sec0Type, passages, browseNavLevel, ) = kernelApi.passage( form['features'], form['query'], sec0, sec1=sec1, sec2=sec2, opened=openedSet, fmt=textFormat, withNodes=form['withNodes'], getx=getx, **options, ) passages = pickle.loads(passages) passages = passageLinks(passages, sec0Type, sec0, sec1, browseNavLevel) 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'''

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

Sets: {setNamesRep}

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