mirror of
https://github.com/python-escpos/python-escpos
synced 2025-09-13 09:09:58 +00:00
Compare commits
70 Commits
v3.0a3
...
update-rea
Author | SHA1 | Date | |
---|---|---|---|
![]() |
ea9a7b3fbb | ||
![]() |
02a47d413c | ||
![]() |
1f9e7bd45a | ||
![]() |
062660e00f | ||
![]() |
6a8cc54b97 | ||
![]() |
6c6fe9bccf | ||
![]() |
c5e46a888d | ||
![]() |
46942820a5 | ||
![]() |
e50e295acc | ||
![]() |
2d7458fa49 | ||
![]() |
a6f635c0d5 | ||
![]() |
2d0f045457 | ||
![]() |
293b8632ff | ||
![]() |
5ff73595b6 | ||
![]() |
4ecab402b8 | ||
![]() |
c56e43da84 | ||
![]() |
88af26f46e | ||
![]() |
9dd966c2a3 | ||
![]() |
a7d959428f | ||
![]() |
8bf0e08659 | ||
![]() |
5ac5a24b50 | ||
![]() |
63252515b5 | ||
![]() |
29a546821b | ||
![]() |
4ddd18279f | ||
![]() |
de761e96e3 | ||
![]() |
ed7bce6932 | ||
![]() |
edd567785c | ||
![]() |
f1054876da | ||
![]() |
490e0657dd | ||
![]() |
b4c32b5a4a | ||
![]() |
40b30225d3 | ||
![]() |
19e3ec6895 | ||
![]() |
df539da854 | ||
![]() |
4534038b39 | ||
![]() |
adf85f7784 | ||
![]() |
aaa8162967 | ||
![]() |
0461adc212 | ||
![]() |
91ff83e506 | ||
![]() |
29ef88f591 | ||
![]() |
7c01a30d6c | ||
![]() |
035c425581 | ||
![]() |
d20646b2a9 | ||
![]() |
206822ac69 | ||
![]() |
dc08792e72 | ||
![]() |
2886075ce9 | ||
![]() |
73fff6291d | ||
![]() |
d5b9d99093 | ||
![]() |
18c51358aa | ||
![]() |
52719c0b7d | ||
![]() |
0051c876bf | ||
![]() |
854759d312 | ||
![]() |
a0343c66af | ||
![]() |
6c94f88c24 | ||
![]() |
6fb23d6826 | ||
![]() |
f649814091 | ||
![]() |
47b4d41b28 | ||
![]() |
599f4f3ca5 | ||
![]() |
d085e5c467 | ||
![]() |
b418302311 | ||
![]() |
f6acb72bbe | ||
![]() |
0c9856c1f6 | ||
![]() |
a748563395 | ||
![]() |
b84e280efb | ||
![]() |
4390dc4a9c | ||
![]() |
6e09fd1e97 | ||
![]() |
100c6b5e89 | ||
![]() |
26d72a69f0 | ||
![]() |
01e28bbcf6 | ||
![]() |
2a7e2a6a36 | ||
![]() |
3c3dab95f5 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -20,6 +20,7 @@ dist/
|
|||||||
.coverage
|
.coverage
|
||||||
src/escpos/version.py
|
src/escpos/version.py
|
||||||
.hypothesis
|
.hypothesis
|
||||||
|
.pytest_cache/
|
||||||
|
|
||||||
# testing temporary directories
|
# testing temporary directories
|
||||||
test/test-cli-output/
|
test/test-cli-output/
|
||||||
|
1
.gitmodules
vendored
1
.gitmodules
vendored
@@ -1,3 +1,4 @@
|
|||||||
[submodule "capabilities-data"]
|
[submodule "capabilities-data"]
|
||||||
path = capabilities-data
|
path = capabilities-data
|
||||||
url = https://github.com/receipt-print-hq/escpos-printer-db.git
|
url = https://github.com/receipt-print-hq/escpos-printer-db.git
|
||||||
|
branch = master
|
||||||
|
3
.mailmap
3
.mailmap
@@ -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>
|
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>
|
Ahmed Tahri <nyuubi.10@gmail.com> TAHRI Ahmed <nyuubi.10@gmail.com>
|
||||||
Michael Elsdörfer <michael@elsdoerfer.com> Michael Elsdörfer <michael@elsdoerfer.info>
|
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>
|
csoft2k <csoft2k@hotmail.com>
|
||||||
Sergio Pulgarin <sergio.pulgarin@gmail.com>
|
Sergio Pulgarin <sergio.pulgarin@gmail.com>
|
||||||
|
reck31 <rakesh.gunduka@gmail.com>
|
||||||
|
Alex Debiasio <alex.debiasio@thinkin.io> <alex.debiasio@studenti.unitn.it>
|
||||||
|
10
.readthedocs.yml
Normal file
10
.readthedocs.yml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
version: 2
|
||||||
|
formats:
|
||||||
|
- pdf
|
||||||
|
- epub
|
||||||
|
python:
|
||||||
|
version: 3.7
|
||||||
|
install:
|
||||||
|
- requirements: doc/requirements.txt
|
||||||
|
- method: setuptools
|
||||||
|
path: .
|
43
.travis.yml
43
.travis.yml
@@ -1,18 +1,36 @@
|
|||||||
language: python
|
language: python
|
||||||
sudo: false
|
sudo: false
|
||||||
cache: pip
|
cache: pip
|
||||||
|
dist: xenial
|
||||||
git:
|
git:
|
||||||
depth: 100000
|
depth: 100000
|
||||||
addons:
|
addons:
|
||||||
apt:
|
apt:
|
||||||
packages:
|
packages:
|
||||||
- graphviz
|
- graphviz
|
||||||
|
env:
|
||||||
|
global:
|
||||||
|
- ESCPOS_CAPABILITIES_FILE=/home/travis/build/python-escpos/python-escpos/capabilities-data/dist/capabilities.json
|
||||||
matrix:
|
matrix:
|
||||||
|
fast_finish: true
|
||||||
include:
|
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
|
- python: 2.7
|
||||||
env: TOXENV=py27
|
env: TOXENV=py27
|
||||||
- python: 3.3
|
|
||||||
env: TOXENV=py33
|
|
||||||
- python: 3.4
|
- python: 3.4
|
||||||
env: TOXENV=py34
|
env: TOXENV=py34
|
||||||
- python: 3.5
|
- python: 3.5
|
||||||
@@ -21,22 +39,31 @@ matrix:
|
|||||||
env: TOXENV=py36
|
env: TOXENV=py36
|
||||||
- python: 3.6-dev
|
- python: 3.6-dev
|
||||||
env: TOXENV=py36
|
env: TOXENV=py36
|
||||||
- python: nightly
|
- python: 3.7
|
||||||
env: TOXENV=py37
|
env: TOXENV=py37
|
||||||
|
- python: 3.7-dev
|
||||||
|
env: TOXENV=py37
|
||||||
|
- python: 3.8-dev
|
||||||
|
env: TOXENV=py38
|
||||||
|
- python: nightly
|
||||||
|
env: TOXENV=py38
|
||||||
- python: pypy
|
- python: pypy
|
||||||
env: TOXENV=pypy
|
env: TOXENV=pypy
|
||||||
- python: pypy3
|
- python: pypy3
|
||||||
env: TOXENV=pypy3
|
env: TOXENV=pypy3
|
||||||
- python: 2.7
|
- python: 3.7
|
||||||
env: TOXENV=docs
|
env: TOXENV=docs
|
||||||
- python: 2.7
|
- python: 3.7
|
||||||
env: TOXENV=flake8
|
|
||||||
- python: 3.6
|
|
||||||
env: TOXENV=flake8
|
env: TOXENV=flake8
|
||||||
allow_failures:
|
allow_failures:
|
||||||
|
- python: 2.7
|
||||||
- python: 3.6-dev
|
- python: 3.6-dev
|
||||||
|
- python: 3.7-dev
|
||||||
|
- python: 3.8-dev
|
||||||
- python: nightly
|
- python: nightly
|
||||||
- python: pypy3
|
- python: pypy3
|
||||||
|
- os: windows
|
||||||
|
- os: osx
|
||||||
before_install:
|
before_install:
|
||||||
- pip install tox codecov 'sphinx>=1.5.1'
|
- pip install tox codecov 'sphinx>=1.5.1'
|
||||||
- ./doc/generate_authors.sh --check
|
- ./doc/generate_authors.sh --check
|
||||||
@@ -59,4 +86,4 @@ deploy:
|
|||||||
tags: true
|
tags: true
|
||||||
repo: python-escpos/python-escpos
|
repo: python-escpos/python-escpos
|
||||||
branch: master
|
branch: master
|
||||||
condition: $TRAVIS_PYTHON_VERSION = "3.5"
|
condition: $TRAVIS_PYTHON_VERSION = "3.7"
|
||||||
|
9
AUTHORS
9
AUTHORS
@@ -1,4 +1,6 @@
|
|||||||
Ahmed Tahri
|
Ahmed Tahri
|
||||||
|
akeonly
|
||||||
|
Alex Debiasio
|
||||||
Asuki Kono
|
Asuki Kono
|
||||||
belono
|
belono
|
||||||
Christoph Heuel
|
Christoph Heuel
|
||||||
@@ -8,8 +10,11 @@ Curtis // mashedkeyboard
|
|||||||
Davis Goglin
|
Davis Goglin
|
||||||
Dean Rispin
|
Dean Rispin
|
||||||
Dmytro Katyukha
|
Dmytro Katyukha
|
||||||
|
Gerard Marull-Paretas
|
||||||
Hark
|
Hark
|
||||||
Joel Lehtonen
|
Joel Lehtonen
|
||||||
|
Justin Vieira
|
||||||
|
kennedy
|
||||||
Kristi
|
Kristi
|
||||||
ldos
|
ldos
|
||||||
Lucy Linder
|
Lucy Linder
|
||||||
@@ -18,8 +23,12 @@ Michael Billington
|
|||||||
Michael Elsdörfer
|
Michael Elsdörfer
|
||||||
mrwunderbar666
|
mrwunderbar666
|
||||||
Nathan Bookham
|
Nathan Bookham
|
||||||
|
Omer Akram
|
||||||
Patrick Kanzler
|
Patrick Kanzler
|
||||||
|
primax79
|
||||||
Qian Linfeng
|
Qian Linfeng
|
||||||
|
Ramon Poca
|
||||||
|
reck31
|
||||||
Renato Lorenzi
|
Renato Lorenzi
|
||||||
Romain Porte
|
Romain Porte
|
||||||
Sam Cheng
|
Sam Cheng
|
||||||
|
@@ -1,6 +1,53 @@
|
|||||||
*********
|
*********
|
||||||
Changelog
|
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
|
||||||
|
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"
|
2017-10-08 - Version 3.0a3 - "Just Testing"
|
||||||
-------------------------------------------
|
-------------------------------------------
|
||||||
This release is the fourth alpha release of the new version 3.0. Please
|
This release is the fourth 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.barcode('1324354657687', 'EAN13', 64, 2, '', '')
|
||||||
p.cut()
|
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>`_.
|
The full project-documentation is available on `Read the Docs <https://python-escpos.readthedocs.io>`_.
|
||||||
|
|
||||||
Contributing
|
Contributing
|
||||||
|
Submodule capabilities-data updated: fd207aa9de...8885283d71
@@ -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"
|
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
|
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
|
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
|
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
|
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
|
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.
|
node, then you don't necessary need to pass the node name.
|
||||||
@@ -108,17 +111,17 @@ on a USB interface.
|
|||||||
|
|
||||||
from escpos import *
|
from escpos import *
|
||||||
""" Seiko Epson Corp. Receipt Printer M129 Definitions (EPSON TM-T88IV) """
|
""" Seiko Epson Corp. Receipt Printer M129 Definitions (EPSON TM-T88IV) """
|
||||||
Epson = printer.Usb(0x04b8,0x0202)
|
p = printer.Usb(0x04b8,0x0202)
|
||||||
# Print text
|
# Print text
|
||||||
Epson.text("Hello World\n")
|
p.text("Hello World\n")
|
||||||
# Print image
|
# Print image
|
||||||
Epson.image("logo.gif")
|
p.image("logo.gif")
|
||||||
# Print QR Code
|
# Print QR Code
|
||||||
Epson.qr("You can readme from your smartphone")
|
p.qr("You can readme from your smartphone")
|
||||||
# Print barcode
|
# Print barcode
|
||||||
Epson.barcode('1324354657687','EAN13',64,2,'','')
|
p.barcode('1324354657687','EAN13',64,2,'','')
|
||||||
# Cut paper
|
# Cut paper
|
||||||
Epson.cut()
|
p.cut()
|
||||||
|
|
||||||
Configuration File
|
Configuration File
|
||||||
------------------
|
------------------
|
||||||
|
@@ -1,7 +0,0 @@
|
|||||||
formats:
|
|
||||||
- pdf
|
|
||||||
- epub
|
|
||||||
requirements_file: doc/requirements.txt
|
|
||||||
python:
|
|
||||||
version: 2
|
|
||||||
setup_py_install: true
|
|
36
setup.py
36
setup.py
@@ -3,7 +3,6 @@
|
|||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
from setuptools import find_packages, setup
|
from setuptools import find_packages, setup
|
||||||
from setuptools.command.test import test as test_command
|
|
||||||
|
|
||||||
|
|
||||||
base_dir = os.path.dirname(__file__)
|
base_dir = os.path.dirname(__file__)
|
||||||
@@ -19,33 +18,6 @@ def read(fname):
|
|||||||
return open(os.path.join(os.path.dirname(__file__), fname)).read()
|
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 = """\
|
setuptools_scm_template = """\
|
||||||
# coding: utf-8
|
# coding: utf-8
|
||||||
# file generated by setuptools_scm
|
# file generated by setuptools_scm
|
||||||
@@ -93,10 +65,7 @@ setup(
|
|||||||
'License :: OSI Approved :: MIT License',
|
'License :: OSI Approved :: MIT License',
|
||||||
'Operating System :: OS Independent',
|
'Operating System :: OS Independent',
|
||||||
'Programming Language :: Python',
|
'Programming Language :: Python',
|
||||||
'Programming Language :: Python :: 2',
|
|
||||||
'Programming Language :: Python :: 2.7',
|
|
||||||
'Programming Language :: Python :: 3',
|
'Programming Language :: Python :: 3',
|
||||||
'Programming Language :: Python :: 3.3',
|
|
||||||
'Programming Language :: Python :: 3.4',
|
'Programming Language :: Python :: 3.4',
|
||||||
'Programming Language :: Python :: 3.5',
|
'Programming Language :: Python :: 3.5',
|
||||||
'Programming Language :: Python :: 3.6',
|
'Programming Language :: Python :: 3.6',
|
||||||
@@ -125,16 +94,15 @@ setup(
|
|||||||
tests_require=[
|
tests_require=[
|
||||||
'jaconv',
|
'jaconv',
|
||||||
'tox',
|
'tox',
|
||||||
'pytest!=3.2.0',
|
'pytest!=3.2.0,!=3.3.0',
|
||||||
'pytest-cov',
|
'pytest-cov',
|
||||||
'pytest-mock',
|
'pytest-mock',
|
||||||
'nose',
|
'nose',
|
||||||
'scripttest',
|
'scripttest',
|
||||||
'mock',
|
'mock',
|
||||||
'hypothesis',
|
'hypothesis!=3.56.9,<4',
|
||||||
'flake8'
|
'flake8'
|
||||||
],
|
],
|
||||||
cmdclass={'test': Tox},
|
|
||||||
entry_points={
|
entry_points={
|
||||||
'console_scripts': [
|
'console_scripts': [
|
||||||
'python-escpos = escpos.cli:main'
|
'python-escpos = escpos.cli:main'
|
||||||
|
@@ -7,13 +7,14 @@ import time
|
|||||||
import six
|
import six
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
|
from tempfile import gettempdir
|
||||||
|
import platform
|
||||||
|
|
||||||
logging.basicConfig()
|
logging.basicConfig()
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
pickle_dir = environ.get('ESCPOS_CAPABILITIES_PICKLE_DIR', gettempdir())
|
||||||
pickle_dir = environ.get('ESCPOS_CAPABILITIES_PICKLE_DIR', '/tmp/')
|
pickle_path = path.join(pickle_dir, '{v}.capabilities.pickle'.format(v=platform.python_version()))
|
||||||
pickle_path = path.join(pickle_dir, 'capabilities.pickle')
|
|
||||||
capabilities_path = environ.get(
|
capabilities_path = environ.get(
|
||||||
'ESCPOS_CAPABILITIES_FILE',
|
'ESCPOS_CAPABILITIES_FILE',
|
||||||
path.join(path.dirname(__file__), 'capabilities.json'))
|
path.join(path.dirname(__file__), 'capabilities.json'))
|
||||||
@@ -37,7 +38,7 @@ else:
|
|||||||
if full_load:
|
if full_load:
|
||||||
logger.debug('Loading and pickling capabilities')
|
logger.debug('Loading and pickling capabilities')
|
||||||
with open(capabilities_path) as cp, open(pickle_path, 'wb') as pp:
|
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)
|
pickle.dump(CAPABILITIES, pp, protocol=2)
|
||||||
|
|
||||||
logger.debug('Finished loading capabilities took %.2fs', time.time() - t0)
|
logger.debug('Finished loading capabilities took %.2fs', time.time() - t0)
|
||||||
@@ -47,7 +48,7 @@ PROFILES = CAPABILITIES['profiles']
|
|||||||
|
|
||||||
|
|
||||||
class NotSupported(Exception):
|
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.
|
printer profile.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
@@ -90,7 +91,7 @@ class BaseProfile(object):
|
|||||||
return self.features.get(feature)
|
return self.features.get(feature)
|
||||||
|
|
||||||
def get_code_pages(self):
|
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()}
|
return {v: k for k, v in self.codePages.items()}
|
||||||
|
|
||||||
|
@@ -24,6 +24,8 @@ from re import match as re_match
|
|||||||
import barcode
|
import barcode
|
||||||
from barcode.writer import ImageWriter
|
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 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 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
|
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)
|
self._raw(GS + b'(L' + header + m + fn + data)
|
||||||
|
|
||||||
def qr(self, content, ec=QR_ECLEVEL_L, size=3, model=QR_MODEL_2,
|
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
|
""" Print QR Code for the provided string
|
||||||
|
|
||||||
:param content: The content of the code. Numeric data will be more efficiently compacted.
|
: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
|
: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)
|
printer (Default)
|
||||||
:param center: Centers the code *default:* False
|
:param center: Centers the code *default:* False
|
||||||
|
:param impl: Image-printing-implementation, refer to :meth:`.image()` for details
|
||||||
"""
|
"""
|
||||||
# Basic validation
|
# Basic validation
|
||||||
if ec not in [QR_ECLEVEL_L, QR_ECLEVEL_M, QR_ECLEVEL_H, QR_ECLEVEL_Q]:
|
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
|
# Convert the RGB image in printable image
|
||||||
self.text('\n')
|
self.text('\n')
|
||||||
self.image(im, center=center)
|
self.image(im, center=center, impl=impl)
|
||||||
self.text('\n')
|
self.text('\n')
|
||||||
self.text('\n')
|
self.text('\n')
|
||||||
return
|
return
|
||||||
@@ -304,8 +307,8 @@ class Escpos(object):
|
|||||||
.. todo:: For fixed-length standards with mandatory checksum (EAN, UPC),
|
.. todo:: For fixed-length standards with mandatory checksum (EAN, UPC),
|
||||||
compute and add the checksum automatically if missing.
|
compute and add the checksum automatically if missing.
|
||||||
|
|
||||||
:param bc: barcode format, 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:func`~escpos.Escpos.barcode`
|
:param code: alphanumeric data to be printed as bar code, see :py:meth:`.barcode()`
|
||||||
:return: bool
|
:return: bool
|
||||||
"""
|
"""
|
||||||
if bc not in BARCODE_FORMATS:
|
if bc not in BARCODE_FORMATS:
|
||||||
@@ -392,7 +395,7 @@ class Escpos(object):
|
|||||||
*default*: A
|
*default*: A
|
||||||
|
|
||||||
:param check: If this parameter is True, the barcode format will be checked to ensure it meets the bc
|
: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.
|
for more information. *default*: True.
|
||||||
|
|
||||||
:raises: :py:exc:`~escpos.exceptions.BarcodeSizeError`,
|
:raises: :py:exc:`~escpos.exceptions.BarcodeSizeError`,
|
||||||
@@ -487,7 +490,8 @@ class Escpos(object):
|
|||||||
barcode_class = barcode.get_barcode_class(barcode_type)
|
barcode_class = barcode.get_barcode_class(barcode_type)
|
||||||
my_code = barcode_class(data, writer=image_writer)
|
my_code = barcode_class(data, writer=image_writer)
|
||||||
|
|
||||||
my_code.write("/dev/null", {
|
with open(os.devnull, "wb") as nullfile:
|
||||||
|
my_code.write(nullfile, {
|
||||||
'module_height': module_height,
|
'module_height': module_height,
|
||||||
'module_width': module_width,
|
'module_width': module_width,
|
||||||
'text_distance': text_distance
|
'text_distance': text_distance
|
||||||
@@ -697,8 +701,8 @@ class Escpos(object):
|
|||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
self._raw(CD_KICK_DEC_SEQUENCE(*pin))
|
self._raw(CD_KICK_DEC_SEQUENCE(*pin))
|
||||||
except:
|
except TypeError as err:
|
||||||
raise CashDrawerError()
|
raise CashDrawerError(err)
|
||||||
|
|
||||||
def linedisplay_select(self, select_display=False):
|
def linedisplay_select(self, select_display=False):
|
||||||
""" Selects the line display or the printer
|
""" 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
|
You should connect a line display to your printer. You can do this by daisy-chaining
|
||||||
the display between your computer and printer.
|
the display between your computer and printer.
|
||||||
|
|
||||||
:param text: Text to display
|
:param text: Text to display
|
||||||
"""
|
"""
|
||||||
self.linedisplay_select(select_display=True)
|
self.linedisplay_select(select_display=True)
|
||||||
@@ -827,30 +832,41 @@ class Escpos(object):
|
|||||||
self._raw(PANEL_BUTTON_OFF)
|
self._raw(PANEL_BUTTON_OFF)
|
||||||
|
|
||||||
def query_status(self, mode):
|
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.
|
:param mode: Integer that sets the status mode queried to the printer.
|
||||||
RT_STATUS_ONLINE: Printer status.
|
- RT_STATUS_ONLINE: Printer status.
|
||||||
RT_STATUS_PAPER: Paper sensor.
|
- RT_STATUS_PAPER: Paper sensor.
|
||||||
:rtype: array(integer)"""
|
:rtype: array(integer)
|
||||||
|
"""
|
||||||
self._raw(mode)
|
self._raw(mode)
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
status = self._read()
|
status = self._read()
|
||||||
return status
|
return status
|
||||||
|
|
||||||
def is_online(self):
|
def is_online(self):
|
||||||
""" Queries the printer its online status.
|
"""
|
||||||
When online, returns True; False otherwise.
|
Queries the online status of the printer.
|
||||||
:rtype: bool: True if online, False if offline."""
|
|
||||||
|
:returns: When online, returns ``True``; ``False`` otherwise.
|
||||||
|
:rtype: bool
|
||||||
|
"""
|
||||||
status = self.query_status(RT_STATUS_ONLINE)
|
status = self.query_status(RT_STATUS_ONLINE)
|
||||||
if len(status) == 0:
|
if len(status) == 0:
|
||||||
return False
|
return False
|
||||||
return not (status & RT_MASK_ONLINE)
|
return not (status[0] & RT_MASK_ONLINE)
|
||||||
|
|
||||||
def paper_status(self):
|
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
|
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.
|
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)
|
status = self.query_status(RT_STATUS_PAPER)
|
||||||
if len(status) == 0:
|
if len(status) == 0:
|
||||||
return 2
|
return 2
|
||||||
@@ -866,7 +882,7 @@ class EscposIO(object):
|
|||||||
"""ESC/POS Printer IO object
|
"""ESC/POS Printer IO object
|
||||||
|
|
||||||
Allows the class to be used together with the `with`-statement. You have to define a printer instance
|
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:
|
This example explains the usage:
|
||||||
|
|
||||||
.. code-block:: Python
|
.. code-block:: Python
|
||||||
|
@@ -34,28 +34,45 @@ 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 idVendor: Vendor ID
|
||||||
:param idProduct: Product 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 timeout: Is the time limit of the USB operation. Default without timeout.
|
||||||
:param in_ep: Input end point
|
:param in_ep: Input end point
|
||||||
:param out_ep: Output end point
|
:param out_ep: Output end point
|
||||||
"""
|
"""
|
||||||
Escpos.__init__(self, *args, **kwargs)
|
Escpos.__init__(self, *args, **kwargs)
|
||||||
self.idVendor = idVendor
|
|
||||||
self.idProduct = idProduct
|
|
||||||
self.timeout = timeout
|
self.timeout = timeout
|
||||||
self.in_ep = in_ep
|
self.in_ep = in_ep
|
||||||
self.out_ep = out_ep
|
self.out_ep = out_ep
|
||||||
self.open()
|
|
||||||
|
|
||||||
def open(self):
|
usb_args = usb_args or {}
|
||||||
""" Search device on USB tree and set it as escpos device """
|
if idVendor:
|
||||||
self.device = usb.core.find(idVendor=self.idVendor, idProduct=self.idProduct)
|
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:
|
if self.device is None:
|
||||||
raise USBNotFoundError("Device not found or cable not plugged in.")
|
raise USBNotFoundError("Device not found or cable not plugged in.")
|
||||||
|
|
||||||
|
self.idVendor = self.device.idVendor
|
||||||
|
self.idProduct = self.device.idProduct
|
||||||
|
|
||||||
|
# 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
|
check_driver = None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -219,6 +236,11 @@ class Network(Escpos):
|
|||||||
"""
|
"""
|
||||||
self.device.sendall(msg)
|
self.device.sendall(msg)
|
||||||
|
|
||||||
|
def _read(self):
|
||||||
|
""" Read data from the TCP socket """
|
||||||
|
|
||||||
|
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:
|
||||||
@@ -312,5 +334,58 @@ class Dummy(Escpos):
|
|||||||
""" 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):
|
||||||
|
""" 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):
|
def close(self):
|
||||||
pass
|
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)
|
||||||
|
19
test/test_function_cashdraw.py
Normal file
19
test/test_function_cashdraw.py
Normal 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])
|
||||||
|
|
8
test/test_function_dummy_clear.py
Normal file
8
test/test_function_dummy_clear.py
Normal 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'')
|
@@ -82,6 +82,7 @@ def test_invalid_model():
|
|||||||
instance.qr("1234", native=True, model="Hello")
|
instance.qr("1234", native=True, model="Hello")
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.skip("this test has to be debugged")
|
||||||
def test_image():
|
def test_image():
|
||||||
"""Test QR as image"""
|
"""Test QR as image"""
|
||||||
instance = printer.Dummy()
|
instance = printer.Dummy()
|
||||||
|
16
test/test_function_softbarcode.py
Normal file
16
test/test_function_softbarcode.py
Normal 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")
|
||||||
|
|
@@ -27,6 +27,7 @@ else:
|
|||||||
mock_open_call = '__builtin__.open'
|
mock_open_call = '__builtin__.open'
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.skip("this test is broken and has to be fixed or discarded")
|
||||||
@settings(use_coverage=False)
|
@settings(use_coverage=False)
|
||||||
@given(path=text())
|
@given(path=text())
|
||||||
def test_load_file_printer(mocker, path):
|
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")
|
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)
|
@settings(deadline=None, use_coverage=False)
|
||||||
@given(txt=text())
|
@given(txt=text())
|
||||||
def test_auto_flush(mocker, txt):
|
def test_auto_flush(mocker, txt):
|
||||||
@@ -59,6 +61,7 @@ def test_auto_flush(mocker, txt):
|
|||||||
assert mock_device.flush.called
|
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)
|
@settings(deadline=None, use_coverage=False)
|
||||||
@given(txt=text())
|
@given(txt=text())
|
||||||
def test_flush_on_close(mocker, txt):
|
def test_flush_on_close(mocker, txt):
|
||||||
|
7
tox.ini
7
tox.ini
@@ -1,5 +1,5 @@
|
|||||||
[tox]
|
[tox]
|
||||||
envlist = py27, py34, py35, docs, flake8
|
envlist = py27, py34, py35, py36, py37, docs, flake8
|
||||||
|
|
||||||
[testenv]
|
[testenv]
|
||||||
deps = nose
|
deps = nose
|
||||||
@@ -7,12 +7,13 @@ deps = nose
|
|||||||
coverage
|
coverage
|
||||||
scripttest
|
scripttest
|
||||||
mock
|
mock
|
||||||
pytest!=3.2.0
|
pytest!=3.2.0,!=3.3.0
|
||||||
pytest-cov
|
pytest-cov
|
||||||
pytest-mock
|
pytest-mock
|
||||||
hypothesis
|
hypothesis!=3.56.9,<4
|
||||||
viivakoodi
|
viivakoodi
|
||||||
commands = py.test --cov escpos
|
commands = py.test --cov escpos
|
||||||
|
passenv = ESCPOS_CAPABILITIES_PICKLE_DIR ESCPOS_CAPABILITIES_FILE CI TRAVIS TRAVIS_* APPVEYOR APPVEYOR_* CODECOV_*
|
||||||
|
|
||||||
[testenv:docs]
|
[testenv:docs]
|
||||||
basepython = python
|
basepython = python
|
||||||
|
Reference in New Issue
Block a user