Adding a Web GUI

This commit is contained in:
Philipp Klaus 2016-11-25 21:21:42 +01:00
parent 91ffde97ef
commit 894dc456ad
7 changed files with 146 additions and 11 deletions

View File

@ -7,7 +7,7 @@ This is a web service to print labels on Brother QL label printers.
import sys, logging, socket, os, functools, textwrap import sys, logging, socket, os, functools, textwrap
from io import BytesIO from io import BytesIO
from bottle import run, route, response, request from bottle import run, route, response, request, jinja2_view as view, static_file, redirect
from PIL import Image, ImageDraw, ImageFont from PIL import Image, ImageDraw, ImageFont
import numpy as np import numpy as np
import markdown import markdown
@ -34,11 +34,17 @@ DEFAULT_FONTS = [
@route('/') @route('/')
def index(): def index():
INDEX_MD = __doc__ + textwrap.dedent(""" redirect('/labeldesigner')
Go to [/api/print/text/Your_Text](/api/print/text/)
to print a label (replace `Your_Text` with your text). @route('/static/<filename:path>')
""") def serve_static(filename):
return markdown.markdown(INDEX_MD) return static_file(filename, root='./static')
@route('/labeldesigner')
@view('labeldesigner.jinja2')
def labeldesigner():
fonts = sorted(list(FONTS.keys()))
return {'title': 'Labeldesigner', 'message': '', 'fonts': fonts}
def get_label_context(request): def get_label_context(request):
""" might raise LookupError() """ """ might raise LookupError() """
@ -83,15 +89,17 @@ def get_label_context(request):
return context return context
def create_label_im(text, **kwargs): def create_label_im(text, **kwargs):
im = Image.new('L', (kwargs['width'], kwargs['height']), 'white')
draw = ImageDraw.Draw(im)
im_font = ImageFont.truetype(kwargs['font_path'], kwargs['font_size']) im_font = ImageFont.truetype(kwargs['font_path'], kwargs['font_size'])
textsize = draw.textsize(text, font=im_font) textsize = im_font.getsize(text)
vertical_offset = (kwargs['height'] - textsize[1])//2 height = max(textsize[1] * (text.count('\n')+1), kwargs['height'])
im = Image.new('L', (kwargs['width'], height), 'white')
draw = ImageDraw.Draw(im)
textsize = draw.multiline_textsize(text, font=im_font)
vertical_offset = 0 #(height - textsize[1])//2
horizontal_offset = max((kwargs['width'] - textsize[0])//2, 0) horizontal_offset = max((kwargs['width'] - textsize[0])//2, 0)
if 'ttf' in kwargs['font_path']: vertical_offset -= 10 if 'ttf' in kwargs['font_path']: vertical_offset -= 10
offset = horizontal_offset, vertical_offset offset = horizontal_offset, vertical_offset
draw.text(offset, text, (0), font=im_font) draw.multiline_text(offset, text, (0), font=im_font, align="center")
return im return im
@route('/api/preview/text/<text>') @route('/api/preview/text/<text>')

View File

@ -1,3 +1,4 @@
brother_ql brother_ql
bottle bottle
markdown markdown
jinja2

6
static/css/bootstrap.min.css vendored Normal file

File diff suppressed because one or more lines are too long

7
static/js/bootstrap.min.js vendored Normal file

File diff suppressed because one or more lines are too long

5
static/js/jquery.min.js vendored Normal file

File diff suppressed because one or more lines are too long

26
views/base.jinja2 Normal file
View File

@ -0,0 +1,26 @@
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Required meta tags always come first -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="/static/css/bootstrap.min.css" integrity="sha384-y3tfxAZXuh4HwSYylfB+J125MxIs6mR5FOHamPBG064zB+AFeWH94NdvaCBm8qnd" crossorigin="anonymous">
<title>{% block page_title %}{% endblock %} | Brother QL</title>
</head>
<body>
<h1>{% block page_headline %}{% endblock %}</h1>
{% block content %}{% endblock %}
<!-- jQuery first, then Bootstrap JS. -->
<script src="/static/js/jquery.min.js"></script>
<script src="/static/js/bootstrap.min.js" integrity="sha384-vZ2WRJMwsjRMW/8U7i6PWi6AlO1L79snBrmgiDpgIWJ82z8eA5lenwvxbMV1PAh7" crossorigin="anonymous"></script>
<script type="text/javascript">
{% block javascript %}{% endblock %}
</script>
</body>
</html>

View File

@ -0,0 +1,82 @@
{% extends "base.jinja2" %}
{% block page_title %}{{ title }}{% endblock %}
{% block content %}
<div class="row">
<div class="col-md-4">
<fieldset class="form-group">
<label for="labelText">Label Text:</label>
<textarea rows="4" id="labelText" class="form-control" onChange="preview()" onInput="preview()"></textarea>
<label for="fontFamily">Font Selection:</label>
<select class="form-control" id="fontFamily" onChange="preview()">
{% for font in fonts %}<option>{{font}}</option> {% endfor %}
</select>
<label for="fontSize">Font Size:</label>
<input id="fontSize" type="text" name="quant[2]" class="form-control input-number" value="70" min="1" max="120" onChange="preview()">
</fieldset>
</div>
<div class="col-md-4">
<fieldset class="form-group">
<label for="previewImg">Label Preview:</label>
<img id="previewImg" src="/api/preview/text/%20" style="border: 1px solid #444; width: 90%; margin: 5%;"/>
<button type="button" class="btn btn-primary btn-block btn-lg" onClick="print()">Print</button>
</fieldset>
</div>
</div>
{% endblock %}
{% block page_headline %}
{{message}}
{% endblock %}
{% block javascript %}
var text = $('#labelText');
//text.oninput = function(){
//var callcount = 0;
// var action = function(){
// alert('changed');
// }
// var delayAction = function(action, time){
// var expectcallcount = callcount;
// var delay = function(){
// if(callcount == expectcallcount){
// action();
// }
// }
// setTimeout(delay, time);
// }
// return function(eventtrigger){
// ++callcount;
// delayAction(action, 1200);
// }
//}();
function last_url_part() {
text = $('#labelText').val().replace(/\n/g, "%0A");
font_family = $('#fontFamily option:selected').text();
font_size = $('#fontSize').val();
if (text == '') text = '%20';
return text + '?font_family=' + font_family + '&font_size=' + font_size;
}
function preview() {
$('#previewImg').attr('src', '/api/preview/text/' + last_url_part() );
}
function print() {
$.ajax({
dataType: "json",
url: '/api/print/text/' + last_url_part(),
success: function( data ) {
console.log(data['success']);
}
});
}
{% endblock %}