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

111 Commits

Author SHA1 Message Date
Patrick Kanzler
557991d80b Merge pull request #388 from python-escpos/development
v3.0a7
2020-05-09 01:45:25 +02:00
Patrick Kanzler
fe08fc1469 drop pypy 2020-05-09 01:35:00 +02:00
Patrick Kanzler
6c27222aeb use bionic on travis 2020-05-09 01:30:38 +02:00
Patrick Kanzler
6731057456 checkout submodules on github 2020-05-09 01:25:28 +02:00
Patrick Kanzler
f0b1a89c48 fix syntax 2020-05-09 01:19:32 +02:00
Patrick Kanzler
fd7bd0710e set path to capabilities file 2020-05-09 01:11:38 +02:00
Patrick Kanzler
7ea58625e6 use tox plugin for github 2020-05-09 01:08:16 +02:00
Patrick Kanzler
baffd98a22 use focal on travis 2020-05-09 01:05:35 +02:00
Patrick Kanzler
ecbdd43dff install tox in github ci 2020-05-09 01:03:45 +02:00
Patrick Kanzler
5b6b96d2a0 update changelog 2020-05-09 00:58:54 +02:00
Patrick Kanzler
7aa20a60e3 update capabilities 2020-05-09 00:40:05 +02:00
Patrick Kanzler
95ec6d5c08 update hypothesis 2020-05-09 00:39:41 +02:00
Patrick Kanzler
18c3a5f298 add capabilities to manifest 2020-05-09 00:37:35 +02:00
Patrick Kanzler
4836dcd486 change pytest call in tox 2020-05-09 00:27:58 +02:00
Patrick Kanzler
d9d400da6d ignore vscode settings 2020-05-09 00:07:35 +02:00
Patrick Kanzler
fe2e1a6d28 add tox task for vscode 2020-05-09 00:07:02 +02:00
Patrick Kanzler
c53575a155 update tox config 2020-05-09 00:02:28 +02:00
Patrick Kanzler
cadf448c38 update travis 2020-05-08 23:53:35 +02:00
Patrick Kanzler
7c05404ac4 build docs with python 3 2020-05-08 23:51:06 +02:00
Patrick Kanzler
e1e1ccb3f2 update trove identifiers 2020-05-08 23:50:28 +02:00
Patrick Kanzler
32c56e78ea simplify branching model 2020-05-08 23:48:48 +02:00
Patrick Kanzler
4d106e8659 Create pythonpackage.yml 2020-05-08 23:34:24 +02:00
Patrick Kanzler
ddab5318cf Merge pull request #380 from mofosyne/development
Add to readme Serial usage example
2020-05-08 23:21:59 +02:00
Patrick Kanzler
9b60e2e3ab Merge pull request #381 from Foaly/feature/image-center-doc
Added some documentation and error handling to the image center flag.
2020-05-08 23:21:17 +02:00
Patrick Kanzler
34cd1ebde1 readd authors 2020-05-08 23:19:47 +02:00
Patrick Kanzler
a2db415559 remove authors 2020-05-08 23:19:31 +02:00
Patrick Kanzler
4e19b0ca51 Merge branch 'development' into feature/image-center-doc 2020-05-08 23:15:35 +02:00
Patrick Kanzler
a3660a6366 fix authors file 2020-05-08 23:14:05 +02:00
Patrick Kanzler
9fa551e6e8 Merge branch 'development' into development 2020-05-08 22:44:07 +02:00
Patrick Kanzler
ae0a049efa fix authors file 2020-05-08 22:43:47 +02:00
Patrick Kanzler
117d286371 Merge branch 'development' into development 2020-05-08 22:41:56 +02:00
Patrick Kanzler
a555a651b4 Merge pull request #385 from Bougakov/patch-1
Clarify the positions of vendor_id and product_id
2020-05-08 22:38:48 +02:00
Alexander Bougakov
e350a49cad Clarify the positions of vendor_id and product_id
An existing example uses same value, `0x1a2b`  in both `Vendor id` and `Product id` fields, which can confuse a new user.
2020-03-22 13:36:49 +03:00
Maximilian Wagenbach
f49c1dcb89 Updating AUTHORS. 2020-03-11 15:56:51 +01:00
Maximilian Wagenbach
cc67cb1c1e Added some documentation and error handling to the image center flag. 2020-03-11 15:51:16 +01:00
Brian
2ee3ff7f87 Update README.rst 2020-03-09 23:19:11 +11:00
Brian
ca45d25670 Update README.rst
Added example on serial.
2020-03-09 23:18:36 +11:00
Patrick Kanzler
51d1299285 update installation information
INSTALL has been outdated

fixes #357
2019-08-08 11:00:27 +02:00
Patrick Kanzler
0c0e6b9b4c Merge pull request #349 from hurta2yaisel/development
Adding except NotImplementedError for 'detach_kernel_driver' in order…
2019-06-30 17:29:48 +02:00
Yaisel Hurtado
50437cc9d2 Generating AUTHORS 2019-06-28 10:10:45 -04:00
Yaisel Hurtado
7c7d401f31 Adding except NotImplementedError for 'detach_kernel_driver' in order to avoid the exception NotImplementedError: Operation not supported or unimplemented on this platform. 2019-06-27 19:28:49 -04:00
Patrick Kanzler
fa140c2df5 cleanup todo page 2019-06-19 15:50:19 +02:00
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
26 changed files with 483 additions and 186 deletions

43
.github/workflows/pythonpackage.yml vendored Normal file
View File

@@ -0,0 +1,43 @@
# This workflow will install Python dependencies, run tests and lint with a variety of Python versions
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
name: Python package
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.5, 3.6, 3.7, 3.8]
steps:
- uses: actions/checkout@v2
with:
submodules: 'recursive'
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v1
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install flake8 pytest tox tox-gh-actions
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
- name: Lint with flake8
run: |
# stop the build if there are Python syntax errors or undefined names
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
- name: Test with tox
run: |
tox
env:
ESCPOS_CAPABILITIES_FILE: /home/runner/work/python-escpos/python-escpos/capabilities-data/dist/capabilities.json

4
.gitignore vendored
View File

@@ -20,6 +20,7 @@ dist/
.coverage
src/escpos/version.py
.hypothesis
.pytest_cache/
# testing temporary directories
test/test-cli-output/
@@ -28,3 +29,6 @@ test/test-cli-output/
*.swp
*.swn
*.swo
# vscode
.vscode/settings.json

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,42 +1,61 @@
language: python
sudo: false
cache: pip
dist: bionic
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:
- python: 2.7
env: TOXENV=py27
- python: 3.3
env: TOXENV=py33
- python: 3.4
env: TOXENV=py34
- 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: 3.5
env: TOXENV=py35
- python: 3.6
env: TOXENV=py36
- python: 3.6-dev
env: TOXENV=py36
- python: nightly
- python: 3.7
env: TOXENV=py37
- python: pypy
env: TOXENV=pypy
- python: 3.7-dev
env: TOXENV=py37
- python: 3.8
env: TOXENV=py38
- python: 3.8-dev
env: TOXENV=py38
- python: nightly
env: TOXENV=py38
- python: pypy3
env: TOXENV=pypy3
- python: 2.7
- python: 3.8
env: TOXENV=docs
- python: 2.7
env: TOXENV=flake8
- python: 3.6
- python: 3.8
env: TOXENV=flake8
allow_failures:
- 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 +78,4 @@ deploy:
tags: true
repo: python-escpos/python-escpos
branch: master
condition: $TRAVIS_PYTHON_VERSION = "3.5"
condition: $TRAVIS_PYTHON_VERSION = "3.8"

16
.vscode/tasks.json vendored Normal file
View File

@@ -0,0 +1,16 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "test with tox",
"type": "shell",
"command": "tox",
"group": {
"kind": "test",
"isDefault": true
}
}
]
}

13
AUTHORS
View File

@@ -1,6 +1,10 @@
Ahmed Tahri
akeonly
Alexander Bougakov
Alex Debiasio
Asuki Kono
belono
Brian
Christoph Heuel
Cody (Quantified Code Bot)
csoft2k
@@ -8,18 +12,26 @@ Curtis // mashedkeyboard
Davis Goglin
Dean Rispin
Dmytro Katyukha
Gerard Marull-Paretas
Hark
Joel Lehtonen
Justin Vieira
kennedy
Kristi
ldos
Lucy Linder
Manuel F Martinez
Maximilian Wagenbach
Michael Billington
Michael Elsdörfer
mrwunderbar666
Nathan Bookham
Omer Akram
Patrick Kanzler
primax79
Qian Linfeng
Ramon Poca
reck31
Renato Lorenzi
Romain Porte
Sam Cheng
@@ -27,4 +39,5 @@ Sergio Pulgarin
Stephan Sokolow
Thijs Triemstra
Thomas van den Berg
Yaisel Hurtado
ysuolmai

View File

@@ -1,6 +1,94 @@
*********
Changelog
*********
2020-05-09 - Version 3.0a7 - "No Fixed Abode"
---------------------------------------------
This release is the eight alpha release of the new version 3.0.
Please be aware that the API is subject to change until v3.0
is released.
This release also marks the point at which the project transitioned
to having only a master-branch (and not an additional development branch).
changes
^^^^^^^
- add Exception for NotImplementedError in detach_kernel_driver
- update installation information
- update and improve documentation
- add error handling to image centering flag
- update and fix tox and CI environment, preparing drop of support for Python 2
contributors
^^^^^^^^^^^^
- Alexander Bougakov
- Brian
- Yaisel Hurtado
- Maximilan Wagenbach
- Patrick Kanzler
2019-06-19 - Version 3.0a6 - "Mistake not..."
---------------------------------------------
This release is the seventh alpha release of the new version 3.0.
Please be aware that 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

@@ -56,12 +56,9 @@ Apart from that the travis-log and the check by Landscape will provide you with
GIT
^^^
The master-branch contains code that has been released to PyPi. A release is marked with a tag
corresponding to the version. Issues are closed when they have been resolved in the development-branch.
When you have a change to make, begin by creating a new branch from the HEAD of `python-escpos/development`.
Name your branch to indicate what you are trying to achieve. Good branch names might
be `improve/text-handling`, `feature/enable-color-printing`.
The master-branch contains the main development of the project. A release to PyPi is marked with a tag
corresponding to the version. Issues are closed when they have been resolved by merging into the master-branch.
When you have a change to make, begin by creating a new branch from the HEAD of `python-escpos/master`.
Please try to group your commits into logical units. If you need to tidy up your branch, you can make use of a
git feature called an 'interactive rebase' before making a pull request. A small, self-contained change-set is

23
INSTALL
View File

@@ -1,23 +1,10 @@
python-escpos
=============
Ensure the library is installed on ${lib_arch}/${python_ver}/site-packages/escpos
This library is available over pypi. So for most of the use-cases it should be sufficient to run
On CLi you must run:
# python setup.py build
# sudo python setup.py install
```
pip install python-escpos --user # add --pre if you want to install pre-releases
```
On Linux, ensure you belongs to the proper group so you can have access to the printer.
This can be done, by adding yourself to 'dialout' group, this might require to re-login
so the changes make effect.
Then, add the following rule to /etc/udev/rules.d/99-escpos.rules
SUBSYSTEM=="usb", ATTRS{idVendor}=="04b8", ATTRS{idProduct}=="0202", MODE="0664", GROUP="dialout"
and restar udev rules.
# sudo service udev restart
Enjoy !!!
And please, don't forget to ALWAYS add Epson.cut() at the end of your printing :)
Manuel F Martinez <manpaz@bashlinux.com>
For more information please read the documentation at https://python-escpos.readthedocs.io/en/latest/user/installation.html

View File

@@ -1,10 +1,10 @@
include *.rst
include *.txt
include COPYING
include LICENSE
include INSTALL
include tox.ini
include capabilities-data/dist/capabilities.json
include src/escpos/capabilities.json
recursive-include doc *.bat
recursive-include doc *.ico
recursive-include doc *.py

View File

@@ -65,6 +65,38 @@ 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()
Another example based on the Serial printer class:
.. code:: python
from escpos.printer import Serial
""" 9600 Baud, 8N1, Flow Control Enabled """
p = Serial(devfile='/dev/tty.usbserial',
baudrate=9600,
bytesize=8,
parity='N',
stopbits=1,
timeout=1.00,
dsrdtr=True)
p.text("Hello World\n")
p.qr("You can readme from your smartphone")
p.cut()
The full project-documentation is available on `Read the Docs <https://python-escpos.readthedocs.io>`_.
Contributing

View File

