mirror of
https://github.com/pklaus/brother_ql_web.git
synced 2024-05-25 11:56:53 +03:00
Adding a Web GUI
This commit is contained in:
parent
91ffde97ef
commit
894dc456ad
|
@ -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>')
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
brother_ql
|
brother_ql
|
||||||
bottle
|
bottle
|
||||||
markdown
|
markdown
|
||||||
|
jinja2
|
||||||
|
|
6
static/css/bootstrap.min.css
vendored
Normal file
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
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
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
26
views/base.jinja2
Normal 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>
|
||||||
|
|
82
views/labeldesigner.jinja2
Normal file
82
views/labeldesigner.jinja2
Normal 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 %}
|
Loading…
Reference in New Issue
Block a user