commit
4ecab402b8
1
.mailmap
1
.mailmap
|
@ -12,3 +12,4 @@ Juanmi Taboada <juanmi@juanmitaboada.com> Juanmi Taboada <juanmi@juan
|
|||
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>
|
||||
|
|
16
.travis.yml
16
.travis.yml
|
@ -1,6 +1,7 @@
|
|||
language: python
|
||||
sudo: false
|
||||
cache: pip
|
||||
dist: xenial
|
||||
git:
|
||||
depth: 100000
|
||||
addons:
|
||||
|
@ -22,23 +23,26 @@ matrix:
|
|||
env: TOXENV=py36
|
||||
- python: 3.6-dev
|
||||
env: TOXENV=py36
|
||||
- python: 3.7
|
||||
env: TOXENV=py37
|
||||
- python: 3.7-dev
|
||||
env: TOXENV=py37
|
||||
- python: 3.8-dev
|
||||
env: TOXENV=py38
|
||||
- python: nightly
|
||||
env: TOXENV=py37
|
||||
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: 3.6-dev
|
||||
- python: 3.7-dev
|
||||
- python: 3.8-dev
|
||||
- python: nightly
|
||||
- python: pypy3
|
||||
before_install:
|
||||
|
@ -63,4 +67,4 @@ deploy:
|
|||
tags: true
|
||||
repo: python-escpos/python-escpos
|
||||
branch: master
|
||||
condition: $TRAVIS_PYTHON_VERSION = "3.6"
|
||||
condition: $TRAVIS_PYTHON_VERSION = "3.7"
|
||||
|
|
6
AUTHORS
6
AUTHORS
|
@ -1,4 +1,6 @@
|
|||
Ahmed Tahri
|
||||
akeonly
|
||||
Alex Debiasio
|
||||
Asuki Kono
|
||||
belono
|
||||
Christoph Heuel
|
||||
|
@ -8,8 +10,10 @@ Curtis // mashedkeyboard
|
|||
Davis Goglin
|
||||
Dean Rispin
|
||||
Dmytro Katyukha
|
||||
Gerard Marull-Paretas
|
||||
Hark
|
||||
Joel Lehtonen
|
||||
Justin Vieira
|
||||
kennedy
|
||||
Kristi
|
||||
ldos
|
||||
|
@ -19,9 +23,11 @@ Michael Billington
|
|||
Michael Elsdörfer
|
||||
mrwunderbar666
|
||||
Nathan Bookham
|
||||
Omer Akram
|
||||
Patrick Kanzler
|
||||
primax79
|
||||
Qian Linfeng
|
||||
Ramon Poca
|
||||
reck31
|
||||
Renato Lorenzi
|
||||
Romain Porte
|
||||
|
|
|
@ -1,6 +1,29 @@
|
|||
*********
|
||||
Changelog
|
||||
*********
|
||||
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
|
||||
|
|
13
README.rst
13
README.rst
|
@ -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
|
||||
|
|
|
@ -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
|
||||
------------------
|
||||
|
|
4
setup.py
4
setup.py
|
@ -65,8 +65,6 @@ 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.4',
|
||||
'Programming Language :: Python :: 3.5',
|
||||
|
@ -102,7 +100,7 @@ setup(
|
|||
'nose',
|
||||
'scripttest',
|
||||
'mock',
|
||||
'hypothesis!=3.56.9',
|
||||
'hypothesis!=3.56.9,<4',
|
||||
'flake8'
|
||||
],
|
||||
entry_points={
|
||||
|
|
|
@ -38,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)
|
||||
|
|
|
@ -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:
|
||||
|
@ -322,3 +344,48 @@ class Dummy(Escpos):
|
|||
|
||||
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)
|
||||
|
|
4
tox.ini
4
tox.ini
|
@ -1,5 +1,5 @@
|
|||
[tox]
|
||||
envlist = py27, py34, py35, docs, flake8
|
||||
envlist = py27, py34, py35, py36, py37, docs, flake8
|
||||
|
||||
[testenv]
|
||||
deps = nose
|
||||
|
@ -10,7 +10,7 @@ deps = nose
|
|||
pytest!=3.2.0,!=3.3.0
|
||||
pytest-cov
|
||||
pytest-mock
|
||||
hypothesis!=3.56.9
|
||||
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_*
|
||||
|
|
Loading…
Reference in New Issue