Add support for signature on brother printers

This commit is contained in:
n07070
2026-11-13 02:45:11 +01:00
parent 0a6431eecf
commit e2eb3d3825
5 changed files with 141 additions and 100 deletions

View File

@@ -1,7 +1,8 @@
""" """
Welcome to the LittlePrynter's source code. Welcome to the LittlePrynter's source code.
This program expose a web interface, with user authentification, This program expose a web interface,
that makes it possible to print messages from the web. that makes it possible to print messages from the web.
It also exposes a API, making it possible to print and interface It also exposes a API, making it possible to print and interface
with much of the printer's abilities. with much of the printer's abilities.
@@ -10,12 +11,14 @@ Then we build the API around Flask,
Then we build the web interface, using the simple Jinja2 templating. Then we build the web interface, using the simple Jinja2 templating.
We support two modes : We support two modes :
The first is a simple mode, where a computer, connected to a thermal printer, The first is a simple mode, where a computer, connected to a thermal printer,
runs this program and exposes a web interface that makes use of the client's camera runs this program and exposes a web interface that makes use of the client's camera
The seconde is booth mode, where a Raspberry Pi is connected to a thermal printer,
a button and a flash. The seconde is booth mode, where a Raspberry Pi is connected to
The web interface exists but may not be used, as the press of the button with take a thermal printer, a button and a flash.
a picture and activate the flash while simply informing the web page. The web interface exists but it's not needed, as the press of the button
takes a picture and activates the flash while simply informing the web page.
""" """
# Following are the librairies we import, # Following are the librairies we import,
@@ -98,11 +101,7 @@ app.config["TEMPLATES_AUTO_RELOAD"] = True
print_queue = PrintQueue(app) print_queue = PrintQueue(app)
# Find out if we are running on a Raspberry Pi # Find out if we are running on a Raspberry Pi
rpi = Raspberry( rpi = Raspberry(print_queue, app, configuration_file)
print_queue,
app,
configuration_file
)
RASPBERRY_PI_CONNECTED = rpi.is_raspberry_pi() RASPBERRY_PI_CONNECTED = rpi.is_raspberry_pi()
@@ -134,6 +133,7 @@ limiter = Limiter(
app.logger.info("🖶 Welcome to LittlePrynter !") app.logger.info("🖶 Welcome to LittlePrynter !")
# General routes # General routes
@app.route("/") @app.route("/")
@limiter.limit("1/second", override_defaults=False) @limiter.limit("1/second", override_defaults=False)
@@ -233,7 +233,6 @@ def web_print_img():
except werkzeug.exceptions.BadRequestKeyError: except werkzeug.exceptions.BadRequestKeyError:
process_image = False process_image = False
try: try:
app.logger.debug("Sending the image to the printer.") app.logger.debug("Sending the image to the printer.")
web.print_image(file, sign, do_cut, process_image) web.print_image(file, sign, do_cut, process_image)
@@ -287,7 +286,6 @@ def api_print_sms():
except werkzeug.exceptions.BadRequestKeyError: except werkzeug.exceptions.BadRequestKeyError:
do_cut = False do_cut = False
try: try:
# comment: We try to print the SMS # comment: We try to print the SMS
web.print_sms(txt, sign, do_cut) web.print_sms(txt, sign, do_cut)
@@ -390,11 +388,13 @@ def api_worker_stop():
worker.stop_worker() worker.stop_worker()
return jsonify(worker.current_state()) return jsonify(worker.current_state())
@app.route("/api/printers") @app.route("/api/printers")
def api_printers_info(): def api_printers_info():
"""Returns the current state of every printers""" """Returns the current state of every printers"""
return jsonify(printers_pool.printers_info()) return jsonify(printers_pool.printers_info())
## Authentification ## Authentification

View File

@@ -77,7 +77,12 @@ class PrintQueue:
with self._lock: with self._lock:
self.app.logger.debug("Return current queue state") self.app.logger.debug("Return current queue state")
return [ return [
{"task_id": t.task_id, "status": t.status, "type": str(t.task_type), "content": str(t.get_print_data())} {
"task_id": t.task_id,
"status": t.status,
"type": str(t.task_type),
"content": str(t.get_print_data()),
}
for t in self._queue for t in self._queue
] ]

View File

@@ -16,7 +16,6 @@ from uuid import uuid4
from PIL import Image, ImageEnhance, ImageDraw, ImageFont from PIL import Image, ImageEnhance, ImageDraw, ImageFont
import numpy as np import numpy as np
# Importing the modules needed for each supported printer Type # Importing the modules needed for each supported printer Type
import escpos.printer import escpos.printer
from brother_ql.models import ModelsManager from brother_ql.models import ModelsManager
@@ -42,6 +41,7 @@ class PrinterInfo:
""" """
Brother-QL printer information Brother-QL printer information
""" """
identifier: str identifier: str
backend: str backend: str
protocol: str protocol: str
@@ -94,13 +94,14 @@ class Printer(ABC):
"""Takes a PrintTask and executes it""" """Takes a PrintTask and executes it"""
def use_printer(self) -> None: def use_printer(self) -> None:
"""Marks the printer as being used """ """Marks the printer as being used"""
self.used = True self.used = True
def free_printer(self) -> None: def free_printer(self) -> None:
"""Marks the printer as being not used, it's available.""" """Marks the printer as being not used, it's available."""
self.used = False self.used = False
class EscPosPrinter(Printer): class EscPosPrinter(Printer):
""" """
Create a new ESC/POS based printer. Create a new ESC/POS based printer.
@@ -128,8 +129,10 @@ class EscPosPrinter(Printer):
"The USB device is not plugged in : %s", "The USB device is not plugged in : %s",
str(e), str(e),
) )
raise e
except Exception as e: except Exception as e:
self.app.logger.error("Printer could not be connected : %s ", str(e)) self.app.logger.error("Printer could not be connected : %s ", str(e))
raise e
try: try:
if p.is_online(): if p.is_online():
@@ -187,7 +190,6 @@ class EscPosPrinter(Printer):
return True return True
def _print_txt(self, msg, signature="", bold=False): def _print_txt(self, msg, signature="", bold=False):
self.ready = False
if not isinstance(msg, str): if not isinstance(msg, str):
self.app.logger.error( self.app.logger.error(
"It is not possible to print a " + str(type(msg)) + ", only strings." "It is not possible to print a " + str(type(msg)) + ", only strings."
@@ -199,6 +201,7 @@ class EscPosPrinter(Printer):
clean_signature = str(signature) clean_signature = str(signature)
# Make checks on the size of the message being printed # Make checks on the size of the message being printed
# TODO: make the max length configurable
if len(clean_msg) > 4096: if len(clean_msg) > 4096:
self.app.logger.warning( self.app.logger.warning(
"Could not print message of this length: " + str(len(clean_msg)) "Could not print message of this length: " + str(len(clean_msg))
@@ -208,7 +211,7 @@ class EscPosPrinter(Printer):
+ str(len(clean_msg)) + str(len(clean_msg))
+ ", needs to be below 4096 caracters long." + ", needs to be below 4096 caracters long."
) )
# TODO: make the max length configurable
if len(signature) > 256: if len(signature) > 256:
self.app.logger.warning( self.app.logger.warning(
"Could not print signature of this length: " + str(len(clean_signature)) "Could not print signature of this length: " + str(len(clean_signature))
@@ -239,9 +242,9 @@ class EscPosPrinter(Printer):
self.ready = True self.ready = True
def _print_img(self, path, signature="", center=True, process=False): def _print_img(self, path, signature="", center=True, process=False):
self.ready = False
clean_signature = str(signature) clean_signature = str(signature)
# TODO: make the max length configurable
if len(signature) > 256: if len(signature) > 256:
self.app.logger.warning( self.app.logger.warning(
"Could not print signature of this length: " + str(len(clean_signature)) "Could not print signature of this length: " + str(len(clean_signature))
@@ -306,7 +309,6 @@ class EscPosPrinter(Printer):
self.ready = True self.ready = True
def _qr(self, content): def _qr(self, content):
self.ready = False
try: try:
self.printer.open(self.usb_args) self.printer.open(self.usb_args)
self.printer.qr(content, center=True) self.printer.qr(content, center=True)
@@ -321,7 +323,6 @@ class EscPosPrinter(Printer):
self.ready = True self.ready = True
def _cut(self): def _cut(self):
self.ready = False
try: try:
self.printer.open(self.usb_args) self.printer.open(self.usb_args)
self.printer.cut() self.printer.cut()
@@ -338,21 +339,23 @@ class EscPosPrinter(Printer):
has_paper = self._has_paper() has_paper = self._has_paper()
is_ready = self.ready is_ready = self.ready
self.app.logger.debug("Has paper : %s " , has_paper ) self.app.logger.debug("Has paper : %s ", has_paper)
self.app.logger.debug("Ready : %s " , is_ready ) self.app.logger.debug("Ready : %s ", is_ready)
return is_ready and has_paper # and is_online return is_ready and has_paper # and is_online
def print_task(self, task_type, data): def print_task(self, task_type, data):
"""Execute actual print based on task type""" """Execute actual print based on task type"""
with self._lock: with self._lock:
self.app.logger.debug("Acquired lock to start print") self.app.logger.debug("Acquired lock to start print")
i_m_ready = self._state() i_m_ready = self._state()
while not i_m_ready: while not i_m_ready:
self.app.logger.debug("Waiting for the printer to become ready, current state %s ", str(i_m_ready)) self.app.logger.debug(
"Waiting for the printer to become ready, current state %s ",
str(i_m_ready),
)
i_m_ready = self._state() i_m_ready = self._state()
time.sleep(0.3) time.sleep(0.3)
@@ -391,9 +394,7 @@ class BrotherPrinter(Printer):
def __init__(self, app, vendor_id, device_id): def __init__(self, app, vendor_id, device_id):
super().__init__( super().__init__(app, vendor_id, device_id, printer_type=PrinterType.BROTHER)
app, vendor_id, device_id, printer_type=PrinterType.BROTHER
)
self.printer = None self.printer = None
self.usb_args = {} self.usb_args = {}
self.usb_args["idVendor"] = self.vendor_id self.usb_args["idVendor"] = self.vendor_id
@@ -431,7 +432,7 @@ class BrotherPrinter(Printer):
self.app.logger.debug(f"Matched printer model: {model}") self.app.logger.debug(f"Matched printer model: {model}")
except ValueError as ve: except ValueError as ve:
self.app.logger.warning("Invalid product ID format:"+ str(ve)) self.app.logger.warning("Invalid product ID format:" + str(ve))
raise ve raise ve
except Exception as e: except Exception as e:
self.app.logger.error("Error while finding a model ? : " + str(e)) self.app.logger.error("Error while finding a model ? : " + str(e))
@@ -459,13 +460,12 @@ class BrotherPrinter(Printer):
def _print_txt(self, msg, signature="", bold=False): def _print_txt(self, msg, signature="", bold=False):
"""Print text after converting it to an image""" """Print text after converting it to an image"""
self._print_img(text_to_image(msg)) self._print_img(text_to_image(msg))
self._print_img(text_to_image(signature))
def _print_img(self, data, process=False): def _print_img(self, data, signature="", process=False):
""" """
Print a raster image via a Brother QL printer Print a raster image via a Brother QL printer
""" """
self.ready = False
if process: if process:
try: try:
self.app.logger.debug("Proccessing the image") self.app.logger.debug("Proccessing the image")
@@ -480,10 +480,13 @@ class BrotherPrinter(Printer):
self.app.logger.warning("Not proccessing the image") self.app.logger.warning("Not proccessing the image")
try: try:
selected_backend = guess_backend(self.printer_info.identifier) selected_backend = guess_backend(self.printer_info.identifier)
BACKEND_CLASS = backend_factory(selected_backend)['backend_class'] BACKEND_CLASS = backend_factory(selected_backend)["backend_class"]
BACKEND_STRING_DESCR = self.printer_info.identifier BACKEND_STRING_DESCR = self.printer_info.identifier
except Exception: except Exception as e:
self.app.logger.error("Couldn't guess the backend to use from the printer string descriptor") self.app.logger.error(
"Couldn't guess the backend to use from the printer string descriptor"
)
raise e
try: try:
im = Image.open(processed_path) im = Image.open(processed_path)
@@ -498,20 +501,40 @@ class BrotherPrinter(Printer):
except Exception as e: except Exception as e:
raise e raise e
if signature != "":
try:
im = Image.open(text_to_image(signature))
qlr = BrotherQLRaster(self.printer_info.model)
create_label(
qlr, im, self.printer_info.label_type, cut=False, dither=True
)
# noinspection PyCallingNonCallable
be = BACKEND_CLASS(BACKEND_STRING_DESCR)
be.write(qlr.data)
be.dispose()
del be
except Exception as e:
raise e
def _cut(self): def _cut(self):
self.ready = False
try: try:
selected_backend = guess_backend(self.printer_info.identifier) selected_backend = guess_backend(self.printer_info.identifier)
BACKEND_CLASS = backend_factory(selected_backend)['backend_class'] BACKEND_CLASS = backend_factory(selected_backend)["backend_class"]
BACKEND_STRING_DESCR = self.printer_info.identifier BACKEND_STRING_DESCR = self.printer_info.identifier
except Exception as e: except Exception as e:
self.app.logger.error("Couldn't guess the backend to use from the printer string descriptor") self.app.logger.error(
"Couldn't guess the backend to use from the printer string descriptor"
)
raise e
data = "src/static/images/1x1.png" data = "src/static/images/1x1.png"
try: try:
im = Image.open(data) im = Image.open(data)
qlr = BrotherQLRaster(self.printer_info.model) qlr = BrotherQLRaster(self.printer_info.model)
create_label(qlr, im, self.printer_info.label_type, threshold=70, cut=True, rotate=0) create_label(
qlr, im, self.printer_info.label_type, threshold=70, cut=True, rotate=0
)
# noinspection PyCallingNonCallable # noinspection PyCallingNonCallable
be = BACKEND_CLASS(BACKEND_STRING_DESCR) be = BACKEND_CLASS(BACKEND_STRING_DESCR)
@@ -521,32 +544,41 @@ class BrotherPrinter(Printer):
except Exception as e: except Exception as e:
raise e raise e
def _qr(self):
# This should not be reached by a print on a BrotherQL
raise NotImplementedError
def print_task(self, task_type, data): def print_task(self, task_type, data):
"""Execute actual print based on task type""" """Execute actual print based on task type"""
with self._lock: with self._lock:
if self.ready: self.app.logger.debug("Acquired lock to start print")
try: i_m_ready = self._state()
match (task_type.value): while not i_m_ready:
case "image": self.app.logger.debug(
self._print_img(data["img"]) "Waiting for the printer to become ready, current state %s ",
self.ready = True str(i_m_ready),
case "cut": )
self._cut() i_m_ready = self._state()
self.ready = True time.sleep(0.3)
case "text":
self._print_txt(data["txt"], signature=data["sign"])
self.ready = True
case _:
raise RuntimeError("This task type is not supported")
except Exception as e:
raise e
# end try
else:
raise RuntimeError("The printer is not ready to print yet !")
# These values are by default for now self.app.logger.debug("Checked state to start printing : %s", self._state())
self.ready = False
# raise NotImplementedError("This printer type is not implemented yet") try:
match (task_type.value):
case "image":
self._print_img(data["img"], signature=data["sign"])
self.ready = True
case "cut":
self._cut()
self.ready = True
case "text":
self._print_txt(data["txt"], signature=data["sign"])
self.ready = True
case _:
raise RuntimeError("This task type is not supported")
except Exception as e:
raise e
def _process_image(self, path, max_width=575, max_height=1000): def _process_image(self, path, max_width=575, max_height=1000):
@@ -563,15 +595,12 @@ def _process_image(self, path, max_width=575, max_height=1000):
grayscale = img.convert("L") grayscale = img.convert("L")
avg_brightness = np.asarray(grayscale, dtype=np.float32).mean() avg_brightness = np.asarray(grayscale, dtype=np.float32).mean()
self.app.logger.debug( self.app.logger.debug("Average brightness of the image: %.2f", avg_brightness)
"Average brightness of the image: %.2f", avg_brightness
)
if avg_brightness < brightness_threshold: if avg_brightness < brightness_threshold:
brightness_factor = min( brightness_factor = min(
max( max(
1 + (brightness_threshold - avg_brightness) 1 + (brightness_threshold - avg_brightness) / brightness_threshold,
/ brightness_threshold,
1.1, 1.1,
), ),
2.5, 2.5,
@@ -580,9 +609,7 @@ def _process_image(self, path, max_width=575, max_height=1000):
"Image is dark; increasing brightness by %.2f", "Image is dark; increasing brightness by %.2f",
brightness_factor, brightness_factor,
) )
grayscale = ImageEnhance.Brightness(grayscale).enhance( grayscale = ImageEnhance.Brightness(grayscale).enhance(brightness_factor)
brightness_factor
)
contrast = float(np.asarray(grayscale, dtype=np.float32).std()) contrast = float(np.asarray(grayscale, dtype=np.float32).std())
self.app.logger.debug("Grayscale standard deviation: %.2f", contrast) self.app.logger.debug("Grayscale standard deviation: %.2f", contrast)
@@ -596,6 +623,7 @@ def _process_image(self, path, max_width=575, max_height=1000):
self.app.logger.debug("Processed and saved image: %s", jpeg_path) self.app.logger.debug("Processed and saved image: %s", jpeg_path)
return jpeg_path return jpeg_path
def text_to_image( def text_to_image(
text, text,
width=400, width=400,
@@ -639,7 +667,11 @@ def text_to_image(
line = "" line = ""
piece = "" piece = ""
for char in word: for char in word:
if piece and draw.textbbox((0, 0), piece + char, font=font)[2] > max_text_width: if (
piece
and draw.textbbox((0, 0), piece + char, font=font)[2]
> max_text_width
):
lines.append(piece) lines.append(piece)
piece = char piece = char
else: else:
@@ -654,11 +686,7 @@ def text_to_image(
ascent, descent = font.getmetrics() ascent, descent = font.getmetrics()
line_height = ascent + descent line_height = ascent + descent
height = ( height = 2 * padding + len(lines) * line_height + (len(lines) - 1) * line_spacing
2 * padding
+ len(lines) * line_height
+ (len(lines) - 1) * line_spacing
)
image = Image.new("RGB", (width, height), background) image = Image.new("RGB", (width, height), background)
draw = ImageDraw.Draw(image) draw = ImageDraw.Draw(image)
@@ -674,4 +702,4 @@ def text_to_image(
image_path = upload_dir / f"{uuid4().hex}.png" image_path = upload_dir / f"{uuid4().hex}.png"
image.save(image_path, format="PNG") image.save(image_path, format="PNG")
return str(image_path) return str(image_path)

View File

@@ -49,10 +49,7 @@ class Printers:
# Find all connected USB devices # Find all connected USB devices
# the find() fnc returns a generator # the find() fnc returns a generator
devices = list( devices = list(
usb.core.find( usb.core.find(find_all=True, custom_match=_FindClass(self.app, 7))
find_all=True,
custom_match=_FindClass(self.app,7)
)
) )
if devices: if devices:
@@ -60,15 +57,15 @@ class Printers:
if waiting_time_for_printer <= 0: if waiting_time_for_printer <= 0:
self.app.logger.warning( self.app.logger.warning(
"No USB devices of class 7 ( printers ) found or pyusb could not access the bus." "No USB devices of class 7 ( printers ) found or pyusb could not access the bus."
) )
raise RuntimeError( raise RuntimeError(
"No USB devices of class 7 ( printers ) found or pyusb could not access the bus." "No USB devices of class 7 ( printers ) found or pyusb could not access the bus."
) )
self.app.logger.warning( self.app.logger.warning(
"No printers found; waiting for a printer to connect..." "No printers found; waiting for a printer to connect..."
) )
time.sleep(1) time.sleep(1)
waiting_time_for_printer -= 1 waiting_time_for_printer -= 1
@@ -120,10 +117,12 @@ class Printers:
self.app.logger.debug("Trying to create a new BROTHER printer") self.app.logger.debug("Trying to create a new BROTHER printer")
brother_printer = BrotherPrinter( brother_printer = BrotherPrinter(
self.app, vendor_id=dev.idVendor, device_id=dev.idProduct) self.app, vendor_id=dev.idVendor, device_id=dev.idProduct
)
except Exception as e: except Exception as e:
self.app.logger.error( self.app.logger.error(
"Could not create a %s printer class with %s:%s" , product, "Could not create a %s printer class with %s:%s",
product,
dev.idVendor, dev.idVendor,
dev.idProduct, dev.idProduct,
) )
@@ -131,12 +130,14 @@ class Printers:
# If the object creation is successfull, we add it to the list of Printers # If the object creation is successfull, we add it to the list of Printers
printers.add(brother_printer) printers.add(brother_printer)
self.app.logger.debug("Found a %s printer" , manufacturer) self.app.logger.debug("Found a %s printer", manufacturer)
self.app.logger.debug("Found %s printers" , len(printers)) self.app.logger.debug("Found %s printers", len(printers))
if len(printers) < 1: if len(printers) < 1:
self.app.logger.warning("Not printers found ! Please plug in a Printer and restart the program.") self.app.logger.warning(
"Not printers found ! Please plug in a Printer and restart the program."
)
raise RuntimeError("No printers found") raise RuntimeError("No printers found")
return printers return printers
@@ -163,26 +164,32 @@ class Printers:
"""Return the current list of printers""" """Return the current list of printers"""
return self.printers return self.printers
class _FindClass: class _FindClass:
""" """
Use by usb.core to modify the way USB devices are found Use by usb.core to modify the way USB devices are found
Taken from pyUSB documentation on Github Taken from pyUSB documentation on Github
""" """
def __init__(self, app, class_): def __init__(self, app, class_):
self._class = class_ self._class = class_
self.app = app self.app = app
def __call__(self, device): def __call__(self, device):
# first, let's check the device # first, let's check the device
self.app.logger.debug("Found a USB device of class %s", str(device.bDeviceClass)) self.app.logger.debug(
"Found a USB device of class %s", str(device.bDeviceClass)
)
if device.bDeviceClass == self._class: if device.bDeviceClass == self._class:
return True return True
# ok, transverse all devices to find an # ok, transverse all devices to find an
# interface that matches our class # interface that matches our class
for configuration in device: for configuration in device:
# Every device can have one or more configuration, # Every device can have one or more configuration,
interface = usb.util.find_descriptor(configuration, bInterfaceClass=self._class) interface = usb.util.find_descriptor(
# each config can have several interfaces configuration, bInterfaceClass=self._class
)
# each config can have several interfaces
if interface is not None: if interface is not None:
return True return True

View File

@@ -20,6 +20,7 @@ class PrintWorker(threading.Thread):
If a print fails, it's not retried, but will be added to a list of completed If a print fails, it's not retried, but will be added to a list of completed
tasks. TODO : Change that tasks. TODO : Change that
""" """
def __init__(self, app, print_queue, printers_pool): def __init__(self, app, print_queue, printers_pool):
super().__init__(daemon=True) super().__init__(daemon=True)
self.app = app self.app = app
@@ -51,12 +52,11 @@ class PrintWorker(threading.Thread):
self._printer_index = (index + 1) % len(self.printers_obj) self._printer_index = (index + 1) % len(self.printers_obj)
return printer return printer
def run(self): def run(self):
"""Background thread that processes queue items""" """Background thread that processes queue items"""
self.app.logger.debug("Worker %s started working.", threading.get_ident()) self.app.logger.debug("Worker %s started working.", threading.get_ident())
self.app.logger.debug("Current threads : %s" , threading.active_count()) self.app.logger.debug("Current threads : %s", threading.active_count())
self.app.logger.debug("Threads actives : %s " , threading.enumerate()) self.app.logger.debug("Threads actives : %s ", threading.enumerate())
while True: while True:
@@ -73,7 +73,9 @@ class PrintWorker(threading.Thread):
# If we do not have a printer, we try to find one # If we do not have a printer, we try to find one
while self.running and self.printer is None: while self.running and self.printer is None:
self.app.logger.debug("Trying to find a available printer for the worker.") self.app.logger.debug(
"Trying to find a available printer for the worker."
)
self.printer = self._acquire_available_printer() self.printer = self._acquire_available_printer()
self.app.logger.debug( self.app.logger.debug(
"The worker got a %s printer and it's %s", "The worker got a %s printer and it's %s",
@@ -81,14 +83,11 @@ class PrintWorker(threading.Thread):
"Ready" if self.printer.ready else "Not ready", "Ready" if self.printer.ready else "Not ready",
) )
if self.printer is None: if self.printer is None:
time.sleep(1) time.sleep(1)
self.printer.use_printer() self.printer.use_printer()
# If the printer is not ready, we wait for it to become ready. # If the printer is not ready, we wait for it to become ready.
while not self.printer.ready: while not self.printer.ready:
self.app.debug("Waiting for our printer to become ready...") self.app.debug("Waiting for our printer to become ready...")
@@ -115,7 +114,9 @@ class PrintWorker(threading.Thread):
if task: if task:
try: try:
self.app.logger.info("Got a new task") self.app.logger.info("Got a new task")
self.app.logger.debug("Got task %s %s", task.task_type, task.task_id) self.app.logger.debug(
"Got task %s %s", task.task_type, task.task_id
)
task.status = "processing" task.status = "processing"
print_data = task.get_print_data() print_data = task.get_print_data()
@@ -132,7 +133,7 @@ class PrintWorker(threading.Thread):
task.status = "completed" task.status = "completed"
self.print_queue.mark_completed(task.task_id, "completed") self.print_queue.mark_completed(task.task_id, "completed")
self.app.logger.debug( self.app.logger.debug(
"Finished printing task %s " , task.task_id "Finished printing task %s ", task.task_id
) )
self.state = "idle" self.state = "idle"
@@ -141,7 +142,7 @@ class PrintWorker(threading.Thread):
self.state = "idle" self.state = "idle"
self.print_queue.mark_completed(task.task_id, "failed") self.print_queue.mark_completed(task.task_id, "failed")
self.app.logger.error( self.app.logger.error(
"Could not print task %s because %s " , task.task_id, str(e) "Could not print task %s because %s ", task.task_id, str(e)
) )
else: else: