mirror of
https://github.com/pklaus/brother_ql_web.git
synced 2024-05-25 11:56:53 +03:00
addes configuration file config.json - close #8
This commit is contained in:
parent
6218a1dfc9
commit
2d07cee36d
|
@ -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
|
||||
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
|
||||
|
||||
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]
|
||||
[--font-folder FONT_FOLDER]
|
||||
[--default-label-size DEFAULT_LABEL_SIZE]
|
||||
[--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}]
|
||||
printer
|
||||
[printer]
|
||||
|
||||
This is a web service to print labels on Brother QL label printers.
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
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 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__)
|
||||
|
||||
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]
|
||||
|
||||
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('/')
|
||||
def index():
|
||||
redirect('/labeldesigner')
|
||||
|
@ -47,10 +41,11 @@ def serve_static(filename):
|
|||
@view('labeldesigner.jinja2')
|
||||
def labeldesigner():
|
||||
font_family_names = sorted(list(FONTS.keys()))
|
||||
label_sizes = LABEL_SIZES
|
||||
title = 'Label Designer'
|
||||
page_headline = 'Brother QL Label Designer'
|
||||
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}
|
||||
return {'font_family_names': font_family_names,
|
||||
'fonts': FONTS,
|
||||
'label_sizes': LABEL_SIZES,
|
||||
'website': CONFIG['WEBSITE'],
|
||||
'label': CONFIG['LABEL']}
|
||||
|
||||
def get_label_context(request):
|
||||
""" might raise LookupError() """
|
||||
|
@ -83,8 +78,8 @@ def get_label_context(request):
|
|||
def get_font_path(font_family_name, font_style_name):
|
||||
try:
|
||||
if font_family_name is None or font_style_name is None:
|
||||
font_family_name = DEFAULT_FONT['family']
|
||||
font_style_name = DEFAULT_FONT['style']
|
||||
font_family_name = CONFIG['LABEL']['DEFAULT_FONTS']['family']
|
||||
font_style_name = CONFIG['LABEL']['DEFAULT_FONTS']['style']
|
||||
font_path = FONTS[font_family_name][font_style_name]
|
||||
except KeyError:
|
||||
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):
|
||||
rotate = 'auto'
|
||||
|
||||
qlr = BrotherQLRaster(MODEL)
|
||||
qlr = BrotherQLRaster(CONFIG['PRINTER']['MODEL'])
|
||||
create_label(qlr, im, context['label_size'], threshold=context['threshold'], cut=True, rotate=rotate)
|
||||
|
||||
if not DEBUG:
|
||||
try:
|
||||
be = BACKEND_CLASS(BACKEND_STRING_DESCR)
|
||||
be = BACKEND_CLASS(CONFIG['PRINTER']['PRINTER'])
|
||||
be.write(qlr.data)
|
||||
be.dispose()
|
||||
del be
|
||||
|
@ -218,57 +213,84 @@ def print_text():
|
|||
return return_dict
|
||||
|
||||
def main():
|
||||
global DEBUG, FONTS, DEFAULT_FONT, MODEL, BACKEND_CLASS, BACKEND_STRING_DESCR, DEFAULT_ORIENTATION, DEFAULT_LABEL_SIZE
|
||||
import argparse
|
||||
global DEBUG, FONTS, BACKEND_CLASS, CONFIG
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument('--port', default=8013)
|
||||
parser.add_argument('--loglevel', type=lambda x: getattr(logging, x.upper()), default='WARNING')
|
||||
parser.add_argument('--font-folder', 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-orientation', default="standard", 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('printer', help='String descriptor for the printer to use (like tcp://192.168.0.23:9100 or file:///dev/usb/lp0)')
|
||||
parser.add_argument('--loglevel', type=lambda x: getattr(logging, x.upper()), default=False)
|
||||
parser.add_argument('--font-folder', default=False, help='folder for additional .ttf/.otf fonts')
|
||||
parser.add_argument('--default-label-size', default=False, help='Label size inserted in your printer. Defaults to 62.')
|
||||
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=False, choices=models, help='The model of your printer (default: QL-500)')
|
||||
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()
|
||||
|
||||
DEBUG = args.loglevel == logging.DEBUG
|
||||
logging.basicConfig(level=args.loglevel)
|
||||
if args.printer:
|
||||
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:
|
||||
selected_backend = guess_backend(args.printer)
|
||||
except:
|
||||
selected_backend = guess_backend(CONFIG['PRINTER']['PRINTER'])
|
||||
except ValueError:
|
||||
parser.error("Couln't guess the backend to use from the printer string descriptor")
|
||||
BACKEND_CLASS = backend_factory(selected_backend)['backend_class']
|
||||
BACKEND_STRING_DESCR = args.printer
|
||||
|
||||
MODEL = args.model
|
||||
|
||||
if args.default_label_size not in label_sizes:
|
||||
if CONFIG['LABEL']['DEFAULT_SIZE'] not in 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()
|
||||
if args.font_folder:
|
||||
FONTS.update(get_fonts(args.font_folder))
|
||||
if ADDITIONAL_FONT_FOLDER:
|
||||
FONTS.update(get_fonts(ADDITIONAL_FONT_FOLDER))
|
||||
|
||||
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.exit(2)
|
||||
|
||||
for font in DEFAULT_FONTS:
|
||||
for font in CONFIG['LABEL']['DEFAULT_FONTS']:
|
||||
try:
|
||||
FONTS[font['family']][font['style']]
|
||||
DEFAULT_FONT = font
|
||||
CONFIG['LABEL']['DEFAULT_FONTS'] = font
|
||||
logger.debug("Selected the following default font: {}".format(font))
|
||||
break
|
||||
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')
|
||||
family = random.choice(list(FONTS.keys()))
|
||||
style = random.choice(list(FONTS[family].keys()))
|
||||
DEFAULT_FONT = {'family': family, 'style': style}
|
||||
sys.stderr.write('The default font is now set to: {family} ({style})\n'.format(**DEFAULT_FONT))
|
||||
CONFIG['LABEL']['DEFAULT_FONTS'] = {'family': family, 'style': style}
|
||||
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__":
|
||||
main()
|
||||
|
|
27
config.example.json
Normal file
27
config.example.json
Normal 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"
|
||||
}
|
||||
}
|
|
@ -10,7 +10,7 @@
|
|||
<link rel="stylesheet" href="/static/css/bootstrap.min.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>
|
||||
<body>
|
||||
<nav class="navbar navbar-inverse navbar-fixed-top">
|
||||
|
@ -22,7 +22,7 @@
|
|||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a class="navbar-brand" href="/">{{page_headline}}</a>
|
||||
<a class="navbar-brand" href="/">{{ website['PAGE_TITLE'] }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
{% block page_title %}{{ title }}{% endblock %}
|
||||
|
||||
{% block jumbotron %}
|
||||
<h1>{{page_headline}}</h1>
|
||||
<p>Design your label and print it...</p>
|
||||
<h1>{{ website['PAGE_TITLE'] }}</h1>
|
||||
<p>{{ website['PAGE_HEADLINE'] }}</p>
|
||||
<!--<p><a class="btn btn-primary btn-lg" href="#" role="button">History of printed labels</a></p>-->
|
||||
{% endblock %}
|
||||
|
||||
|
@ -24,7 +24,7 @@
|
|||
<div class="chooser panel-body">
|
||||
<label for="labelSize" style="display: none">Label Size:</label>
|
||||
<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>
|
||||
<label for="orientation" style="margin-top: 10px; margin-bottom: 0">Label Orientation:</label>
|
||||
<div class="radio" style="margin-top: 5px;">
|
||||
|
@ -56,7 +56,7 @@
|
|||
{% endfor %}
|
||||
</select>
|
||||
<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>
|
||||
<div class="btn-group" data-toggle="buttons">
|
||||
<label class="btn btn-default">
|
||||
|
|
Loading…
Reference in New Issue
Block a user