diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..d2241cf6f9a8874b0e828016b4eab8f4969ee964 --- /dev/null +++ b/.gitignore @@ -0,0 +1,39 @@ +*.py[co] + +# Packages +*.egg +*.egg-info +dist +build +eggs +parts +bin +var +sdist +develop-eggs +.installed.cfg + +# Installer logs +pip-log.txt + +# Unit test / coverage reports +.coverage +.tox + +#Translations +*.mo + +#Mr Developer +.mr.developer.cfg + +# backup files +*~ + +# data files +savegames + +config.py +schilder.wsgi + +*.png.* +*.schild.* diff --git a/config.py.example b/config.py.example index 9b6764099f1e6df91551f3546ebda29668206db2..11696bdf8850916d49b42894842c0ead55fffffd 100755 --- a/config.py.example +++ b/config.py.example @@ -33,6 +33,9 @@ pdfdir = datadir + '/pdf' # Image data directory (needs to be writeable) imagedir = datadir + '/images' +# Cache dir (needs to be writable) +cachedir = datadir + '/cache' + # Upload temp directory (needs to be writeable) uploaddir = datadir + '/upload' diff --git a/data/cache/.gitignore b/data/cache/.gitignore new file mode 100755 index 0000000000000000000000000000000000000000..7dc49cf8232069216f9a1b31868ada2498ab46c8 --- /dev/null +++ b/data/cache/.gitignore @@ -0,0 +1 @@ +*.pdf* \ No newline at end of file diff --git a/schilder.py b/schilder.py index 0b587008b1e022d16ceb862f73ae37321b20f6f6..0af3387548d241d459be502e615b94342c3e1f10 100755 --- a/schilder.py +++ b/schilder.py @@ -85,11 +85,13 @@ def edit_one(filename): formdata = json.load(infile) return edit(form=formdata) -def run_pdflatex(context, outputfilename): +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': try: @@ -109,11 +111,13 @@ def run_pdflatex(context, outputfilename): try: texlog = check_output(['pdflatex', '--halt-on-error', tmptexfile], stderr=STDOUT) except CalledProcessError as e: - flash(Markup("<p>PDFLaTeX Output:</p><pre>%s</pre>" % e.output), 'log') + if overwrite: + flash(Markup("<p>PDFLaTeX Output:</p><pre>%s</pre>" % e.output), 'log') raise SyntaxWarning("PDFLaTeX bailed out") finally: os.chdir(cwd) - flash(Markup("<p>PDFLaTeX Output:</p><pre>%s</pre>" % texlog), 'log') + if overwrite: + flash(Markup("<p>PDFLaTeX Output:</p><pre>%s</pre>" % texlog), 'log') shutil.copy(tmppdffile, outputfilename) shutil.rmtree(tmpdir) @@ -229,6 +233,24 @@ def pdfthumbnail(pdfname, 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") + @app.route('/pdfdownload/<pdfname>') def pdfdownload(pdfname): pdfpath = os.path.join(config.pdfdir, secure_filename(pdfname)) diff --git a/static/main.css b/static/main.css index 0c7907b5f3e6b621177790ae3ebff0148545a0ca..0f163cfa7f1e7779291913ecff91803c2118fea0 100644 --- a/static/main.css +++ b/static/main.css @@ -82,6 +82,9 @@ form { margin-top:1em; margin-bottom:1em; } +form ul { + padding: 0; +} form li { list-style-type:none; display: inline-block; @@ -89,17 +92,17 @@ form li { input[type="radio"] { position:relative; z-index:5; - margin-bottom:1em; + margin-bottom:0; } input[type="radio"]+label > img { position:relative; z-index:4; - top:0.5em; - left:-1.5em; + top:0; + left:-1.4em; margin-right:-1.2em; max-width: 100%; max-height: 10em; - border:3px solid #eee; + border:3px solid lightgray; border-radius: 5px; } input[type="radio"]:checked+label > img { @@ -114,3 +117,14 @@ input[type="radio"]:checked + input[type="file"] { input[type="radio"]:checked + input[type="file"] + label { display:none; } +textarea { + display: block; +} +.box { + display: inline-block; + background: #eee; + border: 1px solid lightgray; + border-radius: 5px; + padding: 0.5em; + margin: 1em 0; +} diff --git a/templates/edit.html b/templates/edit.html index f0ad350dce9b9b181763477c67d4932608283a51..f3a3dc7d93cef29e5d0a9427d442d5543d3c00a4 100644 --- a/templates/edit.html +++ b/templates/edit.html @@ -2,84 +2,97 @@ <!-- <html xmlns="http://www.w3.org/1999/xhtml" > --> <html xmlns:py="http://genshi.edgewall.org/"> <head> - <link rel='stylesheet' type='text/css' href="${ url_for('static', filename='main.css') }"/> - <meta name="viewport" content="width=device-width, initial-scale=1"/> - <title>Schildergenerator</title> + <link rel='stylesheet' type='text/css' href="${ url_for('static', filename='main.css') }"/> + <meta name="viewport" content="width=device-width, initial-scale=1"/> + <title>Schildergenerator</title> </head> <body> - <py:with vars="messages = get_flashed_messages(with_categories=True)"> - <ul class="flashes" py:if="messages"> - <li class="${ category }" py:for="category,message in messages" tabindex="0">${ message }</li> - </ul> - </py:with> - <a href="${ url_for('index') }">Liste der fertigen Schilder</a> - - <form method="post" action="${ url_for('create') }" enctype="multipart/form-data"> - <label for="form:headline">Großer Text</label> - <textarea name="headline" id="form:headline" cols="35" rows="5"><py:if test="defined('form')">${form.headline}</py:if></textarea> - <label for="form:text">Zusatztext</label> - <textarea name="text" id="form:text" cols="35" rows="5"><py:if test="defined('form')">${form.text}</py:if></textarea> - <label for="form:template">TeX-Vorlage</label> - <select name="textemplate" id="form:template"> - <py:choose> - <py:when test="defined('form')"> - <py:for each="template in templates"> - <py:choose> - <py:when test="template == form.textemplate"> - <option label="${template}" value="${template}" selected="selected">${template}</option> - - </py:when> - <py:otherwise> - <option label="${template}" value="${template}">${template}</option> - - </py:otherwise> - </py:choose> - </py:for> - </py:when> - <py:otherwise> - <option py:for="tpl in templates" label="${tpl}" value="${tpl}">${tpl}</option> - </py:otherwise> - </py:choose> - </select> - <ul> - <li> - <py:choose> - <py:when test="defined('form')"> - <input type="radio" name="img" id="img--none" value="__none" checked="${form.img == '__none'}"/> - </py:when> - <py:otherwise> - <input type="radio" name="img" id="img--none" value="__none" checked="checked" /> - </py:otherwise> - </py:choose> - <label for="img--none">Kein Bild</label> - </li> - <li> - <input type="radio" name="img" id="img--upload" value="__upload"/> - <input type="file" name="imgupload"/> - <label for="img--upload">Bild hochladen</label> - </li> - </ul> - <ul> - <li py:for="img in images"> - <py:choose> - <py:when test="defined('form')"> - <py:choose> - <py:when test="img == form.img"> - <input type="radio" name="img" id="img:${img}" value="${img}" checked="True"/> - </py:when> - <py:otherwise> - <input type="radio" name="img" id="img:${img}" value="${img}"/> - </py:otherwise> - </py:choose> - </py:when> - <py:otherwise> - <input type="radio" name="img" id="img:${img}" value="${img}"/> - </py:otherwise> - </py:choose> - <label for="img:${img}"><img src="${ url_for('thumbnail', imgname=img, maxgeometry=100) }" alt="${img}"/></label> - </li> - </ul> - <input type="submit" value="Schild erstellen"/> - </form> + <py:with vars="messages = get_flashed_messages(with_categories=True)"> + <ul class="flashes" py:if="messages"> + <li class="${ category }" py:for="category,message in messages" tabindex="0">${ message }</li> + </ul> + </py:with> + <a href="${ url_for('index') }">Liste der fertigen Schilder</a> + + <form method="post" action="${ url_for('create') }" enctype="multipart/form-data"> + <div class="box"> + <label for="form:template">Wähle eine TeX-Vorlage:</label> + <ul> + <li py:for="textemplate in templates"> + <py:choose> + <py:when test="defined('form')"> + <py:choose> + <py:when test="textemplate == form.textemplate"> + <input type="radio" name="textemplate" id="tpl:${textemplate}" value="${textemplate}" checked="True"/> + </py:when> + <py:otherwise> + <input type="radio" name="textemplate" id="tpl:${textemplate}" value="${textemplate}"/> + </py:otherwise> + </py:choose> + </py:when> + <py:otherwise> + <input type="radio" name="textemplate" id="tpl:${textemplate}" value="${textemplate}"/> + </py:otherwise> + </py:choose> + <label for="tpl:${textemplate}"><img src="${ url_for('tplthumbnail', tplname=textemplate, maxgeometry=72) }" alt="${textemplate}" title="${textemplate}"/></label> + </li> + </ul> + </div><br/> + <div class="box"> + <label for="form:headline">Überschrift</label> + <textarea name="headline" id="form:headline" cols="35" rows="5"><py:if test="defined('form')">${form.headline}</py:if></textarea> + </div> + <div class="box"> + <label for="form:text">Text</label> + <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"> + <input type="submit" value="Schild erstellen"/> + </div><br/> + <div class="box"> + <label for="form:img">Wähle ein Bild (falls auf Vorlage anwendbar):</label> + <ul> + <li> + <py:choose> + <py:when test="defined('form')"> + <input type="radio" name="img" id="img--none" value="__none" checked="${form.img == '__none'}"/> + </py:when> + <py:otherwise> + <input type="radio" name="img" id="img--none" value="__none" checked="checked" /> + </py:otherwise> + </py:choose> + <label for="img--none">Kein Bild</label> + </li> + <li> + <input type="radio" name="img" id="img--upload" value="__upload"/> + <input type="file" name="imgupload"/> + <label for="img--upload">Bild hochladen</label> + </li> + </ul> + <ul> + <li py:for="img in images"> + <py:choose> + <py:when test="defined('form')"> + <py:choose> + <py:when test="img == form.img"> + <input type="radio" name="img" id="img:${img}" value="${img}" checked="True"/> + </py:when> + <py:otherwise> + <input type="radio" name="img" id="img:${img}" value="${img}"/> + </py:otherwise> + </py:choose> + </py:when> + <py:otherwise> + <input type="radio" name="img" id="img:${img}" value="${img}"/> + </py:otherwise> + </py:choose> + <label for="img:${img}"><img src="${ url_for('thumbnail', imgname=img, maxgeometry=100) }" alt="${img}" title="${img}"/></label> + </li> + </ul> + </div> + <div class="box"> + <input type="submit" value="Schild erstellen"/> + </div> + </form> </body> </html>