#!/usr/bin/python
# -*- coding: utf-8 -*-
"""This module contains the implementation of the File printer driver.
:author: python-escpos developers
:organization: `python-escpos <https://github.com/python-escpos>`_
:copyright: Copyright (c) 2012-2023 Bashlinux and python-escpos
:license: MIT
"""
import logging
from typing import IO, Literal, Optional, Union
from ..escpos import Escpos
from ..exceptions import DeviceNotFoundError
def is_usable() -> bool:
"""Indicate whether this component can be used due to dependencies."""
return True
[docs]
class File(Escpos):
"""Generic file printer.
This class is used for parallel port printer or other printers that are directly attached to the file system.
Note that you should stay away from using USB-to-Parallel-Adapter since they are unreliable
and produce arbitrary errors.
inheritance:
.. inheritance-diagram:: escpos.printer.File
:parts: 1
"""
[docs]
@staticmethod
def is_usable() -> bool:
"""Indicate whether this printer class is usable.
Will return True if dependencies are available.
Will return False if not.
"""
return is_usable()
[docs]
def __init__(self, devfile: str = "", auto_flush: bool = True, *args, **kwargs):
"""Initialize file printer with device file.
:param devfile: Device file under dev file system
:param auto_flush: automatically call flush after every call of _raw()
"""
Escpos.__init__(self, *args, **kwargs)
self.devfile = devfile
self.auto_flush = auto_flush
self._device: Union[Literal[False], Literal[None], IO[bytes]] = False
[docs]
def open(self, raise_not_found: bool = True) -> None:
"""Open system file.
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[IO[bytes]] = open(self.devfile, "wb")
except OSError as e:
# Raise exception or log error and cancel
self.device = None
if raise_not_found:
raise DeviceNotFoundError(
f"Could not open the specified file {self.devfile}:\n{e}"
)
else:
logging.error("File printer %s not found", self.devfile)
return
logging.info("File printer enabled")
[docs]
def flush(self) -> None:
"""Flush printing content."""
if self.device:
self.device.flush()
def _raw(self, msg: bytes) -> None:
"""Print any command sent in raw format.
:param msg: arbitrary code to be printed
"""
assert self.device
self.device.write(msg)
if self.auto_flush:
self.flush()
[docs]
def close(self) -> None:
"""Close system file."""
if not self._device:
return
logging.info("Closing File connection to printer %s", self.devfile)
if not self.auto_flush:
self.flush()
self._device.close()
self._device = False