add with-statement

* with imported from mosquito (adaption of the code in 86a3e8dfb257e3af0ec141ee5d97717501d6e945 by @mosquito)
* encoding of file to utf-8
* added rudimentary test for with
* implement close function for all printers
This commit is contained in:
Patrick Kanzler 2016-03-28 15:54:43 +02:00
parent 16569067c2
commit 910f2fbf2f
5 changed files with 126 additions and 5 deletions

View File

@ -1,3 +1,4 @@
# -*- coding: utf-8 -*-
""" Set of ESC/POS Commands (Constants)
This module contains constants that are described in the esc/pos-documentation.

View File

@ -1,4 +1,5 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
""" Main class
This module contains the abstract base class :py:class:`Escpos`.
@ -38,6 +39,10 @@ class Escpos(object):
:param columns: Text columns used by the printer. Defaults to 32."""
self.columns = columns
def __del__(self):
""" call self.close upon deletion """
self.close()
@abstractmethod
def _raw(self, msg):
""" Sends raw data to the printer
@ -620,3 +625,89 @@ class Escpos(object):
self._raw(PANEL_BUTTON_ON)
else:
self._raw(PANEL_BUTTON_OFF)
class EscposIO(object):
"""ESC/POS Printer IO object
Allows the class to be used together with the `with`-statement. You have to define a printer instance
and assign it to the EsposIO-class.
This example explains the usage:
.. code-block:: Python
with EscposIO(printer.Serial('/dev/ttyUSB0')) as p:
p.set(font='a', height=2, align='center', text_type='bold')
p.printer.set(align='left')
p.printer.image('logo.gif')
p.writelines('Big line\\n', font='b')
p.writelines('Привет')
p.writelines('BIG TEXT', width=2)
After the `with`-statement the printer automatically cuts the paper if `autocut` is `True`.
"""
def __init__(self, printer, autocut=True, autoclose=True, **kwargs):
"""
:param printer: An EscPos-printer object
:type printer: escpos.Escpos
:param autocut: If True, paper is automatically cut after the `with`-statement *default*: True
:param kwargs: These arguments will be passed to :py:meth:`escpos.Escpos.set()`
"""
self.printer = printer
self.params = kwargs
self.autocut = autocut
self.autoclose = autoclose
def set(self, **kwargs):
""" Set the printer-parameters
Controls which parameters will be passed to :py:meth:`Escpos.set() <escpos.escpos.Escpos.set()>`.
For more information on the parameters see the :py:meth:`set() <escpos.escpos.Escpos.set()>`-methods
documentation. These parameters can also be passed with this class' constructor or the
:py:meth:`~escpos.escpos.EscposIO.writelines()`-method.
:param kwargs: keyword-parameters that will be passed to :py:meth:`Escpos.set() <escpos.escpos.Escpos.set()>`
"""
self.params.update(kwargs)
def writelines(self, text, **kwargs):
params = dict(self.params)
params.update(kwargs)
if isinstance(text, six.text_type):
lines = text.split('\n')
elif isinstance(text, list) or isinstance(text, tuple):
lines = text
else:
lines = ["{0}".format(text), ]
# TODO check unicode handling
# TODO flush? or on print? (this should prob rather be handled by the _raw-method)
for line in lines:
self.printer.set(**params)
if isinstance(text, six.text_type):
self.printer.text(u"{0}\n".format(line))
else:
self.printer.text("{0}\n".format(line))
def close(self):
""" called upon closing the `with`-statement
"""
self.printer.close()
def __enter__(self, **kwargs):
return self
def __exit__(self, type, value, traceback):
"""
If :py:attr:`autocut <escpos.escpos.EscposIO.autocut>` is `True` (set by this class' constructor),
then :py:meth:`printer.cut() <escpos.escpos.Escpos.cut()>` will be called here.
"""
if not (type is not None and issubclass(type, Exception)):
if self.autocut:
self.printer.cut()
if self.autoclose:
self.close()

View File

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

View File

@ -1,5 +1,6 @@
#!/usr/bin/python
""" This module contains the implentations of abstract base class :py:class:`Escpos`.
# -*- coding: utf-8 -*-
""" This module contains the implementations of abstract base class :py:class:`Escpos`.
:author: `Manuel F Martinez <manpaz@bashlinux.com>`_ and others
:organization: Bashlinux and `python-escpos <https://github.com/python-escpos>`_
@ -82,7 +83,7 @@ class Usb(Escpos):
"""
self.device.write(self.out_ep, msg, self.interface)
def __del__(self):
def close(self):
""" Release USB interface """
if self.device:
usb.util.dispose_resources(self.device)
@ -147,7 +148,7 @@ class Serial(Escpos):
"""
self.device.write(msg)
def __del__(self):
def close(self):
""" Close Serial interface """
if self.device is not None:
self.device.flush()
@ -207,7 +208,7 @@ class Network(Escpos):
"""
self.device.sendall(msg)
def __del__(self):
def close(self):
""" Close TCP connection """
self.device.shutdown(socket.SHUT_RDWR)
self.device.close()
@ -255,7 +256,7 @@ class File(Escpos):
"""
self.device.write(msg)
def __del__(self):
def close(self):
""" Close system file """
self.device.flush()
self.device.close()
@ -294,3 +295,6 @@ class Dummy(Escpos):
def output(self):
""" Get the data that was sent to this printer """
return b''.join(self._output_list)
def close(self):
pass

View File

@ -0,0 +1,24 @@
#!/usr/bin/python
"""test the facility which enables usage of the with-statement
:author: `Patrick Kanzler <patrick.kanzler@fablab.fau.de>`_
:organization: `python-escpos <https://github.com/python-escpos>`_
:copyright: Copyright (c) 2016 `python-escpos <https://github.com/python-escpos>`_
:license: GNU GPL v3
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
import escpos.printer as printer
import escpos.escpos as escpos
import os
def test_with_statement():
"""Use with statement"""
dummy_printer = printer.Dummy()
with escpos.EscposIO(dummy_printer) as p:
p.writelines('Some text.\n')
# TODO extend these tests as they don't really do anything at the moment