addes configuration file config.json - close #8

This commit is contained in:
telegnom 2018-03-05 03:35:31 +01:00 committed by Philipp Klaus
parent 6218a1dfc9
commit 2d07cee36d
5 changed files with 110 additions and 57 deletions

View File

@ -30,16 +30,20 @@ inspect fonts on your machine. This package is pre-installed on many Linux distr
If you're using a Mac, I recommend to use [Homebrew](https://brew.sh) to install If you're using a Mac, I recommend to use [Homebrew](https://brew.sh) to install
fontconfig using [`brew install fontconfig`](http://brewformulas.org/Fontconfig). fontconfig using [`brew install fontconfig`](http://brewformulas.org/Fontconfig).
### Configuration file
Copy `config.example.json` to `config.json` (e.g. `cp config.example.json config.json`) and adjust the values to match your needs.
### Startup ### Startup
To start the server, run `./brother_ql_web.py`. Here's its command line interface: To start the server, run `./brother_ql_web.py`. The command line parameters overwrite the values configured in `config.json`. Here's its command line interface:
usage: brother_ql_web.py [-h] [--port PORT] [--loglevel LOGLEVEL] usage: brother_ql_web.py [-h] [--port PORT] [--loglevel LOGLEVEL]
[--font-folder FONT_FOLDER] [--font-folder FONT_FOLDER]
[--default-label-size DEFAULT_LABEL_SIZE] [--default-label-size DEFAULT_LABEL_SIZE]
[--default-orientation {standard,rotated}] [--default-orientation {standard,rotated}]
[--model {QL-500,QL-550,QL-560,QL-570,QL-580N,QL-650TD,QL-700,QL-710W,QL-720NW,QL-1050,QL-1060N}] [--model {QL-500,QL-550,QL-560,QL-570,QL-580N,QL-650TD,QL-700,QL-710W,QL-720NW,QL-1050,QL-1060N}]
printer [printer]
This is a web service to print labels on Brother QL label printers. This is a web service to print labels on Brother QL label printers.

View File

@ -4,7 +4,7 @@
This is a web service to print labels on Brother QL label printers. This is a web service to print labels on Brother QL label printers.
""" """
import sys, logging, random import sys, logging, random, json, argparse
from io import BytesIO from io import BytesIO
from bottle import run, route, get, post, response, request, jinja2_view as view, static_file, redirect from bottle import run, route, get, post, response, request, jinja2_view as view, static_file, redirect
@ -19,22 +19,16 @@ from font_helpers import get_fonts
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
DEBUG = False
MODEL = None
BACKEND_CLASS = None
BACKEND_STRING_DESCR = None
DEFAULT_ORIENTATION = None
DEFAULT_LABEL_SIZE = None
FONTS = None
DEFAULT_FONT = None
DEFAULT_FONTS = [
{'family': 'Minion Pro', 'style': 'Semibold'},
{'family': 'Linux Libertine', 'style': 'Regular'},
{'family': 'DejaVu Serif', 'style': 'Book'},
]
LABEL_SIZES = [ (name, label_type_specs[name]['name']) for name in label_sizes] LABEL_SIZES = [ (name, label_type_specs[name]['name']) for name in label_sizes]
try:
with open('config.json') as fh:
CONFIG = json.load(fh)
except FileNotFoundError as e:
with open('config.example.json') as fh:
CONFIG = json.load(fh)
@route('/') @route('/')
def index(): def index():
redirect('/labeldesigner') redirect('/labeldesigner')
@ -47,10 +41,11 @@ def serve_static(filename):
@view('labeldesigner.jinja2') @view('labeldesigner.jinja2')
def labeldesigner(): def labeldesigner():
font_family_names = sorted(list(FONTS.keys())) font_family_names = sorted(list(FONTS.keys()))
label_sizes = LABEL_SIZES return {'font_family_names': font_family_names,
title = 'Label Designer' 'fonts': FONTS,
page_headline = 'Brother QL Label Designer' 'label_sizes': LABEL_SIZES,
return {'title': title, 'page_headline': page_headline, 'message': '', 'font_family_names': font_family_names, 'fonts': FONTS, 'label_sizes': label_sizes, 'default_label_size': DEFAULT_LABEL_SIZE, 'default_orientation': DEFAULT_ORIENTATION} 'website': CONFIG['WEBSITE'],
'label': CONFIG['LABEL']}
def get_label_context(request): def get_label_context(request):
""" might raise LookupError() """ """ might raise LookupError() """
@ -83,8 +78,8 @@ def get_label_context(request):
def get_font_path(font_family_name, font_style_name): def get_font_path(font_family_name, font_style_name):
try: try:
if font_family_name is None or font_style_name is None: if font_family_name is None or font_style_name is None:
font_family_name = DEFAULT_FONT['family'] font_family_name = CONFIG['LABEL']['DEFAULT_FONTS']['family']
font_style_name = DEFAULT_FONT['style'] font_style_name = CONFIG['LABEL']['DEFAULT_FONTS']['style']
font_path = FONTS[font_family_name][font_style_name] font_path = FONTS[font_family_name][font_style_name]
except KeyError: except KeyError:
raise LookupError("Couln't find the font & style") raise LookupError("Couln't find the font & style")
@ -199,12 +194,12 @@ def print_text():
elif context['kind'] in (ROUND_DIE_CUT_LABEL, DIE_CUT_LABEL): elif context['kind'] in (ROUND_DIE_CUT_LABEL, DIE_CUT_LABEL):
rotate = 'auto' rotate = 'auto'
qlr = BrotherQLRaster(MODEL) qlr = BrotherQLRaster(CONFIG['PRINTER']['MODEL'])
create_label(qlr, im, context['label_size'], threshold=context['threshold'], cut=True, rotate=rotate) create_label(qlr, im, context['label_size'], threshold=context['threshold'], cut=True, rotate=rotate)
if not DEBUG: if not DEBUG:
try: try:
be = BACKEND_CLASS(BACKEND_STRING_DESCR) be = BACKEND_CLASS(CONFIG['PRINTER']['PRINTER'])
be.write(qlr.data) be.write(qlr.data)
be.dispose() be.dispose()
del be del be
@ -218,57 +213,84 @@ def print_text():
return return_dict return return_dict
def main(): def main():
global DEBUG, FONTS, DEFAULT_FONT, MODEL, BACKEND_CLASS, BACKEND_STRING_DESCR, DEFAULT_ORIENTATION, DEFAULT_LABEL_SIZE global DEBUG, FONTS, BACKEND_CLASS, CONFIG
import argparse
parser = argparse.ArgumentParser(description=__doc__) parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('--port', default=8013) parser.add_argument('--port', default=8013)
parser.add_argument('--loglevel', type=lambda x: getattr(logging, x.upper()), default='WARNING') parser.add_argument('--loglevel', type=lambda x: getattr(logging, x.upper()), default=False)
parser.add_argument('--font-folder', help='folder for additional .ttf/.otf fonts') parser.add_argument('--font-folder', default=False, help='folder for additional .ttf/.otf fonts')
parser.add_argument('--default-label-size', default="62", help='Label size inserted in your printer. Defaults to 62.') parser.add_argument('--default-label-size', default=False, help='Label size inserted in your printer. Defaults to 62.')
parser.add_argument('--default-orientation', default="standard", choices=('standard', 'rotated'), help='Label orientation, defaults to "standard". To turn your text by 90°, state "rotated".') parser.add_argument('--default-orientation', default=False, choices=('standard', 'rotated'), help='Label orientation, defaults to "standard". To turn your text by 90°, state "rotated".')
parser.add_argument('--model', default='QL-500', choices=models, help='The model of your printer (default: QL-500)') parser.add_argument('--model', default=False, choices=models, help='The model of your printer (default: QL-500)')
parser.add_argument('printer', help='String descriptor for the printer to use (like tcp://192.168.0.23:9100 or file:///dev/usb/lp0)') parser.add_argument('printer', nargs='?', default=False, help='String descriptor for the printer to use (like tcp://192.168.0.23:9100 or file:///dev/usb/lp0)')
args = parser.parse_args() args = parser.parse_args()
DEBUG = args.loglevel == logging.DEBUG if args.printer:
logging.basicConfig(level=args.loglevel) CONFIG['PRINTER']['PRINTER'] = args.printer
if args.port:
PORT = args.port
else:
PORT = CONFIG['SERVER']['PORT']
if args.loglevel:
LOGLEVEL = args.loglevel
else:
LOGLEVEL = CONFIG['SERVER']['LOGLEVEL']
if LOGLEVEL == 'DEBUG':
DEBUG = True
else:
DEBUG = False
if args.model:
CONFIG['PRINTER']['MODEL'] = args.model
if args.default_label_size:
CONFIG['LABEL']['DEFAULT_SIZE'] = args.default_label_size
if args.default_orientation:
CONFIG['LABEL']['DEFAULT_ORIENTATION'] = args.default_orientation
if args.font_folder:
ADDITIONAL_FONT_FOLDER = args.font_folder
else:
ADDITIONAL_FONT_FOLDER = CONFIG['SERVER']['ADDITIONAL_FONT_FOLDER']
logging.basicConfig(level=LOGLEVEL)
try: try:
selected_backend = guess_backend(args.printer) selected_backend = guess_backend(CONFIG['PRINTER']['PRINTER'])
except: except ValueError:
parser.error("Couln't guess the backend to use from the printer string descriptor") parser.error("Couln't guess the backend to use from the printer string descriptor")
BACKEND_CLASS = backend_factory(selected_backend)['backend_class'] BACKEND_CLASS = backend_factory(selected_backend)['backend_class']
BACKEND_STRING_DESCR = args.printer
MODEL = args.model if CONFIG['LABEL']['DEFAULT_SIZE'] not in label_sizes:
if args.default_label_size not in label_sizes:
parser.error("Invalid --default-label-size. Please choose on of the following:\n:" + " ".join(label_sizes)) parser.error("Invalid --default-label-size. Please choose on of the following:\n:" + " ".join(label_sizes))
DEFAULT_LABEL_SIZE = args.default_label_size
DEFAULT_ORIENTATION = args.default_orientation
FONTS = get_fonts() FONTS = get_fonts()
if args.font_folder: if ADDITIONAL_FONT_FOLDER:
FONTS.update(get_fonts(args.font_folder)) FONTS.update(get_fonts(ADDITIONAL_FONT_FOLDER))
if not FONTS: if not FONTS:
sys.stderr.write("Not a single font was found on your system. Please install some or use the \"--font-folder\" argument.\n") sys.stderr.write("Not a single font was found on your system. Please install some or use the \"--font-folder\" argument.\n")
sys.exit(2) sys.exit(2)
for font in DEFAULT_FONTS: for font in CONFIG['LABEL']['DEFAULT_FONTS']:
try: try:
FONTS[font['family']][font['style']] FONTS[font['family']][font['style']]
DEFAULT_FONT = font CONFIG['LABEL']['DEFAULT_FONTS'] = font
logger.debug("Selected the following default font: {}".format(font)) logger.debug("Selected the following default font: {}".format(font))
break break
except: pass except: pass
if DEFAULT_FONT is None: if CONFIG['LABEL']['DEFAULT_FONTS'] is None:
sys.stderr.write('Could not find any of the default fonts. Choosing a random one.\n') sys.stderr.write('Could not find any of the default fonts. Choosing a random one.\n')
family = random.choice(list(FONTS.keys())) family = random.choice(list(FONTS.keys()))
style = random.choice(list(FONTS[family].keys())) style = random.choice(list(FONTS[family].keys()))
DEFAULT_FONT = {'family': family, 'style': style} CONFIG['LABEL']['DEFAULT_FONTS'] = {'family': family, 'style': style}
sys.stderr.write('The default font is now set to: {family} ({style})\n'.format(**DEFAULT_FONT)) sys.stderr.write('The default font is now set to: {family} ({style})\n'.format(**CONFIG['LABEL']['DEFAULT_FONTS']))
run(host='', port=args.port, debug=DEBUG) run(host=CONFIG['SERVER']['HOST'], port=PORT, debug=DEBUG)
if __name__ == "__main__": if __name__ == "__main__":
main() main()

27
config.example.json Normal file
View File

@ -0,0 +1,27 @@
{
"SERVER": {
"PORT": 8013,
"HOST": "",
"LOGLEVEL": "WARNING",
"ADDITIONAL_FONT_FOLDER": false
},
"PRINTER": {
"MODEL": "QL-500",
"PRINTER": "file:///dev/usb/lp1"
},
"LABEL": {
"DEFAULT_SIZE": "62",
"DEFAULT_ORIENTATION": "standard",
"DEFAULT_FONT_SIZE": 45,
"DEFAULT_FONTS": [
{"family": "Minion Pro", "style": "Semibold"},
{"family": "Linux Libertine", "style": "Regular"},
{"family": "DejaVu Serif", "style": "Book"}
]
},
"WEBSITE": {
"HTML_TITLE": "Label Designer",
"PAGE_TITLE": "Label Designer",
"PAGE_HEADLINE": "Brother QL Label Designer"
}
}

View File

@ -10,7 +10,7 @@
<link rel="stylesheet" href="/static/css/bootstrap.min.css"> <link rel="stylesheet" href="/static/css/bootstrap.min.css">
<link rel="stylesheet" href="/static/css/custom.css"> <link rel="stylesheet" href="/static/css/custom.css">
<title>{% block page_title %}{% endblock %} | Brother QL</title> <title>{{ website['HTML_TITLE'] }} | Brother QL</title>
</head> </head>
<body> <body>
<nav class="navbar navbar-inverse navbar-fixed-top"> <nav class="navbar navbar-inverse navbar-fixed-top">
@ -22,7 +22,7 @@
<span class="icon-bar"></span> <span class="icon-bar"></span>
<span class="icon-bar"></span> <span class="icon-bar"></span>
</button> </button>
<a class="navbar-brand" href="/">{{page_headline}}</a> <a class="navbar-brand" href="/">{{ website['PAGE_TITLE'] }}</a>
</div> </div>
</div> </div>
</nav> </nav>

View File

@ -3,8 +3,8 @@
{% block page_title %}{{ title }}{% endblock %} {% block page_title %}{{ title }}{% endblock %}
{% block jumbotron %} {% block jumbotron %}
<h1>{{page_headline}}</h1> <h1>{{ website['PAGE_TITLE'] }}</h1>
<p>Design your label and print it...</p> <p>{{ website['PAGE_HEADLINE'] }}</p>
<!--<p><a class="btn btn-primary btn-lg" href="#" role="button">History of printed labels</a></p>--> <!--<p><a class="btn btn-primary btn-lg" href="#" role="button">History of printed labels</a></p>-->
{% endblock %} {% endblock %}
@ -24,7 +24,7 @@
<div class="chooser panel-body"> <div class="chooser panel-body">
<label for="labelSize" style="display: none">Label Size:</label> <label for="labelSize" style="display: none">Label Size:</label>
<select class="form-control" id="labelSize" onChange="preview()"> <select class="form-control" id="labelSize" onChange="preview()">
{% for label_size in label_sizes %}<option value="{{label_size[0]}}" {% if default_label_size == label_size[0] %}selected{% endif %}>{{label_size[1]}}</option>{% endfor %} {% for label_size in label_sizes %}<option value="{{label_size[0]}}" {% if label['DEFAULT_SIZE'] == label_size[0] %}selected{% endif %}>{{label_size[1]}}</option>{% endfor %}
</select> </select>
<label for="orientation" style="margin-top: 10px; margin-bottom: 0">Label Orientation:</label> <label for="orientation" style="margin-top: 10px; margin-bottom: 0">Label Orientation:</label>
<div class="radio" style="margin-top: 5px;"> <div class="radio" style="margin-top: 5px;">
@ -56,7 +56,7 @@
{% endfor %} {% endfor %}
</select> </select>
<label for="fontSize" >Font Size:</label> <label for="fontSize" >Font Size:</label>
<input id="fontSize" class="form-control" type="number" min="1" value="70" onChange="preview()" required> <input id="fontSize" class="form-control" type="number" min="1" value="{{ label['DEFAULT_FONT_SIZE'] }}" onChange="preview()" required>
<label for="fontAlign" class="control-label input-group">Font Alignment:</label> <label for="fontAlign" class="control-label input-group">Font Alignment:</label>
<div class="btn-group" data-toggle="buttons"> <div class="btn-group" data-toggle="buttons">
<label class="btn btn-default"> <label class="btn btn-default">