formatting

This commit is contained in:
Patrick Kanzler 2023-08-10 23:29:26 +02:00
parent b1011a1ee5
commit 1b4230fdd9
17 changed files with 128 additions and 104 deletions

View File

@ -1,5 +1,4 @@
""" Example for printing barcodes. """Example for printing barcodes."""
"""
from escpos.printer import Usb from escpos.printer import Usb
# Adapt to your needs # Adapt to your needs

View File

@ -1,5 +1,4 @@
"""Prints code page tables. """Prints code page tables."""
"""
import sys import sys
@ -19,6 +18,7 @@ from escpos.constants import (
def main(): def main():
"""Init printer and print codepage tables."""
dummy = printer.Dummy() dummy = printer.Dummy()
dummy.hw("init") dummy.hw("init")
@ -35,6 +35,7 @@ def main():
def print_codepage(printer, codepage): def print_codepage(printer, codepage):
"""Print a codepage."""
if codepage.isdigit(): if codepage.isdigit():
codepage = int(codepage) codepage = int(codepage)
printer._raw(CODEPAGE_CHANGE + six.int2byte(codepage)) printer._raw(CODEPAGE_CHANGE + six.int2byte(codepage))

View File

@ -1,3 +1,4 @@
"""Example for a flask application."""
from flask import Flask from flask import Flask
from escpos.printer import CupsPrinter from escpos.printer import CupsPrinter
@ -8,6 +9,7 @@ app = Flask(__name__)
@app.route("/", methods=["GET"]) @app.route("/", methods=["GET"])
def do_print(): def do_print():
"""Print."""
# p = Usb(0x04b8, 0x0e28, 0) # p = Usb(0x04b8, 0x0e28, 0)
p = CupsPrinter(host="localhost", port=631, printer_name="TM-T20III") p = CupsPrinter(host="localhost", port=631, printer_name="TM-T20III")
p.text("Hello World\n") p.text("Hello World\n")

View File

@ -1,9 +1,11 @@
"""Print example QR codes."""
import sys import sys
from escpos.printer import Usb from escpos.printer import Usb
def usage(): def usage():
"""Print information on usage."""
print("usage: qr_code.py <content>") print("usage: qr_code.py <content>")

View File

@ -1,3 +1,4 @@
"""Example file for software barcodes."""
from escpos.printer import Usb from escpos.printer import Usb
# Adapt to your needs # Adapt to your needs

View File

@ -1,16 +1,17 @@
#!/usr/bin/python #!/usr/bin/python
"""Weather forecast example.
Adapted script from Adafruit
Weather forecast for Raspberry Pi w/Adafruit Mini Thermal Printer.
Retrieves data from DarkSky.net's API, prints current conditions and
forecasts for next two days.
Weather example using nice bitmaps.
Written by Adafruit Industries. MIT license.
Adapted and enhanced for escpos library by MrWunderbar666
# Adapted script from Adafruit Icons taken from https://adamwhitcroft.com/climacons/
# Weather forecast for Raspberry Pi w/Adafruit Mini Thermal Printer. Check out his github: https://github.com/AdamWhitcroft/climacons
# Retrieves data from DarkSky.net's API, prints current conditions and """
# forecasts for next two days.
# Weather example using nice bitmaps.
# Written by Adafruit Industries. MIT license.
# Adapted and enhanced for escpos library by MrWunderbar666
# Icons taken from https://adamwhitcroft.com/climacons/
# Check out his github: https://github.com/AdamWhitcroft/climacons
import calendar import calendar
@ -22,7 +23,7 @@ from datetime import datetime
from escpos.printer import Usb from escpos.printer import Usb
""" Setting up the main pathing """ """Set up the main pathing."""
this_dir, this_filename = os.path.split(__file__) this_dir, this_filename = os.path.split(__file__)
GRAPHICS_PATH = os.path.join(this_dir, "graphics/climacons/") GRAPHICS_PATH = os.path.join(this_dir, "graphics/climacons/")
@ -38,13 +39,14 @@ LONG = "114.189945" # Your Location
def forecast_icon(idx): def forecast_icon(idx):
"""Get right icon for forecast."""
icon = data["daily"]["data"][idx]["icon"] icon = data["daily"]["data"][idx]["icon"]
image = GRAPHICS_PATH + icon + ".png" image = GRAPHICS_PATH + icon + ".png"
return image return image
# Dumps one forecast line to the printer
def forecast(idx): def forecast(idx):
"""Dump one forecast line to the printer."""
date = datetime.fromtimestamp(int(data["daily"]["data"][idx]["time"])) date = datetime.fromtimestamp(int(data["daily"]["data"][idx]["time"]))
day = calendar.day_name[date.weekday()] day = calendar.day_name[date.weekday()]
lo = data["daily"]["data"][idx]["temperatureMin"] lo = data["daily"]["data"][idx]["temperatureMin"]
@ -73,6 +75,7 @@ def forecast(idx):
def icon(): def icon():
"""Get icon."""
icon = data["currently"]["icon"] icon = data["currently"]["icon"]
image = GRAPHICS_PATH + icon + ".png" image = GRAPHICS_PATH + icon + ".png"
return image return image

View File

@ -1,4 +1,5 @@
#!/usr/bin/env python #!/usr/bin/env python
"""Setup script for python package."""
import os import os
import sys import sys
@ -14,14 +15,18 @@ sys.path.insert(0, src_dir)
def read(fname): def read(fname):
"""read file from same path as setup.py""" """Read file from same path as setup.py."""
return open(os.path.join(os.path.dirname(__file__), fname)).read() return open(os.path.join(os.path.dirname(__file__), fname)).read()
setuptools_scm_template = """\ setuptools_scm_template = """\
# coding: utf-8 #!/usr/bin/python
# file generated by setuptools_scm # -*- coding: utf-8 -*-
# don't change, don't track in version control \"\"\"Version identifier.
file generated by setuptools_scm
don't change, don't track in version control
\"\"\"
version = '{version}' version = '{version}'
""" """

View File

@ -1,7 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
""" """python-escpos enables you to manipulate escpos-printers."""
python-escpos enables you to manipulate escpos-printers
"""
__all__ = ["constants", "escpos", "exceptions", "printer"] __all__ = ["constants", "escpos", "exceptions", "printer"]

View File

@ -1,3 +1,4 @@
"""Handler for capabilities data."""
import atexit import atexit
import logging import logging
import pickle import pickle
@ -58,9 +59,7 @@ PROFILES: Dict[str, Any] = CAPABILITIES["profiles"]
class NotSupported(Exception): class NotSupported(Exception):
"""Raised if a requested feature is not supported by the """Raised if a requested feature is not supported by the printer profile."""
printer profile.
"""
pass pass

View File

@ -1,6 +1,6 @@
#!/usr/bin/env python #!/usr/bin/env python
# PYTHON_ARGCOMPLETE_OK # PYTHON_ARGCOMPLETE_OK
""" CLI """CLI.
This module acts as a command line interface for python-escpos. It mirrors This module acts as a command line interface for python-escpos. It mirrors
closely the available ESCPOS commands while adding a couple extra ones for convenience. closely the available ESCPOS commands while adding a couple extra ones for convenience.

View File

@ -14,7 +14,9 @@ class CodePageManager:
@staticmethod @staticmethod
def get_encoding_name(encoding): def get_encoding_name(encoding):
# TODO resolve the encoding alias """Get encoding name.
.. todo:: Resolve the encoding alias."""
return encoding.upper() return encoding.upper()
def get_encoding(self, encoding): def get_encoding(self, encoding):

View File

@ -403,7 +403,8 @@ class Escpos(object):
@staticmethod @staticmethod
def check_barcode(bc, code): def check_barcode(bc, code):
""" """Check if barcode is OK.
This method checks if the barcode is in the proper format. This method checks if the barcode is in the proper format.
The validation concerns the barcode length and the set of characters, but won't compute/validate any checksum. The validation concerns the barcode length and the set of characters, but won't compute/validate any checksum.
The full set of requirement for each barcode type is available in the ESC/POS documentation. The full set of requirement for each barcode type is available in the ESC/POS documentation.
@ -582,7 +583,7 @@ class Escpos(object):
function_type=None, function_type=None,
check=True, check=True,
): ):
"""Print Barcode """Print Barcode.
This method allows to print barcodes. The rendering of the barcode is done by the printer and therefore has to This method allows to print barcodes. The rendering of the barcode is done by the printer and therefore has to
be supported by the unit. By default, this method will check whether your barcode text is correct, that is be supported by the unit. By default, this method will check whether your barcode text is correct, that is
@ -886,7 +887,7 @@ class Escpos(object):
double_height=False, double_height=False,
custom_size=False, custom_size=False,
): ):
"""Set text properties by sending them to the printer """Set text properties by sending them to the printer.
:param align: horizontal position for text, possible values are: :param align: horizontal position for text, possible values are:

View File

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
""" ESC/POS Exceptions classes """ESC/POS Exceptions classes.
Result/Exit codes: Result/Exit codes:

View File

@ -1,4 +1,4 @@
""" Image format handling class """Image format handling class.
This module contains the image format handler :py:class:`EscposImage`. This module contains the image format handler :py:class:`EscposImage`.
@ -23,8 +23,7 @@ class EscposImage(object):
""" """
def __init__(self, img_source): def __init__(self, img_source):
""" """Load in an image.
Load in an image
:param img_source: PIL.Image, or filename to load one from. :param img_source: PIL.Image, or filename to load one from.
""" """
@ -50,30 +49,23 @@ class EscposImage(object):
@property @property
def width(self): def width(self):
""" """Return width of image in pixels."""
Width of image in pixels
"""
width_pixels, _ = self._im.size width_pixels, _ = self._im.size
return width_pixels return width_pixels
@property @property
def width_bytes(self): def width_bytes(self):
""" """Return width of image if you use 8 pixels per byte and 0-pad at the end."""
Width of image if you use 8 pixels per byte and 0-pad at the end.
"""
return (self.width + 7) >> 3 return (self.width + 7) >> 3
@property @property
def height(self): def height(self):
""" """Height of image in pixels."""
Height of image in pixels
"""
_, height_pixels = self._im.size _, height_pixels = self._im.size
return height_pixels return height_pixels
def to_column_format(self, high_density_vertical=True): def to_column_format(self, high_density_vertical=True):
""" """Extract slices of an image as equal-sized blobs of column-format data.
Extract slices of an image as equal-sized blobs of column-format data.
:param high_density_vertical: Printed line height in dots :param high_density_vertical: Printed line height in dots
""" """
@ -90,14 +82,11 @@ class EscposImage(object):
left += line_height left += line_height
def to_raster_format(self): def to_raster_format(self):
""" """Convert image to raster-format binary."""
Convert image to raster-format binary
"""
return self._im.tobytes() return self._im.tobytes()
def split(self, fragment_height): def split(self, fragment_height):
""" """Split an image into multiple fragments after fragment_height pixels.
Split an image into multiple fragments after fragment_height pixels
:param fragment_height: height of fragment :param fragment_height: height of fragment
:return: list of PIL objects :return: list of PIL objects
@ -114,7 +103,7 @@ class EscposImage(object):
return fragments return fragments
def center(self, max_width): def center(self, max_width):
"""In-place image centering """Center image in place.
:param: Maximum width in order to deduce x offset for centering :param: Maximum width in order to deduce x offset for centering
:return: None :return: None

View File

@ -1,6 +1,6 @@
#!/usr/bin/python #!/usr/bin/python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
""" Magic Encode """Magic Encode.
This module tries to convert an UTF-8 string to an encoded string for the printer. This module tries to convert an UTF-8 string to an encoded string for the printer.
It uses trial and error in order to guess the right codepage. It uses trial and error in order to guess the right codepage.
@ -24,8 +24,7 @@ from .exceptions import Error
class Encoder(object): class Encoder(object):
"""Takes a list of available code spaces. Picks the right one for a """Take available code spaces and pick the right one for a given character.
given character.
Note: To determine the code page, it needs to do the conversion, and Note: To determine the code page, it needs to do the conversion, and
thus already knows what the final byte in the target encoding would thus already knows what the final byte in the target encoding would
@ -41,20 +40,24 @@ class Encoder(object):
""" """
def __init__(self, codepage_map): def __init__(self, codepage_map):
"""Initialize encoder."""
self.codepages = codepage_map self.codepages = codepage_map
self.available_encodings = set(codepage_map.keys()) self.available_encodings = set(codepage_map.keys())
self.available_characters = {} self.available_characters = {}
self.used_encodings = set() self.used_encodings = set()
def get_sequence(self, encoding): def get_sequence(self, encoding):
"""Get a sequence."""
return int(self.codepages[encoding]) return int(self.codepages[encoding])
def get_encoding_name(self, encoding): def get_encoding_name(self, encoding):
"""Given an encoding provided by the user, will return a """Return a canonical encoding name.
Given an encoding provided by the user, will return a
canonical encoding name; and also validate that the encoding canonical encoding name; and also validate that the encoding
is supported. is supported.
TODO: Support encoding aliases: pc437 instead of cp437. .. todo:: Support encoding aliases: pc437 instead of cp437.
""" """
encoding = CodePages.get_encoding_name(encoding) encoding = CodePages.get_encoding_name(encoding)
if encoding not in self.codepages: if encoding not in self.codepages:
@ -68,7 +71,7 @@ class Encoder(object):
@staticmethod @staticmethod
def _get_codepage_char_list(encoding): def _get_codepage_char_list(encoding):
"""Get codepage character list """Get codepage character list.
Gets characters 128-255 for a given code page, as an array. Gets characters 128-255 for a given code page, as an array.
@ -94,7 +97,7 @@ class Encoder(object):
raise LookupError("Can't find a known encoding for {}".format(encoding)) raise LookupError("Can't find a known encoding for {}".format(encoding))
def _get_codepage_char_map(self, encoding): def _get_codepage_char_map(self, encoding):
"""Get codepage character map """Get codepage character map.
Process an encoding and return a map of UTF-characters to code points Process an encoding and return a map of UTF-characters to code points
in this encoding. in this encoding.
@ -132,7 +135,7 @@ class Encoder(object):
@staticmethod @staticmethod
def _encode_char(char, charmap, defaultchar): def _encode_char(char, charmap, defaultchar):
"""Encode a single character with the given encoding map """Encode a single character with the given encoding map.
:param char: char to encode :param char: char to encode
:param charmap: dictionary for mapping characters in this code page :param charmap: dictionary for mapping characters in this code page
@ -144,7 +147,7 @@ class Encoder(object):
return ord(defaultchar) return ord(defaultchar)
def encode(self, text, encoding, defaultchar="?"): def encode(self, text, encoding, defaultchar="?"):
"""Encode text under the given encoding """Encode text under the given encoding.
:param text: Text to encode :param text: Text to encode
:param encoding: Encoding name to use (must be defined in capabilities) :param encoding: Encoding name to use (must be defined in capabilities)
@ -161,7 +164,9 @@ class Encoder(object):
return (key in self.used_encodings, index) return (key in self.used_encodings, index)
def find_suitable_encoding(self, char): def find_suitable_encoding(self, char):
"""The order of our search is a specific one: """Search in a specific order for a suitable encoding.
It is the following order:
1. code pages that we already tried before; there is a good 1. code pages that we already tried before; there is a good
chance they might work again, reducing the search space, chance they might work again, reducing the search space,
@ -186,7 +191,9 @@ class Encoder(object):
def split_writable_text(encoder, text, encoding): def split_writable_text(encoder, text, encoding):
"""Splits off as many characters from the beginning of text as """Split up the writable text.
Splits off as many characters from the beginning of text as
are writable with "encoding". Returns a 2-tuple (writable, rest). are writable with "encoding". Returns a 2-tuple (writable, rest).
""" """
if not encoding: if not encoding:
@ -201,7 +208,9 @@ def split_writable_text(encoder, text, encoding):
class MagicEncode(object): class MagicEncode(object):
"""A helper that helps us to automatically switch to the right """Help switching to the right code page.
A helper that helps us to automatically switch to the right
code page to encode any given Unicode character. code page to encode any given Unicode character.
This will consider the printers supported codepages, according This will consider the printers supported codepages, according
@ -215,7 +224,7 @@ class MagicEncode(object):
def __init__( def __init__(
self, driver, encoding=None, disabled=False, defaultsymbol="?", encoder=None self, driver, encoding=None, disabled=False, defaultsymbol="?", encoder=None
): ):
""" """Initialize magic encode.
:param driver: :param driver:
:param encoding: If you know the current encoding of the printer :param encoding: If you know the current encoding of the printer
@ -237,7 +246,7 @@ class MagicEncode(object):
self.disabled = disabled self.disabled = disabled
def force_encoding(self, encoding): def force_encoding(self, encoding):
"""Sets a fixed encoding. The change is emitted right away. """Set a fixed encoding. The change is emitted right away.
From now one, this buffer will switch the code page anymore. From now one, this buffer will switch the code page anymore.
However, it will still keep track of the current code page. However, it will still keep track of the current code page.
@ -250,7 +259,6 @@ class MagicEncode(object):
def write(self, text): def write(self, text):
"""Write the text, automatically switching encodings.""" """Write the text, automatically switching encodings."""
if self.disabled: if self.disabled:
self.write_with_encoding(self.encoding, text) self.write_with_encoding(self.encoding, text)
return return
@ -279,12 +287,16 @@ class MagicEncode(object):
self.write_with_encoding(encoding, to_write) self.write_with_encoding(encoding, to_write)
def _handle_character_failed(self, char): def _handle_character_failed(self, char):
"""Called when no codepage was found to render a character.""" """Write a default symbol.
Called when no codepage was found to render a character.
"""
# Writing the default symbol via write() allows us to avoid # Writing the default symbol via write() allows us to avoid
# unnecesary codepage switches. # unnecesary codepage switches.
self.write(self.defaultsymbol) self.write(self.defaultsymbol)
def write_with_encoding(self, encoding, text): def write_with_encoding(self, encoding, text):
"""Write the text and inject necessary codepage switches."""
if text is not None and type(text) is not six.text_type: if text is not None and type(text) is not six.text_type:
raise Error( raise Error(
"The supplied text has to be unicode, but is of type {type}.".format( "The supplied text has to be unicode, but is of type {type}.".format(

View File

@ -41,7 +41,7 @@ except ImportError:
class Usb(Escpos): class Usb(Escpos):
"""USB printer """USB printer.
This class describes a printer that natively speaks USB. This class describes a printer that natively speaks USB.
@ -63,7 +63,8 @@ class Usb(Escpos):
*args, *args,
**kwargs **kwargs
): # noqa: N803 ): # noqa: N803
""" """Initialize USB printer.
:param idVendor: Vendor ID :param idVendor: Vendor ID
:param idProduct: Product ID :param idProduct: Product ID
:param usb_args: Optional USB arguments (e.g. custom_match) :param usb_args: Optional USB arguments (e.g. custom_match)
@ -123,7 +124,7 @@ class Usb(Escpos):
print("Could not set configuration: {0}".format(str(e))) print("Could not set configuration: {0}".format(str(e)))
def _raw(self, msg): def _raw(self, msg):
"""Print any command sent in raw format """Print any command sent in raw format.
:param msg: arbitrary code to be printed :param msg: arbitrary code to be printed
:type msg: bytes :type msg: bytes
@ -131,18 +132,18 @@ class Usb(Escpos):
self.device.write(self.out_ep, msg, self.timeout) self.device.write(self.out_ep, msg, self.timeout)
def _read(self): def _read(self):
"""Reads a data buffer and returns it to the caller.""" """Read a data buffer and return it to the caller."""
return self.device.read(self.in_ep, 16) return self.device.read(self.in_ep, 16)
def close(self): def close(self):
"""Release USB interface""" """Release USB interface."""
if self.device: if self.device:
usb.util.dispose_resources(self.device) usb.util.dispose_resources(self.device)
self.device = None self.device = None
class Serial(Escpos): class Serial(Escpos):
"""Serial printer """Serial printer.
This class describes a printer that is connected by serial interface. This class describes a printer that is connected by serial interface.
@ -166,7 +167,7 @@ class Serial(Escpos):
*args, *args,
**kwargs **kwargs
): ):
""" """Initialize serial printer.
:param devfile: Device file under dev filesystem :param devfile: Device file under dev filesystem
:param baudrate: Baud rate for serial transmission :param baudrate: Baud rate for serial transmission
@ -190,7 +191,7 @@ class Serial(Escpos):
self.open() self.open()
def open(self): def open(self):
"""Setup serial port and set is as escpos device""" """Set up serial port and set is as escpos device."""
if self.device is not None and self.device.is_open: if self.device is not None and self.device.is_open:
self.close() self.close()
self.device = serial.Serial( self.device = serial.Serial(
@ -210,7 +211,7 @@ class Serial(Escpos):
print("Unable to open serial printer on: {0}".format(str(self.devfile))) print("Unable to open serial printer on: {0}".format(str(self.devfile)))
def _raw(self, msg): def _raw(self, msg):
"""Print any command sent in raw format """Print any command sent in raw format.
:param msg: arbitrary code to be printed :param msg: arbitrary code to be printed
:type msg: bytes :type msg: bytes
@ -218,18 +219,18 @@ class Serial(Escpos):
self.device.write(msg) self.device.write(msg)
def _read(self): def _read(self):
"""Reads a data buffer and returns it to the caller.""" """Read the data buffer and return it to the caller."""
return self.device.read(16) return self.device.read(16)
def close(self): def close(self):
"""Close Serial interface""" """Close Serial interface."""
if self.device is not None and self.device.is_open: if self.device is not None and self.device.is_open:
self.device.flush() self.device.flush()
self.device.close() self.device.close()
class Network(Escpos): class Network(Escpos):
"""Network printer """Network printer.
This class is used to attach to a networked printer. You can also use this in order to attach to a printer that This class is used to attach to a networked printer. You can also use this in order to attach to a printer that
is forwarded with ``socat``. is forwarded with ``socat``.
@ -252,7 +253,7 @@ class Network(Escpos):
""" """
def __init__(self, host, port=9100, timeout=60, *args, **kwargs): def __init__(self, host, port=9100, timeout=60, *args, **kwargs):
""" """Initialize network printer.
:param host: Printer's hostname or IP address :param host: Printer's hostname or IP address
:param port: Port to write to :param port: Port to write to
@ -265,7 +266,7 @@ class Network(Escpos):
self.open() self.open()
def open(self): def open(self):
"""Open TCP socket with ``socket``-library and set it as escpos device""" """Open TCP socket with ``socket``-library and set it as escpos device."""
self.device = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.device = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.device.settimeout(self.timeout) self.device.settimeout(self.timeout)
self.device.connect((self.host, self.port)) self.device.connect((self.host, self.port))
@ -274,7 +275,7 @@ class Network(Escpos):
print("Could not open socket for {0}".format(self.host)) print("Could not open socket for {0}".format(self.host))
def _raw(self, msg): def _raw(self, msg):
"""Print any command sent in raw format """Print any command sent in raw format.
:param msg: arbitrary code to be printed :param msg: arbitrary code to be printed
:type msg: bytes :type msg: bytes
@ -282,12 +283,11 @@ class Network(Escpos):
self.device.sendall(msg) self.device.sendall(msg)
def _read(self): def _read(self):
"""Read data from the TCP socket""" """Read data from the TCP socket."""
return self.device.recv(16) return self.device.recv(16)
def close(self): def close(self):
"""Close TCP connection""" """Close TCP connection."""
if self.device is not None: if self.device is not None:
try: try:
self.device.shutdown(socket.SHUT_RDWR) self.device.shutdown(socket.SHUT_RDWR)
@ -297,7 +297,7 @@ class Network(Escpos):
class File(Escpos): class File(Escpos):
"""Generic file printer """Generic file printer.
This class is used for parallel port printer or other printers that are directly attached to the filesystem. This class is used for parallel port printer or other printers that are directly attached to the filesystem.
Note that you should stay away from using USB-to-Parallel-Adapter since they are unreliable Note that you should stay away from using USB-to-Parallel-Adapter since they are unreliable
@ -311,7 +311,7 @@ class File(Escpos):
""" """
def __init__(self, devfile="/dev/usb/lp0", auto_flush=True, *args, **kwargs): def __init__(self, devfile="/dev/usb/lp0", auto_flush=True, *args, **kwargs):
""" """Initialize file printer with device file.
:param devfile: Device file under dev filesystem :param devfile: Device file under dev filesystem
:param auto_flush: automatically call flush after every call of _raw() :param auto_flush: automatically call flush after every call of _raw()
@ -322,18 +322,18 @@ class File(Escpos):
self.open() self.open()
def open(self): def open(self):
"""Open system file""" """Open system file."""
self.device = open(self.devfile, "wb") self.device = open(self.devfile, "wb")
if self.device is None: if self.device is None:
print("Could not open the specified file {0}".format(self.devfile)) print("Could not open the specified file {0}".format(self.devfile))
def flush(self): def flush(self):
"""Flush printing content""" """Flush printing content."""
self.device.flush() self.device.flush()
def _raw(self, msg): def _raw(self, msg):
"""Print any command sent in raw format """Print any command sent in raw format.
:param msg: arbitrary code to be printed :param msg: arbitrary code to be printed
:type msg: bytes :type msg: bytes
@ -343,14 +343,14 @@ class File(Escpos):
self.flush() self.flush()
def close(self): def close(self):
"""Close system file""" """Close system file."""
if self.device is not None: if self.device is not None:
self.device.flush() self.device.flush()
self.device.close() self.device.close()
class Dummy(Escpos): class Dummy(Escpos):
"""Dummy printer """Dummy printer.
This class is used for saving commands to a variable, for use in situations where This class is used for saving commands to a variable, for use in situations where
there is no need to send commands to an actual printer. This includes there is no need to send commands to an actual printer. This includes
@ -364,12 +364,12 @@ class Dummy(Escpos):
""" """
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
""" """ """Init with empty output list."""
Escpos.__init__(self, *args, **kwargs) Escpos.__init__(self, *args, **kwargs)
self._output_list = [] self._output_list = []
def _raw(self, msg): def _raw(self, msg):
"""Print any command sent in raw format """Print any command sent in raw format.
:param msg: arbitrary code to be printed :param msg: arbitrary code to be printed
:type msg: bytes :type msg: bytes
@ -378,11 +378,11 @@ class Dummy(Escpos):
@property @property
def output(self): def output(self):
"""Get the data that was sent to this printer""" """Get the data that was sent to this printer."""
return b"".join(self._output_list) return b"".join(self._output_list)
def clear(self): def clear(self):
"""Clear the buffer of the printer """Clear the buffer of the printer.
This method can be called if you send the contents to a physical printer This method can be called if you send the contents to a physical printer
and want to use the Dummy printer for new output. and want to use the Dummy printer for new output.
@ -390,13 +390,20 @@ class Dummy(Escpos):
del self._output_list[:] del self._output_list[:]
def close(self): def close(self):
"""Close not implemented for Dummy printer."""
pass pass
if _WIN32PRINT: if _WIN32PRINT:
class Win32Raw(Escpos): class Win32Raw(Escpos):
"""Printer binding for win32 API.
Uses the module pywin32 for printing.
"""
def __init__(self, printer_name=None, *args, **kwargs): def __init__(self, printer_name=None, *args, **kwargs):
"""Initialize default printer."""
Escpos.__init__(self, *args, **kwargs) Escpos.__init__(self, *args, **kwargs)
if printer_name is not None: if printer_name is not None:
self.printer_name = printer_name self.printer_name = printer_name
@ -406,6 +413,7 @@ if _WIN32PRINT:
self.open() self.open()
def open(self, job_name="python-escpos"): def open(self, job_name="python-escpos"):
"""Open connection to default printer."""
if self.printer_name is None: if self.printer_name is None:
raise Exception("Printer not found") raise Exception("Printer not found")
self.hPrinter = win32print.OpenPrinter(self.printer_name) self.hPrinter = win32print.OpenPrinter(self.printer_name)
@ -415,6 +423,7 @@ if _WIN32PRINT:
win32print.StartPagePrinter(self.hPrinter) win32print.StartPagePrinter(self.hPrinter)
def close(self): def close(self):
"""Close connection to default printer."""
if not self.hPrinter: if not self.hPrinter:
return return
win32print.EndPagePrinter(self.hPrinter) win32print.EndPagePrinter(self.hPrinter)
@ -449,7 +458,7 @@ if _CUPSPRINT:
""" """
def __init__(self, printer_name=None, *args, **kwargs): def __init__(self, printer_name=None, *args, **kwargs):
"""CupsPrinter class constructor. """Class constructor for CupsPrinter.
:param printer_name: CUPS printer name (Optional) :param printer_name: CUPS printer name (Optional)
:type printer_name: str :type printer_name: str
@ -478,7 +487,7 @@ if _CUPSPRINT:
return self.conn.getPrinters() return self.conn.getPrinters()
def open(self, job_name="python-escpos"): def open(self, job_name="python-escpos"):
"""Setup a new print job and target printer. """Set up a new print job and target the printer.
A call to this method is required to send new jobs to A call to this method is required to send new jobs to
the same CUPS connection. the same CUPS connection.
@ -492,7 +501,7 @@ if _CUPSPRINT:
self.tmpfile = tempfile.NamedTemporaryFile(delete=True) self.tmpfile = tempfile.NamedTemporaryFile(delete=True)
def _raw(self, msg): def _raw(self, msg):
"""Append any command sent in raw format to temporary file """Append any command sent in raw format to temporary file.
:param msg: arbitrary code to be printed :param msg: arbitrary code to be printed
:type msg: bytes :type msg: bytes

View File

@ -13,8 +13,9 @@ import escpos.printer as printer
def test_with_statement(): def test_with_statement():
"""Use with statement""" """Use with statement
.. todo:: Extend these tests as they don't really do anything at the moment"""
dummy_printer = printer.Dummy() dummy_printer = printer.Dummy()
with escpos.EscposIO(dummy_printer) as p: with escpos.EscposIO(dummy_printer) as p:
p.writelines("Some text.\n") p.writelines("Some text.\n")
# TODO extend these tests as they don't really do anything at the moment