commit
2cf30c7f05
|
@ -17,6 +17,10 @@ I have:
|
||||||
<!-- Replace examples with your info -->
|
<!-- Replace examples with your info -->
|
||||||
**Printer:** Manufacturer Model XVI
|
**Printer:** Manufacturer Model XVI
|
||||||
|
|
||||||
|
<!-- since version 2.0.1 you can type 'python-escpos version' in your shell.
|
||||||
|
Alternatively you could use '__version__' in module escpos. -->
|
||||||
**python-escpos version:** 0.0.0
|
**python-escpos version:** 0.0.0
|
||||||
|
|
||||||
|
**python version:** 0.0
|
||||||
|
|
||||||
**operating system:**
|
**operating system:**
|
||||||
|
|
|
@ -17,6 +17,7 @@ temp
|
||||||
build/
|
build/
|
||||||
dist/
|
dist/
|
||||||
.coverage
|
.coverage
|
||||||
|
src/escpos/version.py
|
||||||
|
|
||||||
# testing temporary directories
|
# testing temporary directories
|
||||||
test/test-cli-output/
|
test/test-cli-output/
|
||||||
|
|
|
@ -2,6 +2,21 @@
|
||||||
Changelog
|
Changelog
|
||||||
*********
|
*********
|
||||||
|
|
||||||
|
2016-07-23 - Version 2.1.0 - "But Who's Counting?"
|
||||||
|
--------------------------------------------------
|
||||||
|
|
||||||
|
changes
|
||||||
|
^^^^^^^
|
||||||
|
- packaging: configured the coverage-analysis codecov.io
|
||||||
|
- GitHub: improved issues-template
|
||||||
|
- documentation: add troubleshooting tip to network-interface
|
||||||
|
- the module, cli and documentation is now aware of the version of python-escpos
|
||||||
|
- the cli does now support basic tabcompletion
|
||||||
|
|
||||||
|
contributors
|
||||||
|
^^^^^^^^^^^^
|
||||||
|
- Patrick Kanzler
|
||||||
|
|
||||||
2016-06-24 - Version 2.0.0 - "Attitude Adjuster"
|
2016-06-24 - Version 2.0.0 - "Attitude Adjuster"
|
||||||
------------------------------------------------
|
------------------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
coverage:
|
||||||
|
range: "60...100"
|
||||||
|
|
||||||
|
comment: off
|
||||||
|
|
13
doc/conf.py
13
doc/conf.py
|
@ -15,6 +15,9 @@
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
on_rtd = os.getenv('READTHEDOCS') == 'True'
|
on_rtd = os.getenv('READTHEDOCS') == 'True'
|
||||||
|
if on_rtd:
|
||||||
|
import escpos
|
||||||
|
else:
|
||||||
from setuptools_scm import get_version
|
from setuptools_scm import get_version
|
||||||
|
|
||||||
# If extensions (or modules to document with autodoc) are in another directory,
|
# If extensions (or modules to document with autodoc) are in another directory,
|
||||||
|
@ -70,10 +73,14 @@ copyright = u'2016, Manuel F Martinez and others'
|
||||||
# |version| and |release|, also used in various other places throughout the
|
# |version| and |release|, also used in various other places throughout the
|
||||||
# built documents.
|
# built documents.
|
||||||
#
|
#
|
||||||
# The short X.Y version.
|
if on_rtd:
|
||||||
version = get_version(root=root)
|
|
||||||
# The full version, including alpha/beta/rc tags.
|
# The full version, including alpha/beta/rc tags.
|
||||||
release = version
|
release = escpos.__version__
|
||||||
|
else:
|
||||||
|
# locally setuptools_scm should work
|
||||||
|
release = get_version(root=root)
|
||||||
|
# The short X.Y version.
|
||||||
|
version = '.'.join(release.split('.')[:2]) # The short X.Y version.
|
||||||
|
|
||||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||||
# for a list of supported languages.
|
# for a list of supported languages.
|
||||||
|
|
|
@ -12,7 +12,6 @@ Content
|
||||||
:maxdepth: 1
|
:maxdepth: 1
|
||||||
:caption: User Documentation
|
:caption: User Documentation
|
||||||
|
|
||||||
user/dependencies
|
|
||||||
user/installation
|
user/installation
|
||||||
user/methods
|
user/methods
|
||||||
user/printers
|
user/printers
|
||||||
|
|
|
@ -1,57 +0,0 @@
|
||||||
************
|
|
||||||
Dependencies
|
|
||||||
************
|
|
||||||
|
|
||||||
Fedora
|
|
||||||
------
|
|
||||||
|
|
||||||
Fortunately everything is on Fedora repositories.
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
# yum install python-imaging pyserial pyusb python-qrcode
|
|
||||||
|
|
||||||
Ubuntu
|
|
||||||
------
|
|
||||||
|
|
||||||
Ultimately, this instructions also apply to Raspbian, in case you are
|
|
||||||
interested to install python-escpos on your Raspberry with Raspbian.
|
|
||||||
|
|
||||||
Install the packages available on distro repositories.
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
# apt-get install python-imaging pyserial
|
|
||||||
|
|
||||||
The packages which are not available at Ubuntu repositories need to be
|
|
||||||
installed manually.
|
|
||||||
|
|
||||||
pyusb
|
|
||||||
^^^^^
|
|
||||||
This is the python binding to libusb-1.0
|
|
||||||
|
|
||||||
* Get the latest tarball from `sourceforge <http://sourceforge.net/projects/pyusb/files/PyUSB%201.0/>`__
|
|
||||||
* Build and install it
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
# tar zxvf pyusb-1.*.tar.gz
|
|
||||||
# cd pyusb-1.*
|
|
||||||
# python setup.py build
|
|
||||||
# sudo python setup.py install
|
|
||||||
|
|
||||||
python-qrcode
|
|
||||||
^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
This is the python module to generate QR Codes
|
|
||||||
|
|
||||||
* Checkout the latest code from `github <https://github.com/lincolnloop/python-qrcode>`__
|
|
||||||
* Build and install it
|
|
||||||
|
|
||||||
::
|
|
||||||
|
|
||||||
# git clone https://github.com/lincolnloop/python-qrcode
|
|
||||||
# cd python-qrcode
|
|
||||||
# python setup.py build
|
|
||||||
# sudo python setup.py install
|
|
||||||
|
|
|
@ -2,16 +2,26 @@
|
||||||
Installation
|
Installation
|
||||||
************
|
************
|
||||||
|
|
||||||
System preparation
|
:Last Reviewed: 2016-07-23
|
||||||
------------------
|
|
||||||
|
|
||||||
1. Install the required
|
Installation with PIP
|
||||||
`dependencies <https://github.com/manpaz/python-escpos/wiki/Dependencies>`__
|
---------------------
|
||||||
|
Installation should be rather straight-forward. python-escpos is on PyPi, so you can simply enter:
|
||||||
|
|
||||||
2. Get the *Product ID* and *Vendor ID* from the lsusb command
|
::
|
||||||
|
|
||||||
|
pip install python-escpos
|
||||||
|
|
||||||
|
This should install all necessary dependencies. Apart from that python-escpos should also be
|
||||||
|
available as a Debian package. If you want to always benefit from the newest stable releases you should probably
|
||||||
|
install from PyPi.
|
||||||
|
|
||||||
|
Setup udev for USB-Printers
|
||||||
|
---------------------------
|
||||||
|
1. Get the *Product ID* and *Vendor ID* from the lsusb command
|
||||||
``# lsusb Bus 002 Device 001: ID 1a2b:1a2b Device name``
|
``# lsusb Bus 002 Device 001: ID 1a2b:1a2b Device name``
|
||||||
|
|
||||||
3. Create a udev rule to let users belonging to *dialout* group use the
|
2. Create a udev rule to let users belonging to *dialout* group use the
|
||||||
printer. You can create the file
|
printer. You can create the file
|
||||||
``/etc/udev/rules.d/99-escpos.rules`` and add the following:
|
``/etc/udev/rules.d/99-escpos.rules`` and add the following:
|
||||||
``SUBSYSTEM=="usb", ATTRS{idVendor}=="1a2b", ATTRS{idProduct}=="1a2b", MODE="0664", GROUP="dialout"``
|
``SUBSYSTEM=="usb", ATTRS{idVendor}=="1a2b", ATTRS{idProduct}=="1a2b", MODE="0664", GROUP="dialout"``
|
||||||
|
@ -20,21 +30,19 @@ System preparation
|
||||||
"dialout" group, or use another group you already belongs instead
|
"dialout" group, or use another group you already belongs instead
|
||||||
"dialout" and set it in the ``GROUP`` parameter in the above rule.
|
"dialout" and set it in the ``GROUP`` parameter in the above rule.
|
||||||
|
|
||||||
4. Restart udev ``# sudo service udev restart`` In some new systems it
|
3. Restart udev ``# sudo service udev restart`` In some new systems it
|
||||||
is done with ``# sudo udevadm control --reload``
|
is done with ``# sudo udevadm control --reload``
|
||||||
|
|
||||||
Install
|
Enabling tab-completion in CLI
|
||||||
-------
|
------------------------------
|
||||||
|
python-escpos has a CLI with tab-completion. This is realised with ``argcomplete``.
|
||||||
|
In order for this to work you have to enable tab-completion, which is described in
|
||||||
|
the `manual of argcomplete <https://argcomplete.readthedocs.io>`__.
|
||||||
|
|
||||||
* Clone python-escpos from github
|
If you only want to enable it for python-escpos, or global activation does not work, try this:
|
||||||
* Change directory to python-escpos and install the package
|
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
# cd python-escpos
|
eval "$(register-python-argcomplete python-escpos)"
|
||||||
# python setup.py build
|
|
||||||
# sudo python setup.py install
|
|
||||||
|
|
||||||
* Enjoy !!!
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,17 @@ Based on socket
|
||||||
* ``host`` is an alphanumeric host name, could be either DNS host name or IP address.
|
* ``host`` is an alphanumeric host name, could be either DNS host name or IP address.
|
||||||
* ``port`` to write to (default = 9100)
|
* ``port`` to write to (default = 9100)
|
||||||
|
|
||||||
|
Troubleshooting:
|
||||||
|
Problems with a network-attached printer can have numerous causes. Make sure that your device has a proper IP address.
|
||||||
|
Often you can check the IP address by triggering the self-test of the device. As a next step try to send text
|
||||||
|
manually to the device. You could use for example:
|
||||||
|
|
||||||
|
::
|
||||||
|
echo "OK\n" | nc IPADDRESS 9100
|
||||||
|
# the port number is often 9100
|
||||||
|
|
||||||
|
As a last resort try to reset the interface of the printer. This should be described in its manual.
|
||||||
|
|
||||||
File("file\_name")
|
File("file\_name")
|
||||||
^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
|
19
setup.py
19
setup.py
|
@ -45,9 +45,24 @@ class Tox(test_command):
|
||||||
errno = tox.cmdline(args=args)
|
errno = tox.cmdline(args=args)
|
||||||
sys.exit(errno)
|
sys.exit(errno)
|
||||||
|
|
||||||
|
|
||||||
|
setuptools_scm_template = """\
|
||||||
|
# coding: utf-8
|
||||||
|
# file generated by setuptools_scm
|
||||||
|
# don't change, don't track in version control
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
version = '{version}'
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
name='python-escpos',
|
name='python-escpos',
|
||||||
use_scm_version=True,
|
use_scm_version={
|
||||||
|
'write_to': 'src/escpos/version.py',
|
||||||
|
'write_to_template': setuptools_scm_template,
|
||||||
|
},
|
||||||
url='https://github.com/python-escpos/python-escpos',
|
url='https://github.com/python-escpos/python-escpos',
|
||||||
download_url='https://github.com/python-escpos/python-escpos/archive/master.zip',
|
download_url='https://github.com/python-escpos/python-escpos/archive/master.zip',
|
||||||
description='Python library to manipulate ESC/POS Printers',
|
description='Python library to manipulate ESC/POS Printers',
|
||||||
|
@ -95,6 +110,8 @@ setup(
|
||||||
'six',
|
'six',
|
||||||
'appdirs',
|
'appdirs',
|
||||||
'pyyaml',
|
'pyyaml',
|
||||||
|
'argparse',
|
||||||
|
'argcomplete',
|
||||||
],
|
],
|
||||||
setup_requires=[
|
setup_requires=[
|
||||||
'setuptools_scm',
|
'setuptools_scm',
|
||||||
|
|
|
@ -1 +1,19 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
python-escpos enables you to manipulate escpos-printers
|
||||||
|
"""
|
||||||
|
from __future__ import absolute_import
|
||||||
|
from __future__ import division
|
||||||
|
from __future__ import print_function
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
__all__ = ["constants", "escpos", "exceptions", "printer"]
|
__all__ = ["constants", "escpos", "exceptions", "printer"]
|
||||||
|
|
||||||
|
try:
|
||||||
|
from .version import version as __version__ # noqa
|
||||||
|
except ImportError: # pragma: no cover
|
||||||
|
raise ImportError(
|
||||||
|
'Failed to find (autogenerated) version.py. '
|
||||||
|
'This might be because you are installing from GitHub\'s tarballs, '
|
||||||
|
'use the PyPI ones.'
|
||||||
|
)
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
# PYTHON_ARGCOMPLETE_OK
|
||||||
""" CLI
|
""" CLI
|
||||||
|
|
||||||
This module acts as a command line interface for python-escpos. It mirrors
|
This module acts as a command line interface for python-escpos. It mirrors
|
||||||
|
@ -14,9 +15,15 @@ from __future__ import print_function
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
|
try:
|
||||||
|
import argcomplete
|
||||||
|
except ImportError:
|
||||||
|
# this CLI works nevertheless without argcomplete
|
||||||
|
pass # noqa
|
||||||
import sys
|
import sys
|
||||||
import six
|
import six
|
||||||
from . import config
|
from . import config
|
||||||
|
from . import version
|
||||||
|
|
||||||
|
|
||||||
# Must be defined before it's used in DEMO_FUNCTIONS
|
# Must be defined before it's used in DEMO_FUNCTIONS
|
||||||
|
@ -448,14 +455,17 @@ def main():
|
||||||
# Allow config file location to be passed
|
# Allow config file location to be passed
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-c', '--config',
|
'-c', '--config',
|
||||||
help='Altnerate path to the configuration file',
|
help='Alternate path to the configuration file',
|
||||||
)
|
)
|
||||||
|
|
||||||
# Everything interesting runs off of a subparser so we can use the format
|
# Everything interesting runs off of a subparser so we can use the format
|
||||||
# cli [subparser] -args
|
# cli [subparser] -args
|
||||||
command_subparsers = parser.add_subparsers(
|
command_subparsers = parser.add_subparsers(
|
||||||
title='ESCPOS Command',
|
title='ESCPOS Command',
|
||||||
|
dest='parser',
|
||||||
)
|
)
|
||||||
|
# fix inconsistencies in the behaviour of some versions of argparse
|
||||||
|
command_subparsers.required = False # force 'required' testing
|
||||||
|
|
||||||
# Build the ESCPOS command arguments
|
# Build the ESCPOS command arguments
|
||||||
for command in ESCPOS_COMMANDS:
|
for command in ESCPOS_COMMANDS:
|
||||||
|
@ -491,6 +501,14 @@ def main():
|
||||||
action='store_true',
|
action='store_true',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
parser_command_version = command_subparsers.add_parser('version',
|
||||||
|
help='Print the version of python-escpos')
|
||||||
|
parser_command_version.set_defaults(version=True)
|
||||||
|
|
||||||
|
# hook in argcomplete
|
||||||
|
if 'argcomplete' in globals():
|
||||||
|
argcomplete.autocomplete(parser)
|
||||||
|
|
||||||
# Get only arguments actually passed
|
# Get only arguments actually passed
|
||||||
args_dict = vars(parser.parse_args())
|
args_dict = vars(parser.parse_args())
|
||||||
if not args_dict:
|
if not args_dict:
|
||||||
|
@ -498,6 +516,12 @@ def main():
|
||||||
sys.exit()
|
sys.exit()
|
||||||
command_arguments = dict([k, v] for k, v in six.iteritems(args_dict) if v is not None)
|
command_arguments = dict([k, v] for k, v in six.iteritems(args_dict) if v is not None)
|
||||||
|
|
||||||
|
# If version should be printed, do this, then exit
|
||||||
|
print_version = command_arguments.pop('version', None)
|
||||||
|
if print_version:
|
||||||
|
print(version.version)
|
||||||
|
sys.exit()
|
||||||
|
|
||||||
# If there was a config path passed, grab it
|
# If there was a config path passed, grab it
|
||||||
config_path = command_arguments.pop('config', None)
|
config_path = command_arguments.pop('config', None)
|
||||||
|
|
||||||
|
@ -511,6 +535,9 @@ def main():
|
||||||
|
|
||||||
target_command = command_arguments.pop('func')
|
target_command = command_arguments.pop('func')
|
||||||
|
|
||||||
|
# remove helper-argument 'parser' from dict
|
||||||
|
command_arguments.pop('parser', None)
|
||||||
|
|
||||||
if hasattr(printer, target_command):
|
if hasattr(printer, target_command):
|
||||||
# print command with args
|
# print command with args
|
||||||
getattr(printer, target_command)(**command_arguments)
|
getattr(printer, target_command)(**command_arguments)
|
||||||
|
|
|
@ -11,6 +11,7 @@ import os
|
||||||
import sys
|
import sys
|
||||||
from scripttest import TestFileEnvironment
|
from scripttest import TestFileEnvironment
|
||||||
from nose.tools import assert_equals
|
from nose.tools import assert_equals
|
||||||
|
import escpos
|
||||||
|
|
||||||
TEST_DIR = os.path.abspath('test/test-cli-output')
|
TEST_DIR = os.path.abspath('test/test-cli-output')
|
||||||
|
|
||||||
|
@ -29,7 +30,7 @@ printer:
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class TestCLI:
|
class TestCLI():
|
||||||
""" Contains setups, teardowns, and tests for CLI
|
""" Contains setups, teardowns, and tests for CLI
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -60,8 +61,7 @@ class TestCLI:
|
||||||
)
|
)
|
||||||
|
|
||||||
self.default_args = (
|
self.default_args = (
|
||||||
sys.executable,
|
'python-escpos',
|
||||||
'-mescpos.cli',
|
|
||||||
'-c',
|
'-c',
|
||||||
CONFIGFILE,
|
CONFIGFILE,
|
||||||
)
|
)
|
||||||
|
@ -79,10 +79,16 @@ class TestCLI:
|
||||||
|
|
||||||
def test_cli_help(self):
|
def test_cli_help(self):
|
||||||
""" Test getting help from cli """
|
""" Test getting help from cli """
|
||||||
result = self.env.run(sys.executable, '-mescpos.cli', '-h')
|
result = self.env.run('python-escpos', '-h')
|
||||||
assert not result.stderr
|
assert not result.stderr
|
||||||
assert 'usage' in result.stdout
|
assert 'usage' in result.stdout
|
||||||
|
|
||||||
|
def test_cli_version(self):
|
||||||
|
""" Test the version string """
|
||||||
|
result = self.env.run('python-escpos', 'version')
|
||||||
|
assert not result.stderr
|
||||||
|
assert_equals(escpos.__version__, result.stdout.strip())
|
||||||
|
|
||||||
def test_cli_text(self):
|
def test_cli_text(self):
|
||||||
""" Make sure text returns what we sent it """
|
""" Make sure text returns what we sent it """
|
||||||
test_text = 'this is some text'
|
test_text = 'this is some text'
|
||||||
|
|
Loading…
Reference in New Issue