diff --git a/src/printer.py b/src/printer.py index 8405c4c..f1acf62 100644 --- a/src/printer.py +++ b/src/printer.py @@ -107,7 +107,7 @@ class EscPosPrinter(Printer): Create a new ESC/POS based printer. """ - def __init__(self, app, vendor_id, device_id): + def __init__(self, app, vendor_id, device_id, configuration_file): """ Create a connexion to a ESC/POS Printer via USB, Making sure the printer is alive, @@ -123,7 +123,7 @@ class EscPosPrinter(Printer): try: # This also calls open(), which we need to close() # or else the device will appear as busy. - p = escpos.printer.Usb(self.vendor_id, self.device_id, 0, profile="TM-P80") + p = escpos.printer.Usb(self.vendor_id, self.device_id, 0, profile=configuration_file["profile"]) except escpos.exceptions.DeviceNotFoundError as e: self.app.logger.error( "The USB device is not plugged in : %s", @@ -140,9 +140,21 @@ class EscPosPrinter(Printer): except Exception as e: raise e + self.printer_info = PrinterInfo( + identifier=configuration_file["profile"], + backend="pyusb", + model=configuration_file["profile"], + protocol="ESC/POS", + vendor_id=self.vendor_id, + product_id=self.device_id, + serial_number="", + label_type=configuration_file["label_type"], + ) + # Setting up the printing options. + # TODO : Expose this to the web interface p.set( - align="center", + align=configuration_file["align_text"], font="a", bold=False, underline=0, @@ -287,22 +299,22 @@ class EscPosPrinter(Printer): except Exception as e: self.app.logger.error(str(e)) raise RuntimeError("Could not print the picture") from e - finally: - try: - os.remove(path) - os.remove(processed_path) - self.app.logger.debug("Removed image : " + str(processed_path)) - self.app.logger.debug("Removed image : " + str(path)) - except OSError as e: - raise e + # finally: + # try: + # os.remove(path) + # os.remove(processed_path) + # self.app.logger.debug("Removed image : " + str(processed_path)) + # self.app.logger.debug("Removed image : " + str(path)) + # except OSError as e: + # raise e - try: - self.printer.close() - except Exception as e: - self.app.logger.error( - "Could not close the printer connexion %s", str(e) - ) - raise RuntimeError("Could not close the printer connexion. ") from e + try: + self.printer.close() + except Exception as e: + self.app.logger.error( + "Could not close the printer connexion %s", str(e) + ) + raise RuntimeError("Could not close the printer connexion. ") from e self.app.logger.info("Printed a picture") self.ready = True @@ -391,7 +403,7 @@ class BrotherPrinter(Printer): Manages connexion and capabilities of a BrotherQL Printer """ - def __init__(self, app, vendor_id, device_id): + def __init__(self, app, vendor_id, device_id, configuration_file): super().__init__(app, vendor_id, device_id, printer_type=PrinterType.BROTHER) self.printer = None @@ -445,7 +457,7 @@ class BrotherPrinter(Printer): vendor_id=vendor_id, product_id=self.device_id, serial_number=serial_number, - label_type="62", + label_type=configuration_file["label_type"], # TODO: Implement automatic label type detection : https://framagit.org/stickoeur/diagnostickoeur/-/blob/no-masters/printit.py?ref_type=heads#L239 ) self.app.logger.debug("Created a Brother printer !") self.ready = True @@ -461,10 +473,11 @@ class BrotherPrinter(Printer): self._print_img(text_to_image(msg)) self._print_img(text_to_image(signature)) - def _print_img(self, data, signature="", process=False): + def _print_img(self, data, signature="", process=False,): """ Print a raster image via a Brother QL printer """ + self.app.logger.debug("Printing an image %s via Brother printer", data) if process: try: self.app.logger.debug("Proccessing the image") @@ -477,6 +490,7 @@ class BrotherPrinter(Printer): else: processed_path = data self.app.logger.warning("Not proccessing the image") + try: selected_backend = guess_backend(self.printer_info.identifier) BACKEND_CLASS = backend_factory(selected_backend)["backend_class"] @@ -490,39 +504,95 @@ class BrotherPrinter(Printer): try: im = Image.open(processed_path) qlr = BrotherQLRaster(self.printer_info.model) - create_label(qlr, im, self.printer_info.label_type, cut=False, dither=True) + # 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 + # be = BACKEND_CLASS(BACKEND_STRING_DESCR) + # be.write(qlr.data) + # be.dispose() + # del be + + instructions = convert( + qlr=qlr, + images=[im], + label=self.printer_info.label_type, + dither=True, + compress=False, + dpi_600=False, + cut=False, + ) + + success = send( + instructions=instructions, + printer_identifier=BACKEND_STRING_DESCR, + backend_identifier="pyusb", + blocking=False + ) + + self.app.logger.debug(str(success)) + self.app.logger.debug("Printed image") + time.sleep(2) + + except usb.core.USBError as e: + if "timeout error" in str(e): + self.app.logger.error("USB Timeout Error %s", str(e) ) except Exception as e: raise e - finally: - try: - os.remove(processed_path) - self.app.logger.debug("Removed image : " + str(processed_path)) - except OSError as e: - raise e + # finally: + # try: + # os.remove(processed_path) + # self.app.logger.debug("Removed image : " + str(processed_path)) + # except OSError as e: + # raise e if signature != "": + self.app.logger.debug("Printing signature for the image %s", data) try: - im = Image.open(text_to_image(signature)) + signature_file = text_to_image(signature) + im = Image.open(signature_file) qlr = BrotherQLRaster(self.printer_info.model) - create_label( - qlr, im, self.printer_info.label_type, cut=False, dither=True - ) + # 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 + # be = BACKEND_CLASS(BACKEND_STRING_DESCR) + # be.write(qlr.data) + # be.dispose() + # del be + instructions = convert( + qlr=qlr, + images=[signature_file], + label=self.printer_info.label_type, + dither=True, + compress=False, + dpi_600=False, + cut=False, + ) + + + success = send( + instructions=instructions, + printer_identifier=BACKEND_STRING_DESCR, + backend_identifier="pyusb", + blocking=False + ) + self.app.logger.debug(str(success)) + self.app.logger.debug("Printed signature") + time.sleep(2) + + except Exception as e: raise e + finally: + try: + # os.remove(signature_file) + self.app.logger.debug("Removed image : " + str(signature_file)) + except OSError as e: + raise e def _cut(self): + self.app.logger.debug("Cutting via Brother Printer") try: selected_backend = guess_backend(self.printer_info.identifier) BACKEND_CLASS = backend_factory(selected_backend)["backend_class"] @@ -546,12 +616,14 @@ class BrotherPrinter(Printer): be.write(qlr.data) be.dispose() del be + self.app.logger.debug("Finished cutting via Brother Printer") except Exception as e: raise e + def _qr(self): # This should not be reached by a print on a BrotherQL - raise NotImplementedError + raise NotImplementedError() def print_task(self, task_type, data): """Execute actual print based on task type""" diff --git a/src/printers.py b/src/printers.py index e45ba0d..aaa4a01 100644 --- a/src/printers.py +++ b/src/printers.py @@ -18,11 +18,12 @@ class Printers: Finds and creates a set of Printer that can be used by the Workers to print. """ - def __init__(self, app): + def __init__(self, app, configuration_file): """ Discovers printers connected to the computer """ self.app = app + self.configuration_file = configuration_file self.printers = list(self._discover_printers()) self._lock = threading.Lock() @@ -42,8 +43,7 @@ class Printers: printers = set() - # TODO : this could go in the config ? - waiting_time_for_printer = 5 + waiting_time_for_printer = self.configuration_file["printer"]["waiting_time"] while True: # Find all connected USB devices @@ -97,9 +97,7 @@ class Printers: self.app.logger.debug("Trying to create a new EPSON printer") prid = dev.idProduct vendir = dev.idVendor - escpos_printer = EscPosPrinter( - self.app, vendor_id=vendir, device_id=prid - ) + escpos_printer = EscPosPrinter(self.app, vendir, prid, self.configuration_file["printer"]["epson"] ) except Exception as e: raise e @@ -111,9 +109,7 @@ class Printers: # We create a new BrotherPrinter() self.app.logger.debug("Trying to create a new BROTHER printer") - brother_printer = BrotherPrinter( - self.app, vendor_id=dev.idVendor, device_id=dev.idProduct - ) + brother_printer = BrotherPrinter(self.app, dev.idVendor, dev.idProduct, self.configuration_file["printer"]["brother"] ) except Exception as e: self.app.logger.error( "Could not create a %s printer class with %s:%s", @@ -148,6 +144,8 @@ class Printers: return None with self._lock: + # So don't always look at the first printer available if need be + # this allows for a round-robin lookup for offset in range(len(printers)): index = (start_index + offset) % len(printers) printer = printers[index] @@ -158,9 +156,11 @@ class Printers: return None - def printers_info(self): - """Return the current list of printers""" - return self.printers + # def printers_info(self): + # """Return the current list of printers""" + # printers_info_list = {} + # for i in self.printers + # return self.printers class _FindClass: