1
0
mirror of https://github.com/python-escpos/python-escpos synced 2025-09-13 09:09:58 +00:00

69 Commits

Author SHA1 Message Date
Patrick Kanzler
8b3076871f Merge pull request #346 from python-escpos/development
release v3.0a6
2019-06-19 15:28:46 +02:00
Patrick Kanzler
46429b1092 update changelog 2019-06-19 14:39:52 +02:00
Patrick Kanzler
99ca096f82 Merge pull request #345 from python-escpos/setup-fix-capabilities-path
improve package structure with capabilities file
2019-06-19 14:30:00 +02:00
Patrick Kanzler
2d97c0bbbd improve package structure with capabilities file 2019-06-19 14:14:59 +02:00
Patrick Kanzler
6c6fe9bccf Merge pull request #342 from python-escpos/108-test-on-windows-travis
Add Windows and macOS configuration for Travis CI
2019-06-16 12:13:30 +02:00
Patrick Kanzler
c5e46a888d fix allowed failures 2019-06-16 03:08:19 +02:00
Patrick Kanzler
46942820a5 update env variables 2019-06-16 03:05:42 +02:00
Patrick Kanzler
e50e295acc add osx 2019-06-16 03:01:36 +02:00
Patrick Kanzler
2d7458fa49 activate fast_finish 2019-06-16 02:47:46 +02:00
Patrick Kanzler
a6f635c0d5 fix capabilities file 2019-06-16 02:45:40 +02:00
Patrick Kanzler
2d0f045457 add first draft of Windows conf for #108 2019-06-16 02:45:40 +02:00
Patrick Kanzler
293b8632ff Merge pull request #341 from python-escpos/308-update-docstring-qr
fix links and impl (in qr-method) in docstrings
2019-06-16 02:17:27 +02:00
Patrick Kanzler
5ff73595b6 fix links and impl (in qr-method) in docstrings
fixes #308
2019-06-16 01:54:47 +02:00
Patrick Kanzler
4ecab402b8 Merge pull request #339 from python-escpos/development
release v3.0a5
2019-06-16 00:31:07 +02:00
Patrick Kanzler
c56e43da84 update changelog 2019-06-16 00:17:04 +02:00
Patrick Kanzler
88af26f46e Merge pull request #338 from alexdebiasio/development
Implemented _read method of Network printer class. Solves issue #286
2019-06-16 00:01:12 +02:00
Patrick Kanzler
9dd966c2a3 update mailmap 2019-06-15 23:40:00 +02:00
Patrick Kanzler
a7d959428f update authors 2019-06-15 22:50:50 +02:00
Alex Debiasio
8bf0e08659 Implemented _read method of Network printer class 2019-06-13 21:28:46 +02:00
Patrick Kanzler
5ac5a24b50 Toolchain update travis drop py2x (#336)
* drop python 2 from supported languages

Python 2 compatibility will not be actively revoked, but will
not be worked on.

* update travis config

* remove flake8-test with Py2.7
2019-06-11 00:24:09 +02:00
Patrick Kanzler
63252515b5 Merge pull request #335 from python-escpos/322-doc-serial-printer-on-windows
doc add example for Serial on Windows
2019-06-10 22:26:34 +02:00
Patrick Kanzler
29a546821b doc add example for Serial on Windows
fixes #322
2019-06-10 22:05:26 +02:00
Patrick Kanzler
4ddd18279f Merge pull request #320 from ramonpoca/development
Add Win32Raw printer to available printers
2019-06-07 10:11:53 +02:00
Patrick Kanzler
de761e96e3 Merge branch 'development' into development 2019-06-07 09:53:14 +02:00
Patrick Kanzler
ed7bce6932 Merge pull request #329 from akeonly/patch-1
Update README.rst : example for network printer
2019-06-05 00:05:08 +02:00
Patrick Kanzler
edd567785c fix whitespace 2019-06-04 23:57:19 +02:00
Patrick Kanzler
f1054876da update authors 2019-06-04 23:55:33 +02:00
Patrick Kanzler
490e0657dd Merge branch 'development' into patch-1 2019-06-04 23:04:39 +02:00
Patrick Kanzler
b4c32b5a4a Merge branch 'development' into development 2019-06-04 23:04:25 +02:00
Patrick Kanzler
40b30225d3 Merge pull request #330 from om26er/windows-support
Enable Windows Support
2019-06-04 23:04:09 +02:00
Patrick Kanzler
19e3ec6895 Merge pull request #331 from teamorchard/use-pyyaml-safe-load
Update to use pyyaml safe_load()
2019-06-04 22:45:05 +02:00
Patrick Kanzler
df539da854 Merge branch 'development' into development 2019-06-04 22:31:47 +02:00
Patrick Kanzler
4534038b39 Merge branch 'development' into patch-1 2019-06-04 22:31:33 +02:00
Patrick Kanzler
adf85f7784 Merge branch 'development' into windows-support 2019-06-04 22:31:08 +02:00
Patrick Kanzler
aaa8162967 Merge branch 'development' into use-pyyaml-safe-load 2019-06-04 22:30:47 +02:00
Patrick Kanzler
0461adc212 restrict hypothesis-version to below 4 2019-06-04 22:30:23 +02:00
Justin Vieira
91ff83e506 Update to use pyyaml safe_load(), as load() is unsafe and disabled on some systems 2019-05-29 16:43:19 -04:00
Omer Akram
29ef88f591 Better comment 2019-05-22 17:25:33 +05:00
Omer Akram
7c01a30d6c fix a typo 2019-05-22 17:20:15 +05:00
Omer Akram
035c425581 Add author 2019-05-22 17:09:27 +05:00
Omer Akram
d20646b2a9 Make windows enablement code more intelligent 2019-05-22 17:01:13 +05:00
Omer Akram
206822ac69 Enable Windows Support 2019-05-22 16:39:26 +05:00
akeonly
dc08792e72 Update README.rst : example for network printer
Add example for Network Printer
2019-05-11 18:33:33 +07:00
Ramon Poca
2886075ce9 Fix initializer mess 2018-12-31 14:24:10 +01:00
Ramon Poca
73fff6291d Fix syntax 2018-12-31 13:57:53 +01:00
Ramon Poca
d5b9d99093 Update AUTHORS 2018-12-31 10:43:31 +01:00
Ramon Poca
18c51358aa Add Win32Raw printer to available printers 2018-12-13 08:01:05 -08:00
Gerard Marull-Paretas
52719c0b7d Allow arbitrary USB args 2018-11-21 22:01:13 +01:00
Patrick Kanzler
0051c876bf Merge pull request #298 from python-escpos/development
release v3.0a4
2018-05-15 23:12:17 +02:00
Patrick Kanzler
854759d312 update changelog 2018-05-15 22:48:33 +02:00
Patrick Kanzler
a0343c66af update capabilities-data 2018-05-15 22:07:12 +02:00
Patrick Kanzler
6c94f88c24 improve platform independence (#296)
* add os.devnull for platform independence

fixes #288

* add test for soft_barcode

* open devnull as binary

* add version identifier to pickle
2018-05-15 01:03:07 +02:00
Patrick Kanzler
6fb23d6826 remove test from setup.py (#297)
fixes #294
2018-05-15 00:34:43 +02:00
Patrick Kanzler
f649814091 Fix travis-builds and tests in general (#295)
* add explicit location of capabilities.json for travis
* pass on env variables in tox builds
* drop support for python 3.3 and remove python3.3 from supported versions list
2018-05-14 18:06:31 +02:00
Patrick Kanzler
47b4d41b28 use package for tempdir
cherry-picked from 8494cca526 in #274
2018-05-13 18:52:39 +02:00
Patrick Kanzler
599f4f3ca5 add new authors 2018-05-13 18:44:47 +02:00
primax79
d085e5c467 parameter for implementation of nonnative qrcode (#289) 2018-05-13 18:42:41 +02:00
kennedy
b418302311 Modified submodule to always pull from master branch (#283) 2018-05-13 18:42:07 +02:00
Patrick Kanzler
f6acb72bbe Merge branch 'fix-travis-builds' into development 2018-05-13 18:40:57 +02:00
Patrick Kanzler
0c9856c1f6 disable QR test for image 2018-05-13 18:26:48 +02:00
Patrick Kanzler
a748563395 blacklist hypothesis version 2018-05-13 18:04:48 +02:00
Patrick Kanzler
b84e280efb disable broken tests 2018-05-13 17:32:52 +02:00
Thijs Triemstra
4390dc4a9c fix is_online() (#282)
* fix is_online

* fix sphinx formatting

* reword
2018-05-02 09:25:04 +02:00
Thijs Triemstra
6e09fd1e97 fix typo 2018-04-26 07:22:37 +02:00
Thijs Triemstra
100c6b5e89 fix typo (#279) 2018-02-07 22:17:18 +01:00
Christoph Heuel
26d72a69f0 Feature/clear content in dummy printer (#271)
Add Function to Dummy Printer for Clearing Buffer

If you are using the dummy printer, you may want to use the printer
again after sending the output to a physical printer.
This method empties the list of the output buffer.
2017-12-04 00:13:28 +01:00
Patrick Kanzler
01e28bbcf6 ammend blacklisting from cd1bcb57b4
the last comment was a bit rushed and did not properly blacklist both
bad versions of pytest
2017-12-03 23:49:46 +01:00
Patrick Kanzler
2a7e2a6a36 blacklist pytest 3.3.0
see pytest-dev/pytest#2957
2017-12-03 23:43:23 +01:00
reck
3c3dab95f5 raise exception when TypeError occurs in cashdraw (#268) 2017-12-03 23:21:29 +01:00
20 changed files with 333 additions and 106 deletions

1
.gitignore vendored
View File

@@ -20,6 +20,7 @@ dist/
.coverage
src/escpos/version.py
.hypothesis
.pytest_cache/
# testing temporary directories
test/test-cli-output/

1
.gitmodules vendored
View File

@@ -1,3 +1,4 @@
[submodule "capabilities-data"]
path = capabilities-data
url = https://github.com/receipt-print-hq/escpos-printer-db.git
branch = master

View File

@@ -8,5 +8,8 @@ Cody (Quantified Code Bot) <cody@quantifiedcode.com> Cody <cody@quantifiedcode.c
Renato Lorenzi <renato.lorenzi@senior.com.br> Renato.Lorenzi <renato.lorenzi@senior.com.br>
Ahmed Tahri <nyuubi.10@gmail.com> TAHRI Ahmed <nyuubi.10@gmail.com>
Michael Elsdörfer <michael@elsdoerfer.com> Michael Elsdörfer <michael@elsdoerfer.info>
Juanmi Taboada <juanmi@juanmitaboada.com> Juanmi Taboada <juanmi@juanmitaboada.com>
csoft2k <csoft2k@hotmail.com>
Sergio Pulgarin <sergio.pulgarin@gmail.com>
reck31 <rakesh.gunduka@gmail.com>
Alex Debiasio <alex.debiasio@thinkin.io> <alex.debiasio@studenti.unitn.it>

View File

@@ -1,18 +1,36 @@
language: python
sudo: false
cache: pip
dist: xenial
git:
depth: 100000
addons:
apt:
packages:
- graphviz
env:
global:
- ESCPOS_CAPABILITIES_FILE=/home/travis/build/python-escpos/python-escpos/capabilities-data/dist/capabilities.json
matrix:
fast_finish: true
include:
- name: "Python 3.7 on Windows"
os: windows
language: shell
before_install:
- choco install python
- pip install tox codecov 'sphinx>=1.5.1'
env:
- TOXENV=py37
- PATH=/c/Python37:/c/Python37/Scripts:$PATH
- ESCPOS_CAPABILITIES_FILE=C:/Users/travis/build/python-escpos/python-escpos/capabilities-data/dist/capabilities.json
- name: "Python 3.7 on macOS"
os: osx
osx_image: xcode10.2
language: shell
env: TOXENV=py37 ESCPOS_CAPABILITIES_FILE=/Users/travis/build/python-escpos/python-escpos/capabilities-data/dist/capabilities.json
- python: 2.7
env: TOXENV=py27
- python: 3.3
env: TOXENV=py33
- python: 3.4
env: TOXENV=py34
- python: 3.5
@@ -21,22 +39,31 @@ matrix:
env: TOXENV=py36
- python: 3.6-dev
env: TOXENV=py36
- python: nightly
- python: 3.7
env: TOXENV=py37
- python: 3.7-dev
env: TOXENV=py37
- python: 3.8-dev
env: TOXENV=py38
- python: nightly
env: TOXENV=py38
- python: pypy
env: TOXENV=pypy
- python: pypy3
env: TOXENV=pypy3
- python: 2.7
- python: 3.7
env: TOXENV=docs
- python: 2.7
env: TOXENV=flake8
- python: 3.6
- python: 3.7
env: TOXENV=flake8
allow_failures:
- python: 2.7
- python: 3.6-dev
- python: 3.7-dev
- python: 3.8-dev
- python: nightly
- python: pypy3
- os: windows
- os: osx
before_install:
- pip install tox codecov 'sphinx>=1.5.1'
- ./doc/generate_authors.sh --check
@@ -59,4 +86,4 @@ deploy:
tags: true
repo: python-escpos/python-escpos
branch: master
condition: $TRAVIS_PYTHON_VERSION = "3.5"
condition: $TRAVIS_PYTHON_VERSION = "3.7"

View File

@@ -1,4 +1,6 @@
Ahmed Tahri
akeonly
Alex Debiasio
Asuki Kono
belono
Christoph Heuel
@@ -8,8 +10,11 @@ Curtis // mashedkeyboard
Davis Goglin
Dean Rispin
Dmytro Katyukha
Gerard Marull-Paretas
Hark
Joel Lehtonen
Justin Vieira
kennedy
Kristi
ldos
Lucy Linder
@@ -18,8 +23,12 @@ Michael Billington
Michael Elsdörfer
mrwunderbar666
Nathan Bookham
Omer Akram
Patrick Kanzler
primax79
Qian Linfeng
Ramon Poca
reck31
Renato Lorenzi
Romain Porte
Sam Cheng

View File

@@ -1,6 +1,69 @@
*********
Changelog
*********
2019-06-19 - Version 3.0a6 - "Mistake not..."
---------------------------------------------
This release is the seventh alpha release of the new version 3.0.
Please be aware the the API is subject to change until v3.0 is
released.
changes
^^^^^^^
- fix inclusion of the capabilities-file
- execute CI jobs also on Windows and macOS-targets
- improve documentation
contributors
^^^^^^^^^^^^
- Patrick Kanzler
2019-06-16 - Version 3.0a5 - "Lightly Seared On The Reality Grill"
------------------------------------------------------------------
This release is the sixth alpha release of the new version 3.0. Please
be aware that the API is subject to change until v3.0 is released.
changes
^^^^^^^
- allow arbitrary USB arguments in USB-class
- add Win32Raw-Printer on Windows-platforms
- add and improve Windows support of USB-class
- use pyyaml safe_load()
- improve doc
- implement _read method of Network printer class
contributors
^^^^^^^^^^^^
- Patrick Kanzler
- Gerard Marull-Paretas
- Ramon Poca
- akeonly
- Omer Akram
- Justin Vieira
2018-05-15 - Version 3.0a4 - "Kakistocrat"
------------------------------------------
This release is the fifth alpha release of the new version 3.0. Please
be aware that the API will still change until v3.0 is released.
changes
^^^^^^^
- raise exception when TypeError occurs in cashdraw (#268)
- Feature/clear content in dummy printer (#271)
- fix is_online() (#282)
- improve documentation
- Modified submodule to always pull from master branch (#283)
- parameter for implementation of nonnative qrcode (#289)
- improve platform independence (#296)
contributors
^^^^^^^^^^^^
- Christoph Heuel
- Patrick Kanzler
- kennedy
- primax79
- reck31
- Thijs Triemstra
2017-10-08 - Version 3.0a3 - "Just Testing"
-------------------------------------------
This release is the fourth alpha release of the new version 3.0. Please

View File

@@ -1,6 +1,5 @@
include *.rst
include *.txt
include COPYING
include LICENSE
include INSTALL
include tox.ini

View File

@@ -65,6 +65,19 @@ The basic usage is:
p.barcode('1324354657687', 'EAN13', 64, 2, '', '')
p.cut()
Another example based on the Network printer class:
.. code:: python
from escpos.printer import Network
kitchen = Network("192.168.1.100") #Printer IP Address
kitchen.text("Hello World\n")
kitchen.barcode('1324354657687', 'EAN13', 64, 2, '', '')
kitchen.cut()
The full project-documentation is available on `Read the Docs <https://python-escpos.readthedocs.io>`_.
Contributing

View File

@@ -44,7 +44,7 @@ to have and the second yields the "Output Endpoint" address.
::
Epson = printer.Usb(0x04b8,0x0202)
p = printer.Usb(0x04b8,0x0202)
By default the "Interface" number is "0" and the "Output Endpoint"
address is "0x01". If you have other values then you can define them on
@@ -55,7 +55,7 @@ on 0x81 and out\_ep=0x02, then the printer definition should look like:
::
Generic = printer.Usb(0x1a2b,0x1a2b,0,0x81,0x02)
p = printer.Usb(0x1a2b,0x1a2b,0,0x81,0x02)
Network printer
^^^^^^^^^^^^^^^
@@ -67,7 +67,7 @@ IP by DHCP or you set it manually.
::
Epson = printer.Network("192.168.1.99")
p = printer.Network("192.168.1.99")
Serial printer
^^^^^^^^^^^^^^
@@ -81,7 +81,10 @@ to.
::
Epson = printer.Serial("/dev/tty0")
p = printer.Serial("/dev/tty0")
# on a Windows OS serial devices are typically accessible as COM
p = printer.Serial("COM1")
Other printers
^^^^^^^^^^^^^^
@@ -93,7 +96,7 @@ passing the device node name.
::
Epson = printer.File("/dev/usb/lp1")
p = printer.File("/dev/usb/lp1")
The default is "/dev/usb/lp0", so if the printer is located on that
node, then you don't necessary need to pass the node name.
@@ -108,17 +111,17 @@ on a USB interface.
from escpos import *
""" Seiko Epson Corp. Receipt Printer M129 Definitions (EPSON TM-T88IV) """
Epson = printer.Usb(0x04b8,0x0202)
p = printer.Usb(0x04b8,0x0202)
# Print text
Epson.text("Hello World\n")
p.text("Hello World\n")
# Print image
Epson.image("logo.gif")
p.image("logo.gif")
# Print QR Code
Epson.qr("You can readme from your smartphone")
p.qr("You can readme from your smartphone")
# Print barcode
Epson.barcode('1324354657687','EAN13',64,2,'','')
p.barcode('1324354657687','EAN13',64,2,'','')
# Cut paper
Epson.cut()
p.cut()
Configuration File
------------------

View File

@@ -3,7 +3,6 @@
import os
import sys
from setuptools import find_packages, setup
from setuptools.command.test import test as test_command
base_dir = os.path.dirname(__file__)
@@ -19,33 +18,6 @@ def read(fname):
return open(os.path.join(os.path.dirname(__file__), fname)).read()
class Tox(test_command):
"""proxy class that enables tox to be run with setup.py test"""
user_options = [('tox-args=', 'a', "Arguments to pass to tox")]
def initialize_options(self):
"""initialize the user-options"""
test_command.initialize_options(self)
self.tox_args = None
def finalize_options(self):
"""finalize user-options"""
test_command.finalize_options(self)
self.test_args = []
self.test_suite = True
def run_tests(self):
"""run tox and pass on user-options"""
# import here, cause outside the eggs aren't loaded
import tox
import shlex
args = self.tox_args
if args:
args = shlex.split(self.tox_args)
errno = tox.cmdline(args=args)
sys.exit(errno)
setuptools_scm_template = """\
# coding: utf-8
# file generated by setuptools_scm
@@ -84,7 +56,7 @@ setup(
platforms='any',
package_dir={"": "src"},
packages=find_packages(where="src", exclude=["tests", "tests.*"]),
package_data={'': ['COPYING', 'src/escpos/capabilities.json']},
package_data={'escpos': ['capabilities.json']},
include_package_data=True,
classifiers=[
'Development Status :: 4 - Beta',
@@ -93,10 +65,7 @@ setup(
'License :: OSI Approved :: MIT License',
'Operating System :: OS Independent',
'Programming Language :: Python',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
@@ -125,16 +94,15 @@ setup(
tests_require=[
'jaconv',
'tox',
'pytest!=3.2.0',
'pytest!=3.2.0,!=3.3.0',
'pytest-cov',
'pytest-mock',
'nose',
'scripttest',
'mock',
'hypothesis',
'hypothesis!=3.56.9,<4',
'flake8'
],
cmdclass={'test': Tox},
entry_points={
'console_scripts': [
'python-escpos = escpos.cli:main'

View File

@@ -7,13 +7,14 @@ import time
import six
import yaml
from tempfile import gettempdir
import platform
logging.basicConfig()
logger = logging.getLogger(__name__)
pickle_dir = environ.get('ESCPOS_CAPABILITIES_PICKLE_DIR', '/tmp/')
pickle_path = path.join(pickle_dir, 'capabilities.pickle')
pickle_dir = environ.get('ESCPOS_CAPABILITIES_PICKLE_DIR', gettempdir())
pickle_path = path.join(pickle_dir, '{v}.capabilities.pickle'.format(v=platform.python_version()))
capabilities_path = environ.get(
'ESCPOS_CAPABILITIES_FILE',
path.join(path.dirname(__file__), 'capabilities.json'))
@@ -37,7 +38,7 @@ else:
if full_load:
logger.debug('Loading and pickling capabilities')
with open(capabilities_path) as cp, open(pickle_path, 'wb') as pp:
CAPABILITIES = yaml.load(cp)
CAPABILITIES = yaml.safe_load(cp)
pickle.dump(CAPABILITIES, pp, protocol=2)
logger.debug('Finished loading capabilities took %.2fs', time.time() - t0)
@@ -47,7 +48,7 @@ PROFILES = CAPABILITIES['profiles']
class NotSupported(Exception):
"""Raised if a requested feature is not suppored by the
"""Raised if a requested feature is not supported by the
printer profile.
"""
pass
@@ -90,7 +91,7 @@ class BaseProfile(object):
return self.features.get(feature)
def get_code_pages(self):
"""Return the support code pages as a {name: index} dict.
"""Return the support code pages as a ``{name: index}`` dict.
"""
return {v: k for k, v in self.codePages.items()}

View File

@@ -24,6 +24,8 @@ from re import match as re_match
import barcode
from barcode.writer import ImageWriter
import os
from .constants import ESC, GS, NUL, QR_ECLEVEL_L, QR_ECLEVEL_M, QR_ECLEVEL_H, QR_ECLEVEL_Q
from .constants import QR_MODEL_1, QR_MODEL_2, QR_MICRO, BARCODE_TYPES, BARCODE_HEIGHT, BARCODE_WIDTH
from .constants import BARCODE_FONT_A, BARCODE_FONT_B, BARCODE_FORMATS
@@ -180,7 +182,7 @@ class Escpos(object):
self._raw(GS + b'(L' + header + m + fn + data)
def qr(self, content, ec=QR_ECLEVEL_L, size=3, model=QR_MODEL_2,
native=False, center=False):
native=False, center=False, impl="bitImageRaster"):
""" Print QR Code for the provided string
:param content: The content of the code. Numeric data will be more efficiently compacted.
@@ -193,6 +195,7 @@ class Escpos(object):
:param native: True to render the code on the printer, False to render the code as an image and send it to the
printer (Default)
:param center: Centers the code *default:* False
:param impl: Image-printing-implementation, refer to :meth:`.image()` for details
"""
# Basic validation
if ec not in [QR_ECLEVEL_L, QR_ECLEVEL_M, QR_ECLEVEL_H, QR_ECLEVEL_Q]:
@@ -222,7 +225,7 @@ class Escpos(object):
# Convert the RGB image in printable image
self.text('\n')
self.image(im, center=center)
self.image(im, center=center, impl=impl)
self.text('\n')
self.text('\n')
return
@@ -304,8 +307,8 @@ class Escpos(object):
.. todo:: For fixed-length standards with mandatory checksum (EAN, UPC),
compute and add the checksum automatically if missing.
:param bc: barcode format, see :py:func`~escpos.Escpos.barcode`
:param code: alphanumeric data to be printed as bar code, see :py:func`~escpos.Escpos.barcode`
:param bc: barcode format, see :py:meth:`.barcode()`
:param code: alphanumeric data to be printed as bar code, see :py:meth:`.barcode()`
:return: bool
"""
if bc not in BARCODE_FORMATS:
@@ -392,7 +395,7 @@ class Escpos(object):
*default*: A
:param check: If this parameter is True, the barcode format will be checked to ensure it meets the bc
requirements as defigned in the esc/pos documentation. See py:func:`~escpos.Escpos.check_barcode`
requirements as defigned in the esc/pos documentation. See :py:meth:`.check_barcode()`
for more information. *default*: True.
:raises: :py:exc:`~escpos.exceptions.BarcodeSizeError`,
@@ -487,11 +490,12 @@ class Escpos(object):
barcode_class = barcode.get_barcode_class(barcode_type)
my_code = barcode_class(data, writer=image_writer)
my_code.write("/dev/null", {
'module_height': module_height,
'module_width': module_width,
'text_distance': text_distance
})
with open(os.devnull, "wb") as nullfile:
my_code.write(nullfile, {
'module_height': module_height,
'module_width': module_width,
'text_distance': text_distance
})
# Retrieve the Pillow image and print it
image = my_code.writer._image
@@ -697,8 +701,8 @@ class Escpos(object):
else:
try:
self._raw(CD_KICK_DEC_SEQUENCE(*pin))
except:
raise CashDrawerError()
except TypeError as err:
raise CashDrawerError(err)
def linedisplay_select(self, select_display=False):
""" Selects the line display or the printer
@@ -728,6 +732,7 @@ class Escpos(object):
You should connect a line display to your printer. You can do this by daisy-chaining
the display between your computer and printer.
:param text: Text to display
"""
self.linedisplay_select(select_display=True)
@@ -827,30 +832,41 @@ class Escpos(object):
self._raw(PANEL_BUTTON_OFF)
def query_status(self, mode):
""" Queries the printer for its status, and returns an array of integers containing it.
"""
Queries the printer for its status, and returns an array of integers containing it.
:param mode: Integer that sets the status mode queried to the printer.
RT_STATUS_ONLINE: Printer status.
RT_STATUS_PAPER: Paper sensor.
:rtype: array(integer)"""
- RT_STATUS_ONLINE: Printer status.
- RT_STATUS_PAPER: Paper sensor.
:rtype: array(integer)
"""
self._raw(mode)
time.sleep(1)
status = self._read()
return status
def is_online(self):
""" Queries the printer its online status.
When online, returns True; False otherwise.
:rtype: bool: True if online, False if offline."""
"""
Queries the online status of the printer.
:returns: When online, returns ``True``; ``False`` otherwise.
:rtype: bool
"""
status = self.query_status(RT_STATUS_ONLINE)
if len(status) == 0:
return False
return not (status & RT_MASK_ONLINE)
return not (status[0] & RT_MASK_ONLINE)
def paper_status(self):
""" Queries the printer its paper status.
"""
Queries the paper status of the printer.
Returns 2 if there is plenty of paper, 1 if the paper has arrived to
the near-end sensor and 0 if there is no paper.
:rtype: int: 2: Paper is adequate. 1: Paper ending. 0: No paper."""
:returns: 2: Paper is adequate. 1: Paper ending. 0: No paper.
:rtype: int
"""
status = self.query_status(RT_STATUS_PAPER)
if len(status) == 0:
return 2
@@ -866,7 +882,7 @@ 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.
and assign it to the EscposIO class.
This example explains the usage:
.. code-block:: Python

View File

@@ -34,41 +34,58 @@ class Usb(Escpos):
"""
def __init__(self, idVendor, idProduct, timeout=0, in_ep=0x82, out_ep=0x01, *args, **kwargs): # noqa: N803
def __init__(self, idVendor, idProduct, usb_args=None, timeout=0, in_ep=0x82, out_ep=0x01,
*args, **kwargs): # noqa: N803
"""
:param idVendor: Vendor ID
:param idProduct: Product ID
:param usb_args: Optional USB arguments (e.g. custom_match)
:param timeout: Is the time limit of the USB operation. Default without timeout.
:param in_ep: Input end point
:param out_ep: Output end point
"""
Escpos.__init__(self, *args, **kwargs)
self.idVendor = idVendor
self.idProduct = idProduct
self.timeout = timeout
self.in_ep = in_ep
self.out_ep = out_ep
self.open()
def open(self):
""" Search device on USB tree and set it as escpos device """
self.device = usb.core.find(idVendor=self.idVendor, idProduct=self.idProduct)
usb_args = usb_args or {}
if idVendor:
usb_args['idVendor'] = idVendor
if idProduct:
usb_args['idProduct'] = idProduct
self.open(usb_args)
def open(self, usb_args):
""" Search device on USB tree and set it as escpos device.
:param usb_args: USB arguments
"""
self.device = usb.core.find(**usb_args)
if self.device is None:
raise USBNotFoundError("Device not found or cable not plugged in.")
check_driver = None
self.idVendor = self.device.idVendor
self.idProduct = self.device.idProduct
try:
check_driver = self.device.is_kernel_driver_active(0)
except NotImplementedError:
pass
# pyusb has three backends: libusb0, libusb1 and openusb but
# only libusb1 backend implements the methods is_kernel_driver_active()
# and detach_kernel_driver().
# This helps enable this library to work on Windows.
if self.device.backend.__module__.endswith("libusb1"):
check_driver = None
if check_driver is None or check_driver:
try:
self.device.detach_kernel_driver(0)
except usb.core.USBError as e:
if check_driver is not None:
print("Could not detatch kernel driver: {0}".format(str(e)))
check_driver = self.device.is_kernel_driver_active(0)
except NotImplementedError:
pass
if check_driver is None or check_driver:
try:
self.device.detach_kernel_driver(0)
except usb.core.USBError as e:
if check_driver is not None:
print("Could not detatch kernel driver: {0}".format(str(e)))
try:
self.device.set_configuration()
@@ -219,6 +236,11 @@ class Network(Escpos):
"""
self.device.sendall(msg)
def _read(self):
""" Read data from the TCP socket """
return self.device.recv(16)
def close(self):
""" Close TCP connection """
if self.device is not None:
@@ -312,5 +334,58 @@ class Dummy(Escpos):
""" Get the data that was sent to this printer """
return b''.join(self._output_list)
def clear(self):
""" Clear the buffer of the 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.
"""
del self._output_list[:]
def close(self):
pass
_WIN32PRINT = False
try:
import win32print
_WIN32PRINT = True
except ImportError:
pass
if _WIN32PRINT:
class Win32Raw(Escpos):
def __init__(self, printer_name=None, *args, **kwargs):
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
def open(self, job_name="python-escpos"):
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)
def close(self):
if not self.hPrinter:
return
win32print.EndPagePrinter(self.hPrinter)
win32print.EndDocPrinter(self.hPrinter)
win32print.ClosePrinter(self.hPrinter)
self.hPrinter = None
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)

View File

@@ -0,0 +1,19 @@
#!/usr/bin/python
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
import escpos.printer as printer
from escpos.exceptions import CashDrawerError
import pytest
def test_raise_CashDrawerError():
"""should raise an error if the sequence is invalid.
"""
instance = printer.Dummy()
with pytest.raises(CashDrawerError):
# call with sequence that is too long
instance.cashdraw([1,1,1,1,1,1])

View File

@@ -0,0 +1,8 @@
from nose.tools import assert_raises
from escpos.printer import Dummy
def test_printer_dummy_clear():
printer = Dummy()
printer.text("Hello")
printer.clear()
assert(printer.output == b'')

View File

@@ -82,6 +82,7 @@ def test_invalid_model():
instance.qr("1234", native=True, model="Hello")
@pytest.mark.skip("this test has to be debugged")
def test_image():
"""Test QR as image"""
instance = printer.Dummy()
@@ -109,4 +110,4 @@ def instance():
def test_center_not_implementer(instance):
with pytest.raises(NotImplementedError):
instance.qr("test", center=True, native=True)
instance.qr("test", center=True, native=True)

View File

@@ -0,0 +1,16 @@
#!/usr/bin/python
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 pytest
def test_soft_barcode():
"""just execute soft_barcode
"""
instance = printer.Dummy()
instance.soft_barcode("ean8", "1234")

View File

@@ -27,6 +27,7 @@ else:
mock_open_call = '__builtin__.open'
@pytest.mark.skip("this test is broken and has to be fixed or discarded")
@settings(use_coverage=False)
@given(path=text())
def test_load_file_printer(mocker, path):
@@ -38,6 +39,7 @@ def test_load_file_printer(mocker, path):
mock_open.assert_called_with(path, "wb")
@pytest.mark.skip("this test is broken and has to be fixed or discarded")
@settings(deadline=None, use_coverage=False)
@given(txt=text())
def test_auto_flush(mocker, txt):
@@ -59,6 +61,7 @@ def test_auto_flush(mocker, txt):
assert mock_device.flush.called
@pytest.mark.skip("this test is broken and has to be fixed or discarded")
@settings(deadline=None, use_coverage=False)
@given(txt=text())
def test_flush_on_close(mocker, txt):

View File

@@ -1,5 +1,5 @@
[tox]
envlist = py27, py34, py35, docs, flake8
envlist = py27, py34, py35, py36, py37, docs, flake8
[testenv]
deps = nose
@@ -7,12 +7,13 @@ deps = nose
coverage
scripttest
mock
pytest!=3.2.0
pytest!=3.2.0,!=3.3.0
pytest-cov
pytest-mock
hypothesis
hypothesis!=3.56.9,<4
viivakoodi
commands = py.test --cov escpos
passenv = ESCPOS_CAPABILITIES_PICKLE_DIR ESCPOS_CAPABILITIES_FILE CI TRAVIS TRAVIS_* APPVEYOR APPVEYOR_* CODECOV_*
[testenv:docs]
basepython = python