Commit f3e996a5 authored by Dave Kliczbor's avatar Dave Kliczbor
Browse files

Added feature: Choose between LaTeX and Wiki/reStructuredText Syntax

parent 39d5d838
......@@ -2,12 +2,16 @@
# -*- encoding: utf8 -*-
from flask import Flask, flash, session, redirect, url_for, escape, request, Response, Markup
import sys, os, os.path, glob
import sys
import os
import os.path
import glob
from genshi.template import TemplateLoader
from genshi.template.text import NewTextTemplate
from flaskext.genshi import Genshi, render_response
from werkzeug.utils import secure_filename
from collections import defaultdict
from docutils.core import publish_parts
import warnings
import shutil
import subprocess
......@@ -24,6 +28,7 @@ app.secret_key = config.app_secret
genshi = Genshi(app)
genshi.extensions['html'] = 'html5'
def check_output(*popenargs, **kwargs):
# Copied from py2.7s subprocess module
r"""Run command with arguments and return its output as a byte string.
......@@ -58,205 +63,238 @@ def check_output(*popenargs, **kwargs):
#raise Exception(output)
return output
def allowed_file(filename):
return '.' in filename and filename.rsplit('.', 1)[1] in config.allowed_extensions
return '.' in filename and filename.rsplit('.', 1)[1] in config.allowed_extensions
@app.route('/')
def index(**kwargs):
data = defaultdict(str)
data.update(**kwargs)
filelist = glob.glob(config.datadir + '/*.schild')
data['files'] = [ unicode(os.path.basename(f)) for f in sorted(filelist) ]
return render_response('index.html', data)
data = defaultdict(str)
data.update(**kwargs)
filelist = glob.glob(config.datadir + '/*.schild')
data['files'] = [unicode(os.path.basename(f)) for f in sorted(filelist)]
return render_response('index.html', data)
@app.route('/edit')
def edit(**kwargs):
data = defaultdict(str)
data.update(**kwargs)
imagelist = glob.glob(config.imagedir + '/*.png')
data['images'] = [ os.path.basename(f) for f in imagelist ]
templatelist = glob.glob(config.textemplatedir + '/*.tex')
data['templates'] = [ unicode(os.path.basename(f)) for f in sorted(templatelist) ]
return render_response('edit.html', data)
data = defaultdict(str)
data.update(**kwargs)
imagelist = glob.glob(config.imagedir + '/*.png')
data['images'] = [os.path.basename(f) for f in imagelist]
templatelist = glob.glob(config.textemplatedir + '/*.tex')
data['templates'] = [unicode(os.path.basename(f))
for f in sorted(templatelist)]
return render_response('edit.html', data)
@app.route('/edit/<filename>')
def edit_one(filename):
with open(os.path.join(config.datadir, filename), 'r') as infile:
formdata = json.load(infile)
return edit(form=formdata)
with open(os.path.join(config.datadir, filename), 'r') as infile:
formdata = defaultdict(str, json.load(infile))
if len(formdata['markup']) < 1:
formdata['markup'] = 'latex'
return edit(form=formdata)
def run_pdflatex(context, outputfilename, overwrite=True):
if not context.has_key('textemplate'):
context['textemplate'] = "text-image-quer.tex"
genshitex = TemplateLoader([config.textemplatedir])
template = genshitex.load(context['textemplate'], cls=NewTextTemplate, encoding='utf8')
if not overwrite and os.path.isfile(outputfilename) and os.path.getmtime(template.filepath) < os.path.getmtime(outputfilename):
return
tmpdir = tempfile.mkdtemp(dir=config.tmpdir)
if context.has_key('img') and context['img'] and context['img'] != '__none':
if not context.has_key('textemplate'):
context['textemplate'] = "text-image-quer.tex"
genshitex = TemplateLoader([config.textemplatedir])
template = genshitex.load(
context['textemplate'], cls=NewTextTemplate, encoding='utf8')
if not overwrite and os.path.isfile(outputfilename) and os.path.getmtime(template.filepath) < os.path.getmtime(outputfilename):
return
print(str(context))
if context['markup'] == 'rst':
context['text'] = publish_parts(context['text'], writer_name='latex')['body']
context['headline'] = publish_parts(context['headline'], writer_name='latex')['body']
tmpdir = tempfile.mkdtemp(dir=config.tmpdir)
if context.has_key('img') and context['img'] and context['img'] != '__none':
try:
shutil.copy(os.path.join(config.imagedir, context[
'img']), os.path.join(tmpdir, context['img']))
except:
raise IOError("COULD NOT COPY")
else:
# print "MEH No image"
pass
tmptexfile = os.path.join(tmpdir, 'output.tex')
tmppdffile = os.path.join(tmpdir, 'output.pdf')
with open(tmptexfile, 'w') as texfile:
texfile.write(template.generate(form=context).render(encoding='utf8'))
cwd = os.getcwd()
os.chdir(tmpdir)
os.symlink(config.texsupportdir, os.path.join(tmpdir, 'support'))
try:
shutil.copy(os.path.join(config.imagedir, context['img']), os.path.join(tmpdir, context['img']))
except:
raise IOError("COULD NOT COPY")
else:
#print "MEH No image"
pass
tmptexfile = os.path.join(tmpdir, 'output.tex')
tmppdffile = os.path.join(tmpdir, 'output.pdf')
with open(tmptexfile, 'w') as texfile:
texfile.write(template.generate(form = context).render(encoding='utf8'))
cwd = os.getcwd()
os.chdir(tmpdir)
os.symlink(config.texsupportdir, os.path.join(tmpdir, 'support'))
try:
texlog = check_output(['pdflatex', '--halt-on-error', tmptexfile], stderr=STDOUT)
except CalledProcessError as e:
texlog = check_output(
['pdflatex', '--halt-on-error', tmptexfile], stderr=STDOUT)
except CalledProcessError as e:
if overwrite:
flash(Markup("<p>PDFLaTeX Output:</p><pre>%s</pre>" % e.output), 'log')
raise SyntaxWarning("PDFLaTeX bailed out")
finally:
os.chdir(cwd)
if overwrite:
flash(Markup("<p>PDFLaTeX Output:</p><pre>%s</pre>" % e.output), 'log')
raise SyntaxWarning("PDFLaTeX bailed out")
finally:
os.chdir(cwd)
if overwrite:
flash(Markup("<p>PDFLaTeX Output:</p><pre>%s</pre>" % texlog), 'log')
shutil.copy(tmppdffile, outputfilename)
shutil.rmtree(tmpdir)
flash(Markup("<p>PDFLaTeX Output:</p><pre>%s</pre>" % texlog), 'log')
shutil.copy(tmppdffile, outputfilename)
shutil.rmtree(tmpdir)
def save_and_convert_image_upload(inputname):
file = request.files[inputname]
if file:
if not allowed_file(file.filename):
raise UserWarning("Uploaded image is not in the list of allowed file types.")
filename = os.path.join(config.uploaddir, secure_filename(file.filename))
file.save(filename)
img = PythonMagick.Image(filename)
imgname = os.path.splitext(secure_filename(file.filename))[0].replace('.', '_') + '.png'
savedfilename = os.path.join(config.imagedir, imgname)
img.write(savedfilename)
os.remove(filename)
return imgname
return None
file = request.files[inputname]
if file:
if not allowed_file(file.filename):
raise UserWarning(
"Uploaded image is not in the list of allowed file types.")
filename = os.path.join(
config.uploaddir, secure_filename(file.filename))
file.save(filename)
img = PythonMagick.Image(filename)
imgname = os.path.splitext(secure_filename(file.filename))[
0].replace('.', '_') + '.png'
savedfilename = os.path.join(config.imagedir, imgname)
img.write(savedfilename)
os.remove(filename)
return imgname
return None
@app.route('/create', methods=['POST'])
def create():
if request.method == 'POST':
formdata = request.form.to_dict(flat=True)
for a in ('headline', 'text'):
formdata[a] = unicode(formdata[a])
try:
imgpath = save_and_convert_image_upload('imgupload')
if imgpath is not None:
formdata['img'] = imgpath
outfilename = secure_filename(formdata['headline'][:16])+str(hash(formdata['headline']+formdata['text']+os.path.splitext(formdata['textemplate'])[0]+os.path.splitext(formdata['img'])[0]))+'.schild'
outpdfname = outfilename + '.pdf'
formdata['pdfname'] = outpdfname
run_pdflatex(formdata, os.path.join(config.pdfdir, outpdfname))
with open(os.path.join(config.datadir, outfilename), 'w') as outfile:
json.dump(formdata, outfile)
flash(Markup(u"""PDF created and data saved. You might create another one. Here's a preview. Click to print.<br/>
if request.method == 'POST':
formdata = defaultdict(str, request.form.to_dict(flat=True))
for a in ('headline', 'text'):
formdata[a] = unicode(formdata[a])
try:
imgpath = save_and_convert_image_upload('imgupload')
if imgpath is not None:
formdata['img'] = imgpath
outfilename = secure_filename(formdata['headline'][:16]) + str(hash(formdata['headline'] + formdata[
'text'] + os.path.splitext(formdata['textemplate'])[0] + os.path.splitext(formdata['img'])[0])) + '.schild'
outpdfname = outfilename + '.pdf'
formdata['pdfname'] = outpdfname
with open(os.path.join(config.datadir, outfilename), 'w') as outfile:
json.dump(formdata, outfile)
run_pdflatex(formdata, os.path.join(config.pdfdir, outpdfname))
flash(Markup(u"""PDF created and data saved. You might create another one. Here's a preview. Click to print.<br/>
<a href="%s"><img src="%s"/></a>""" %
(url_for('schild', filename=outfilename), url_for('pdfthumbnail', pdfname=outpdfname, maxgeometry=200))
))
except Exception as e:
flash(u"Could not create pdf or save data: %s" % str(e), 'error')
(url_for('schild', filename=outfilename), url_for(
'pdfthumbnail', pdfname=outpdfname, maxgeometry=200))
))
except Exception as e:
flash(u"Could not create pdf or save data: %s" % str(e), 'error')
data = {'form': formdata}
imagelist = glob.glob(config.imagedir + '/*.png')
data['images'] = [os.path.basename(f) for f in imagelist]
templatelist = glob.glob(config.textemplatedir + '/*.tex')
data['templates'] = [os.path.basename(f) for f in sorted(templatelist)]
return redirect(url_for('edit_one', filename=outfilename))
flash("No POST data. You've been redirected to the edit page.", 'warning')
return redirect(url_for('edit'))
data = {'form': formdata }
imagelist = glob.glob(config.imagedir + '/*.png')
data['images'] = [ os.path.basename(f) for f in imagelist ]
templatelist = glob.glob(config.textemplatedir + '/*.tex')
data['templates'] = [ os.path.basename(f) for f in sorted(templatelist) ]
return render_response('edit.html', data)
flash("No POST data. You've been redirected to the edit page.", 'warning')
return redirect(url_for('edit'))
@app.route('/schild/<filename>')
def schild(filename):
return render_response('schild.html', {'filename':filename, 'printer':[ unicode(f) for f in sorted(config.printers.keys()) ]})
return render_response('schild.html', {'filename': filename, 'printer': [unicode(f) for f in sorted(config.printers.keys())]})
@app.route('/printout', methods=['POST'])
def printout():
filename = os.path.join(config.pdfdir, secure_filename(request.form['filename']))
printer = config.printers[request.form['printer']]
copies = int(request.form['copies']) or 0
if copies > 0 and copies <= 6:
try:
lprout = check_output(['lpr', '-H', str(config.printserver), '-P', str(printer), '-#', str(copies)] + config.lproptions + [filename], stderr=STDOUT)
flash(u'Schild wurde zum Drucker geschickt!')
except CalledProcessError as e:
flash(Markup("<p>Could not print:</p><pre>%s</pre>" % e.output), 'error')
else:
flash(u'Ungültige Anzahl Kopien!')
return redirect(url_for('index'))
filename = os.path.join(
config.pdfdir, secure_filename(request.form['filename']))
printer = config.printers[request.form['printer']]
copies = int(request.form['copies']) or 0
if copies > 0 and copies <= 6:
try:
lprout = check_output(['lpr', '-H', str(config.printserver), '-P', str(
printer), '-#', str(copies)] + config.lproptions + [filename], stderr=STDOUT)
flash(u'Schild wurde zum Drucker geschickt!')
except CalledProcessError as e:
flash(Markup("<p>Could not print:</p><pre>%s</pre>" % e.output), 'error')
else:
flash(u'Ungültige Anzahl Kopien!')
return redirect(url_for('index'))
@app.route('/delete', methods=['POST'])
def delete():
filename = secure_filename(request.form['filename'])
try:
os.unlink(os.path.join(config.datadir, filename))
for f in glob.glob(os.path.join(config.pdfdir, filename + '.pdf*')):
os.unlink(f)
flash(u"Schild %s wurde gelöscht" % filename)
return redirect(url_for('index'))
except:
flash(u"Schild %s konnte nicht gelöscht werden." % filename, 'error')
return redirect(url_for('schild', filename=filename))
filename = secure_filename(request.form['filename'])
try:
os.unlink(os.path.join(config.datadir, filename))
for f in glob.glob(os.path.join(config.pdfdir, filename + '.pdf*')):
os.unlink(f)
flash(u"Schild %s wurde gelöscht" % filename)
return redirect(url_for('index'))
except:
flash(u"Schild %s konnte nicht gelöscht werden." % filename, 'error')
return redirect(url_for('schild', filename=filename))
@app.route('/image/<imgname>')
def image(imgname):
imgpath = os.path.join(config.imagedir, secure_filename(imgname))
#print(imgpath)
if os.path.exists(imgpath):
with open(imgpath, 'r') as imgfile:
return Response(imgfile.read(), mimetype="image/png")
else:
return "Meh" #redirect(url_for('index'))
imgpath = os.path.join(config.imagedir, secure_filename(imgname))
# print(imgpath)
if os.path.exists(imgpath):
with open(imgpath, 'r') as imgfile:
return Response(imgfile.read(), mimetype="image/png")
else:
return "Meh" # redirect(url_for('index'))
def make_thumb(filename, maxgeometry):
thumbpath = filename + '.' + str(maxgeometry)
if not os.path.exists(thumbpath) or os.path.getmtime(filename) > os.path.getmtime(thumbpath):
img = PythonMagick.Image(str(filename))
img.transform("%sx%s" % (maxgeometry,maxgeometry))
img.quality(90)
img.write(str("png:%s" % thumbpath))
return thumbpath
thumbpath = filename + '.' + str(maxgeometry)
if not os.path.exists(thumbpath) or os.path.getmtime(filename) > os.path.getmtime(thumbpath):
img = PythonMagick.Image(str(filename))
img.transform("%sx%s" % (maxgeometry, maxgeometry))
img.quality(90)
img.write(str("png:%s" % thumbpath))
return thumbpath
@app.route('/thumbnail/<imgname>/<int:maxgeometry>')
def thumbnail(imgname, maxgeometry):
imgpath = os.path.join(config.imagedir, secure_filename(imgname))
thumbpath = make_thumb(imgpath, maxgeometry)
with open(thumbpath, 'r') as imgfile:
return Response(imgfile.read(), mimetype="image/png")
imgpath = os.path.join(config.imagedir, secure_filename(imgname))
thumbpath = make_thumb(imgpath, maxgeometry)
with open(thumbpath, 'r') as imgfile:
return Response(imgfile.read(), mimetype="image/png")
@app.route('/pdfthumb/<pdfname>/<int:maxgeometry>')
def pdfthumbnail(pdfname, maxgeometry):
pdfpath = os.path.join(config.pdfdir, secure_filename(pdfname))
thumbpath = make_thumb(pdfpath, maxgeometry)
with open(thumbpath, 'r') as imgfile:
return Response(imgfile.read(), mimetype="image/png")
pdfpath = os.path.join(config.pdfdir, secure_filename(pdfname))
thumbpath = make_thumb(pdfpath, maxgeometry)
with open(thumbpath, 'r') as imgfile:
return Response(imgfile.read(), mimetype="image/png")
@app.route('/tplthumb/<tplname>/<int:maxgeometry>')
def tplthumbnail(tplname, maxgeometry):
pdfpath = os.path.join(config.cachedir, secure_filename(tplname)+'.pdf')
try:
run_pdflatex(
{ 'textemplate' : secure_filename(tplname),
'img' : 'pictograms-nps-misc-camera.png',
'headline' : u'Überschrift',
'text' : u'Dies ist der Text, der in der UI als Text bezeichnet ist.',
}, pdfpath, overwrite=False
)
except Exception as e:
return str(e)
else:
thumbpath = make_thumb(pdfpath, maxgeometry)
with open(thumbpath, 'r') as imgfile:
return Response(imgfile.read(), mimetype="image/png")
pdfpath = os.path.join(config.cachedir, secure_filename(tplname) + '.pdf')
try:
run_pdflatex(
{'textemplate': secure_filename(tplname),
'img': 'pictograms-nps-misc-camera.png',
'headline': u'Überschrift',
'text': u'Dies ist der Text, der in der UI als Text bezeichnet ist.',
}, pdfpath, overwrite=False
)
except Exception as e:
return str(e)
else:
thumbpath = make_thumb(pdfpath, maxgeometry)
with open(thumbpath, 'r') as imgfile:
return Response(imgfile.read(), mimetype="image/png")
@app.route('/pdfdownload/<pdfname>')
def pdfdownload(pdfname):
pdfpath = os.path.join(config.pdfdir, secure_filename(pdfname))
with open(pdfpath, 'r') as pdffile:
return Response(pdffile.read(), mimetype="application/pdf")
pdfpath = os.path.join(config.pdfdir, secure_filename(pdfname))
with open(pdfpath, 'r') as pdffile:
return Response(pdffile.read(), mimetype="application/pdf")
if __name__ == '__main__':
app.debug = True
app.run(host=config.listen, port=config.port)
app.debug = True
app.run(host=config.listen, port=config.port)
......@@ -23,6 +23,9 @@ body > a {
img.bigpreview {
width: 100%;
}
.box {
width: 95%;
}
}
body > *, form > * {
display: block;
......@@ -133,3 +136,10 @@ textarea {
margin: 0.3em 0;
background: #eee linear-gradient(to bottom, #fff 0%,#eee 0.5em,#eee 92%,#e6e6e6 100%);
}
label {
line-height: 1.8em;
}
.box label+select {
height: initial;
float: right;
}
\ No newline at end of file
......@@ -44,6 +44,18 @@
</div>
<div class="box">
<label for="form:text">Text</label>
<select name="markup">
<py:choose>
<py:when test="not defined('form') or form.markup == 'rst' or form.markup == ''">
<option value="latex">LaTeX</option>
<option value="rst" selected="True">Wiki (reStructuredText)</option>
</py:when>
<py:when test="defined('form') and form.markup == 'latex'">
<option value="latex" selected="True">LaTeX</option>
<option value="rst">Wiki (reStructuredText)</option>
</py:when>
</py:choose>
</select>
<textarea name="text" id="form:text" cols="35" rows="5"><py:if test="defined('form')">${form.text}</py:if></textarea>
</div><br/>
<div class="box">
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment