added check for usability

This commit is contained in:
Patrick Kanzler 2023-08-17 00:48:28 +02:00
parent 3643a22a10
commit e4424dca00
8 changed files with 161 additions and 56 deletions

View File

@ -26,6 +26,13 @@ except ImportError:
# TODO: dev build mode that let's the wrapper bypass?
def is_usable():
"""Indicate whether this component can be used due to dependencies."""
usable = False
if not _DEP_PYCUPS:
usable = True
return usable
def dependency_pycups(func):
"""Indicate dependency on pycups."""
@ -33,7 +40,7 @@ def dependency_pycups(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
"""Throw a RuntimeError if pycups is not imported."""
if not _DEP_PYCUPS:
if is_usable():
raise RuntimeError(
"Printing with PyCups requires the pycups library to"
"be installed. Please refer to the documentation on"

View File

@ -11,6 +11,11 @@
from ..escpos import Escpos
def is_usable():
"""Indicate whether this component can be used due to dependencies."""
return True
class Dummy(Escpos):
"""Dummy printer.

View File

@ -11,6 +11,11 @@
from ..escpos import Escpos
def is_usable():
"""Indicate whether this component can be used due to dependencies."""
return True
class File(Escpos):
"""Generic file printer.

View File

@ -16,13 +16,21 @@ import sys
from ..escpos import Escpos
def is_usable():
"""Indicate whether this component can be used due to dependencies."""
usable = False
if not sys.platform.startswith("win"):
usable = True
return usable
def dependency_linux_lp(func):
"""Indicate dependency on non Windows."""
@functools.wraps(func)
def wrapper(*args, **kwargs):
"""Throw a RuntimeError if not on a non-Windows system."""
if not sys.platform.startswith("win"):
if is_usable():
raise RuntimeError(
"This printer driver depends on LP which is not"
"available on Windows systems."

View File

@ -13,6 +13,11 @@ import socket
from ..escpos import Escpos
def is_usable():
"""Indicate whether this component can be used due to dependencies."""
return True
class Network(Escpos):
"""Network printer.

View File

@ -24,13 +24,21 @@ except ImportError:
pass
def is_usable():
"""Indicate whether this component can be used due to dependencies."""
usable = False
if not _DEP_PYSERIAL:
usable = True
return usable
def dependency_pyserial(func):
"""Indicate dependency on pyserial."""
@functools.wraps(func)
def wrapper(*args, **kwargs):
"""Throw a RuntimeError if pyserial not installed."""
if not _DEP_PYSERIAL:
if is_usable():
raise RuntimeError(
"Printing with Serial requires the pyserial library to"
"be installed. Please refer to the documentation on"

View File

@ -7,13 +7,47 @@
:copyright: Copyright (c) 2012-2023 Bashlinux and python-escpos
:license: MIT
"""
import usb.core
import usb.util
import functools
from ..escpos import Escpos
from ..exceptions import USBNotFoundError
#: keeps track if the usb dependency could be loaded (:py:class:`escpos.printer.Usb`)
_DEP_USB = False
try:
import usb.core
import usb.util
_DEP_USB = True
except ImportError:
pass
def is_usable():
"""Indicate whether this component can be used due to dependencies."""
usable = False
if not _DEP_USB:
usable = True
return usable
def dependency_usb(func):
"""Indicate dependency on usb."""
@functools.wraps(func)
def wrapper(*args, **kwargs):
"""Throw a RuntimeError if usb not installed."""
if is_usable():
raise RuntimeError(
"Printing with USB connection requires a usb library to"
"be installed. Please refer to the documentation on"
"what to install and install the dependencies for USB."
)
return func(*args, **kwargs)
return wrapper
class Usb(Escpos):
"""USB printer.
@ -37,7 +71,7 @@ class Usb(Escpos):
out_ep=0x01,
*args,
**kwargs
): # noqa: N803
):
"""Initialize USB printer.
:param idVendor: Vendor ID
@ -59,6 +93,7 @@ class Usb(Escpos):
usb_args["idProduct"] = idProduct
self.open(usb_args)
@dependency_usb
def open(self, usb_args):
"""Search device on USB tree and set it as escpos device.
@ -110,6 +145,7 @@ class Usb(Escpos):
"""Read a data buffer and return it to the caller."""
return self.device.read(self.in_ep, 16)
@dependency_usb
def close(self):
"""Release USB interface."""
if self.device:

View File

@ -8,68 +8,99 @@
:license: MIT
"""
import functools
from ..escpos import Escpos
_WIN32PRINT = False
#: keeps track if the win32print dependency could be loaded (:py:class:`escpos.printer.Win32Raw`)
_DEP_WIN32PRINT = False
try:
import win32print
_WIN32PRINT = True
_DEP_WIN32PRINT = True
except ImportError:
pass
if _WIN32PRINT:
def is_usable():
"""Indicate whether this component can be used due to dependencies."""
usable = False
if not _DEP_WIN32PRINT:
usable = True
return usable
class Win32Raw(Escpos):
"""Printer binding for win32 API.
Uses the module pywin32 for printing.
def dependency_win32print(func):
"""Indicate dependency on win32print."""
inheritance:
.. inheritance-diagram:: escpos.printer.Win32Raw
:parts: 1
"""
def __init__(self, printer_name=None, *args, **kwargs):
"""Initialize default printer."""
Escpos.__init__(self, *args, **kwargs)
if printer_name is not None:
self.printer_name = printer_name
else:
self.printer_name = win32print.GetDefaultPrinter()
self.hPrinter = None
self.open()
def open(self, job_name="python-escpos"):
"""Open connection to default printer."""
if self.printer_name is None:
raise Exception("Printer not found")
self.hPrinter = win32print.OpenPrinter(self.printer_name)
self.current_job = win32print.StartDocPrinter(
self.hPrinter, 1, (job_name, None, "RAW")
@functools.wraps(func)
def wrapper(*args, **kwargs):
"""Throw a RuntimeError if win32print not installed."""
if is_usable():
raise RuntimeError(
"Printing with Win32Raw requires a win32print library to"
"be installed. Please refer to the documentation on"
"what to install and install the dependencies for win32print."
)
win32print.StartPagePrinter(self.hPrinter)
return func(*args, **kwargs)
def close(self):
"""Close connection to default printer."""
if not self.hPrinter:
return
win32print.EndPagePrinter(self.hPrinter)
win32print.EndDocPrinter(self.hPrinter)
win32print.ClosePrinter(self.hPrinter)
self.hPrinter = None
return wrapper
def _raw(self, msg):
"""Print any command sent in raw format.
:param msg: arbitrary code to be printed
:type msg: bytes
"""
if self.printer_name is None:
raise Exception("Printer not found")
if self.hPrinter is None:
raise Exception("Printer job not opened")
win32print.WritePrinter(self.hPrinter, msg)
class Win32Raw(Escpos):
"""Printer binding for win32 API.
Uses the module pywin32 for printing.
inheritance:
.. inheritance-diagram:: escpos.printer.Win32Raw
:parts: 1
"""
@dependency_win32print
def __init__(self, printer_name=None, *args, **kwargs):
"""Initialize default printer."""
Escpos.__init__(self, *args, **kwargs)
if printer_name is not None:
self.printer_name = printer_name
else:
self.printer_name = win32print.GetDefaultPrinter()
self.hPrinter = None
self.open()
@dependency_win32print
def open(self, job_name="python-escpos"):
"""Open connection to default printer."""
if self.printer_name is None:
raise Exception("Printer not found")
self.hPrinter = win32print.OpenPrinter(self.printer_name)
self.current_job = win32print.StartDocPrinter(
self.hPrinter, 1, (job_name, None, "RAW")
)
win32print.StartPagePrinter(self.hPrinter)
@dependency_win32print
def close(self):
"""Close connection to default printer."""
if not self.hPrinter:
return
win32print.EndPagePrinter(self.hPrinter)
win32print.EndDocPrinter(self.hPrinter)
win32print.ClosePrinter(self.hPrinter)
self.hPrinter = None
@dependency_win32print
def _raw(self, msg):
"""Print any command sent in raw format.
:param msg: arbitrary code to be printed
:type msg: bytes
"""
if self.printer_name is None:
raise Exception("Printer not found")
if self.hPrinter is None:
raise Exception("Printer job not opened")
win32print.WritePrinter(self.hPrinter, msg)