diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index a7eb764..36ed5e6 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -17,6 +17,10 @@ I have: **Printer:** Manufacturer Model XVI + **python-escpos version:** 0.0.0 + **python version:** 0.0 + **operating system:** diff --git a/.gitignore b/.gitignore index 8c4de97..247392d 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,7 @@ temp build/ dist/ .coverage +src/escpos/version.py # testing temporary directories test/test-cli-output/ diff --git a/CHANGELOG.rst b/CHANGELOG.rst index b7be3cd..a8d0d63 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -2,6 +2,21 @@ 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" ------------------------------------------------ diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 0000000..50302f9 --- /dev/null +++ b/codecov.yml @@ -0,0 +1,5 @@ +coverage: + range: "60...100" + +comment: off + diff --git a/doc/conf.py b/doc/conf.py index 0c9568a..2cbe0cf 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -15,7 +15,10 @@ import sys import os on_rtd = os.getenv('READTHEDOCS') == 'True' -from setuptools_scm import get_version +if on_rtd: + import escpos +else: + from setuptools_scm import get_version # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the @@ -70,10 +73,14 @@ copyright = u'2016, Manuel F Martinez and others' # |version| and |release|, also used in various other places throughout the # built documents. # +if on_rtd: + # The full version, including alpha/beta/rc tags. + release = escpos.__version__ +else: + # locally setuptools_scm should work + release = get_version(root=root) # The short X.Y version. -version = get_version(root=root) -# The full version, including alpha/beta/rc tags. -release = version +version = '.'.join(release.split('.')[:2]) # The short X.Y version. # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/doc/index.rst b/doc/index.rst index 2b30b31..8e876a0 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -12,7 +12,6 @@ Content :maxdepth: 1 :caption: User Documentation - user/dependencies user/installation user/methods user/printers diff --git a/doc/user/dependencies.rst b/doc/user/dependencies.rst deleted file mode 100644 index cc2963d..0000000 --- a/doc/user/dependencies.rst +++ /dev/null @@ -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 `__ -* 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 `__ -* Build and install it - -:: - - # git clone https://github.com/lincolnloop/python-qrcode - # cd python-qrcode - # python setup.py build - # sudo python setup.py install - diff --git a/doc/user/installation.rst b/doc/user/installation.rst index be08c8a..4c826b6 100644 --- a/doc/user/installation.rst +++ b/doc/user/installation.rst @@ -2,16 +2,26 @@ Installation ************ -System preparation ------------------- +:Last Reviewed: 2016-07-23 -1. Install the required - `dependencies `__ +Installation with PIP +--------------------- +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`` -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 ``/etc/udev/rules.d/99-escpos.rules`` and add the following: ``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" 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`` -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 `__. -* Clone python-escpos from github -* Change directory to python-escpos and install the package +If you only want to enable it for python-escpos, or global activation does not work, try this: - :: + :: - # cd python-escpos - # python setup.py build - # sudo python setup.py install - -* Enjoy !!! + eval "$(register-python-argcomplete python-escpos)" diff --git a/doc/user/printers.rst b/doc/user/printers.rst index c1f5495..cdf3c0f 100644 --- a/doc/user/printers.rst +++ b/doc/user/printers.rst @@ -35,6 +35,17 @@ Based on socket * ``host`` is an alphanumeric host name, could be either DNS host name or IP address. * ``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") ^^^^^^^^^^^^^^^^^^ diff --git a/setup.py b/setup.py index 7ca8222..7a3895b 100755 --- a/setup.py +++ b/setup.py @@ -45,9 +45,24 @@ class Tox(test_command): errno = tox.cmdline(args=args) 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( 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', download_url='https://github.com/python-escpos/python-escpos/archive/master.zip', description='Python library to manipulate ESC/POS Printers', @@ -95,6 +110,8 @@ setup( 'six', 'appdirs', 'pyyaml', + 'argparse', + 'argcomplete', ], setup_requires=[ 'setuptools_scm', diff --git a/src/escpos/__init__.py b/src/escpos/__init__.py index 0459ce8..3fbc808 100644 --- a/src/escpos/__init__.py +++ b/src/escpos/__init__.py @@ -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"] + +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.' + ) diff --git a/src/escpos/cli.py b/src/escpos/cli.py index e2e8a83..3e3311d 100644 --- a/src/escpos/cli.py +++ b/src/escpos/cli.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +# PYTHON_ARGCOMPLETE_OK """ CLI 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 import argparse +try: + import argcomplete +except ImportError: + # this CLI works nevertheless without argcomplete + pass # noqa import sys import six from . import config +from . import version # Must be defined before it's used in DEMO_FUNCTIONS @@ -448,14 +455,17 @@ def main(): # Allow config file location to be passed parser.add_argument( '-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 # cli [subparser] -args command_subparsers = parser.add_subparsers( 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 for command in ESCPOS_COMMANDS: @@ -491,6 +501,14 @@ def main(): 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 args_dict = vars(parser.parse_args()) if not args_dict: @@ -498,6 +516,12 @@ def main(): sys.exit() 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 config_path = command_arguments.pop('config', None) @@ -511,6 +535,9 @@ def main(): target_command = command_arguments.pop('func') + # remove helper-argument 'parser' from dict + command_arguments.pop('parser', None) + if hasattr(printer, target_command): # print command with args getattr(printer, target_command)(**command_arguments) diff --git a/test/test_cli.py b/test/test_cli.py index 03beb2d..b9aebc3 100644 --- a/test/test_cli.py +++ b/test/test_cli.py @@ -11,6 +11,7 @@ import os import sys from scripttest import TestFileEnvironment from nose.tools import assert_equals +import escpos 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 """ @@ -60,8 +61,7 @@ class TestCLI: ) self.default_args = ( - sys.executable, - '-mescpos.cli', + 'python-escpos', '-c', CONFIGFILE, ) @@ -79,10 +79,16 @@ class TestCLI: def test_cli_help(self): """ 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 '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): """ Make sure text returns what we sent it """ test_text = 'this is some text'