@@ -2,38 +2,9 @@
TODO
****
Introduction
------------
python-escpos is the initial idea, from here we can start to build a
robust library to get most of the ESC/POS printers working with this
library.
Eventually, this library must be able to cover almost all the defined
models detailed in the ESC/POS Command Specification Manual.
Details
-------
What things are planned to work on?
Testing
~~~~~~~
* Test on many printers as possible (USB, Serial, Network)
* automate testing
Design
~~~~~~
* Add all those sequences which are not common, but part of the ESC/POS
Command Specifications.
* Port to Python 3
* Windows compatibility (hidapi instead libusb?)
* PDF417 support
* use something similar to the `capabilities` in escpos-php
Open points and issues of the project are tracked in the GitHub issues.
Some annotations still remain in the code and should be moved over time
into the issue tracker.
Todos in the codebase
~~~~~~~~~~~~~~~~~~~~~

View File

@@ -44,18 +44,20 @@ 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
your instance. So, assuming that we have another printer where in\_ep is
on 0x81 and out\_ep=0x02, then the printer definition should look like:
your instance. So, assuming that we have another printer, CT-S2000,
manufactured by Citizen (with "Vendor ID" of 2730 and "Product ID" of 0fff)
where in\_ep is on 0x81 and out\_ep=0x02, then the printer definition should
look like:
**Generic USB Printer initialization**
::
Generic = printer.Usb(0x1a2b,0x1a2b,0,0x81,0x02)
p = printer.Usb(0x2730, 0x0fff, 0, 0x81, 0x02)
Network printer
^^^^^^^^^^^^^^^
@@ -67,7 +69,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 +83,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 +98,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 +113,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,5 +3,5 @@ formats:
- epub
requirements_file: doc/requirements.txt
python:
version: 2
version: 3
setup_py_install: true

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,16 +65,12 @@ 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',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: Implementation :: CPython',
'Programming Language :: Python :: Implementation :: PyPy',
'Topic :: Software Development :: Libraries :: Python Modules',
'Topic :: Office/Business :: Financial :: Point-Of-Sale',
],
@@ -125,16 +93,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>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
@@ -104,6 +106,9 @@ class Escpos(object):
* `graphics`: prints with the `GS ( L`-command
* `bitImageColumn`: prints with the `ESC *`-command
When trying to center an image make sure you have initialized the printer with a valid profile, that
contains a media width pixel field. Otherwise the centering will have no effect.
:param img_source: PIL image or filename to load: `jpg`, `gif`, `png` or `bmp`
:param high_density_vertical: print in high density in vertical direction *default:* True
:param high_density_horizontal: print in high density in horizontal direction *default:* True
@@ -115,6 +120,10 @@ class Escpos(object):
im = EscposImage(img_source)
try:
if self.profile.profile_data['media']['width']['pixels'] == "Unknown":
print("The media.width.pixel field of the printer profile is not set. " +
"The center flag will have no effect.")
max_width = int(self.profile.profile_data['media']['width']['pixels'])
if im.width > max_width:
@@ -180,7 +189,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 +202,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 +232,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 +314,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 +402,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 +497,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 +708,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 +739,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 +839,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 +889,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

@@ -8,15 +8,12 @@
:license: MIT
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
from __future__ import absolute_import, division, print_function, unicode_literals
import usb.core
import usb.util
import serial
import socket
import usb.core
import usb.util
from .escpos import Escpos
from .exceptions import USBNotFoundError
@@ -34,41 +31,60 @@ 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 NotImplementedError:
pass
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 +235,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 +333,59 @@ 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,7 +27,7 @@ else:
mock_open_call = '__builtin__.open'
@settings(use_coverage=False)
@pytest.mark.skip("this test is broken and has to be fixed or discarded")
@given(path=text())
def test_load_file_printer(mocker, path):
"""test the loading of the file-printer"""
@@ -38,7 +38,7 @@ def test_load_file_printer(mocker, path):
mock_open.assert_called_with(path, "wb")
@settings(deadline=None, use_coverage=False)
@pytest.mark.skip("this test is broken and has to be fixed or discarded")
@given(txt=text())
def test_auto_flush(mocker, txt):
"""test auto_flush in file-printer"""
@@ -59,7 +59,7 @@ def test_auto_flush(mocker, txt):
assert mock_device.flush.called
@settings(deadline=None, use_coverage=False)
@pytest.mark.skip("this test is broken and has to be fixed or discarded")
@given(txt=text())
def test_flush_on_close(mocker, txt):
"""test flush on close in file-printer"""

16
tox.ini
View File

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