1
0
mirror of https://github.com/python-escpos/python-escpos synced 2025-12-02 09:43:30 +00:00

Separate method open() and constructor, enhance consistency between connectors. (#584)

* Add self-open mechanism
* self-open mechanism through the 'device' property
* Separate open() and store connection in 'device'
* Restore device status to False on close()
* Add default value to all params + type annotations
* Add generic DeviceNotFoundError exception
* Update USBNotFoundError return code
* Enhance connectors consistency
* Fix LP printer stall
* Fix LP waste of paper due to auto-flush + flush on close
* Move platform dependent printers' guard to init

---------

Co-authored-by: Patrick Kanzler <4189642+patkan@users.noreply.github.com>
This commit is contained in:
Benito López
2023-10-16 11:36:07 +02:00
committed by GitHub
parent 3a8af8a6f5
commit a00b98937b
10 changed files with 537 additions and 179 deletions

View File

@@ -8,9 +8,12 @@
:license: MIT
"""
import logging
import socket
from typing import Literal, Optional, Union
from ..escpos import Escpos
from ..exceptions import DeviceNotFoundError
def is_usable() -> bool:
@@ -54,7 +57,14 @@ class Network(Escpos):
"""
return is_usable()
def __init__(self, host, port=9100, timeout=60, *args, **kwargs):
def __init__(
self,
host: str = "",
port: int = 9100,
timeout: Union[int, float] = 60,
*args,
**kwargs,
):
"""Initialize network printer.
:param host: Printer's host name or IP address
@@ -65,16 +75,40 @@ class Network(Escpos):
self.host = host
self.port = port
self.timeout = timeout
self.open()
def open(self):
"""Open TCP socket with ``socket``-library and set it as escpos device."""
self.device = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.device.settimeout(self.timeout)
self.device.connect((self.host, self.port))
self._device: Union[Literal[False], Literal[None], socket.socket] = False
if self.device is None:
print("Could not open socket for {0}".format(self.host))
def open(self, raise_not_found: bool = True) -> None:
"""Open TCP socket with ``socket``-library and set it as escpos device.
By default raise an exception if device is not found.
:param raise_not_found: Default True.
False to log error but do not raise exception.
:raises: :py:exc:`~escpos.exceptions.DeviceNotFoundError`
"""
if self._device:
self.close()
try:
# Open device
self.device: Optional[socket.socket] = socket.socket(
socket.AF_INET, socket.SOCK_STREAM
)
self.device.settimeout(self.timeout)
self.device.connect((self.host, self.port))
except OSError as e:
# Raise exception or log error and cancel
self.device = None
if raise_not_found:
raise DeviceNotFoundError(
f"Could not open socket for {self.host}:\n{e}"
)
else:
logging.error("Network device %s not found", self.host)
return
logging.info("Network printer enabled")
def _raw(self, msg):
"""Print any command sent in raw format.
@@ -88,11 +122,14 @@ class Network(Escpos):
"""Read data from the TCP socket."""
return self.device.recv(16)
def close(self):
def close(self) -> None:
"""Close TCP connection."""
if self.device is not None:
try:
self.device.shutdown(socket.SHUT_RDWR)
except socket.error:
pass
self.device.close()
if not self._device:
return
logging.info("Closing Network connection to printer %s", self.host)
try:
self._device.shutdown(socket.SHUT_RDWR)
except socket.error:
pass
self._device.close()
self._device = False