From dc915ab4034fa7cc40f9fb25731ac7d5ac8dedac Mon Sep 17 00:00:00 2001 From: Brendan Howell Date: Thu, 19 Mar 2020 23:55:27 +0100 Subject: [PATCH] refactor small printer to use central config --- screenless/bureau/bureau.py | 89 ++++++++++++++++++++++++++----------- 1 file changed, 62 insertions(+), 27 deletions(-) diff --git a/screenless/bureau/bureau.py b/screenless/bureau/bureau.py index babb239..9eee76e 100644 --- a/screenless/bureau/bureau.py +++ b/screenless/bureau/bureau.py @@ -1,4 +1,5 @@ # bureau +import configparser import functools import glob import inspect @@ -12,13 +13,11 @@ import string import subprocess import tempfile import textwrap -#import traceback import threading import lmdb import PIL import weasyprint -from weasyprint.fonts import FontConfiguration import zmq from escpos import printer from mako.template import Template @@ -63,30 +62,24 @@ def add_api(apistr, name=""): return decorator -#def log_traceback(func): -# """ this is a decorator that catches tracebacks for logging""" -# def wrapper(*args): -# my_bureau = args[0] -# try: -# func(*args) -# except Exception as e: -# my_bureau.log.error("CRASH TRACE: {0}".format(my_bureau.name), -# exc_info=e) -# raise -# return wrapper - - class LogPrinter(logging.Handler): """ LogPrinter prints logs on a receipt printer for screenless debugging. """ - def __init__(self): + def __init__(self, log_printer): + self.printer = log_printer logging.Handler.__init__(self) def emit(self, record): - prn = printer.Usb(0x416, 0x5011, in_ep=0x81, out_ep=0x03) + if (self.printer["inep"] is None) and (self.printer["outep"] is None): + prn = printer.Usb(self.printer["vendorid"], self.printer["productid"]) + else: + prn = printer.Usb(self.printer["vendorid"], + self.printer["productid"], + in_ep=self.printer["inep"], + out_ep=self.printer["outep"]) msg = self.format(record) - text = textwrap.fill(msg, width=48) + text = textwrap.fill(msg, width=self.printer["textwidth"]) text += "\r\n" * 4 prn.text(text) prn.cut() @@ -162,7 +155,7 @@ class Bureau(object): default_config = {} def __init__(self): - """ set up ZeroMQ connections and register commands""" + """ set up ZeroMQ connections, printers, fonts and register commands""" self.commands = {} self.api = {} @@ -187,6 +180,36 @@ class Bureau(object): self.load_config() + # load printer configs + printcfg = configparser.ConfigParser() + try: + printcfg.read("printers.cfg") + self.smprint = object() + self.smprint["vendorid"] = printcfg["smallprinter"]["vendorid"] + self.smprint["prodid"] = printcfg["smallprinter"]["productid"] + self.smprint["in_ep"] = printcfg["smallprinter"]["inep"] + self.smprint["out_ep"] = printcfg["smallprinter"]["outep"] + self.smprint["width"] = printcfg["smallprinter"]["width"] + self.smprint["textwidth"] = printcfg["smallprinter"]["textwidth"] + + self.lp["name"] = printcfg["largeprinter"]["name"] + self.lp["papersize"] = printcfg["largeprinter"]["papersize"] + self.lp["duplex"] = printcfg["largeprinter"]["duplex"] + except KeyError: + # TODO: eventually refactor this since it could overwrite a half-broken config + sp_dict = {"vendorid": None, "productid": None, + "inep": None, "outep": None, "width": 384, + "textwidth": 32} + lp_dict = {"name": None, "papersize": "A4", + "duplex": False} + printcfg["smallprinter"] = sp_dict + printcfg["largeprinter"] = lp_dict + with open("printers.cfg", "w") as print_conf_file: + printcfg.write(print_conf_file) + self.smprint = sp_dict + self.lp = lp_dict + + # setup log file if "debug" in self.config: if self.config["debug"]: @@ -198,7 +221,7 @@ class Bureau(object): logfile = os.path.join(basepath, self.prefix + ".log") logging.basicConfig(filename=logfile, level=log_level) self.log = logging.getLogger(self.prefix) - log_printer = LogPrinter() + log_printer = LogPrinter(self.smprint) log_format = logging.Formatter('LOG ${levelname} $name: $message', style='$') log_printer.setFormatter(log_format) self.log.addHandler(log_printer) @@ -352,9 +375,14 @@ class Bureau(object): """ print on Thermal Line printer. """ - # TODO: look up device and width in config - prn = printer.Usb(0x416, 0x5011, in_ep=0x81, out_ep=0x03) - text = textwrap.fill(text, width=48) + if (self.smprint["inep"] is None) and (self.smprint["outep"] is None): + prn = printer.Usb(self.smprint["vendorid"], self.smprint["productid"]) + else: + prn = printer.Usb(self.smprint["vendorid"], + self.smprint["productid"], + in_ep=self.smprint["inep"], + out_ep=self.smprint["outep"]) + text = textwrap.fill(text, width=self.smprint["textwidth"]) text += "\r\n" * 2 prn.text(text + "\r\n\r\n") if cut: @@ -364,8 +392,13 @@ class Bureau(object): """ print an image on the mini thermal printer. """ - # TODO: make printer id/width configured and easy - prn = printer.Usb(0x416, 0x5011, in_ep=0x81, out_ep=0x03) + if (self.smprint["inep"] is None) and (self.smprint["outep"] is None): + prn = printer.Usb(self.smprint["vendorid"], self.smprint["productid"]) + else: + prn = printer.Usb(self.smprint["vendorid"], + self.smprint["productid"], + in_ep=self.smprint["inep"], + out_ep=self.smprint["outep"]) if type(img) is PIL.Image.Image: im = img @@ -374,8 +407,10 @@ class Bureau(object): # NOTE: might be worth tring to push up brightness im = PIL.ImageOps.equalize(im) # stretch histogram for nicer dither - im.thumbnail((576, 1024), PIL.Image.ANTIALIAS) # resize to fit printer - prn.image(im, impl="bitImageColumn") # not using this impl crashes ?? + # resize to fit printer + im.thumbnail((self.smprint["width"], 1024), PIL.Image.ANTIALIAS) + # not using this bitImageColumn crashes some printers, sigh + prn.image(im, impl="bitImageColumn") @add_command("test") def test(self, data=None):