changeset 29:63d1260cc64e 0.1.0

- class name is now 'Zebra' instead of 'zebra' - Fix for missing win32print module in pypi - Drop python 2 support - use setuptools instead of distutils - improve documentation - Added reset(), reset_default(), autosense(), print_config_label() and print_graphic() functions
author Ben Croston <ben@croston.org>
date Tue, 01 Sep 2020 15:57:24 +0100
parents 172de216b85d
children ddc251fb92aa
files CHANGELOG.rst LICENCE MANIFEST.in README README.rst setup.py zebra.py
diffstat 7 files changed, 144 insertions(+), 81 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CHANGELOG.rst	Tue Sep 01 15:57:24 2020 +0100
@@ -0,0 +1,20 @@
+Changelog
+=========
+
+0.1.0
+-----
+- class name is now 'Zebra' instead of 'zebra'
+- Fix for missing win32print module in pypi
+- Drop python 2 support
+- use setuptools instead of distutils
+- improve documentation
+- Added reset(), reset_default(), autosense(), print_config_label() and
+  print_graphic() functions
+
+0.0.5
+-----
+- Added -oraw to lpr command to make more CUPS installations work
+
+0.0.4 and earlier
+-----------------
+Undocumented!
--- a/LICENCE	Mon Apr 27 11:39:37 2015 +0100
+++ b/LICENCE	Tue Sep 01 15:57:24 2020 +0100
@@ -1,4 +1,4 @@
-Copyright (c) 2011-2015 Ben Croston
+Copyright (c) 2011-2020 Ben Croston
 
 Permission is hereby granted, free of charge, to any person obtaining a copy of
 this software and associated documentation files (the "Software"), to deal in
--- a/MANIFEST.in	Mon Apr 27 11:39:37 2015 +0100
+++ b/MANIFEST.in	Tue Sep 01 15:57:24 2020 +0100
@@ -1,1 +1,1 @@
-include MANIFEST.in INSTALL README LICENCE
+include MANIFEST.in INSTALL README.rst LICENCE CHANGELOG.rst
--- a/README	Mon Apr 27 11:39:37 2015 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-============
-Zebra-0.0.5
-============
-
-Usage:
-
-::
-
-    from zebra import zebra
-
-    z = zebra( [queue] )
-      Constructor with optional printer queue
-
-    z.getqueues()
-      Return a list containing available printer queues
-
-    z.setqueue( queue )
-      Set the printer queue
-
-    z.setup( direct_thermal=None, label_height=None, label_width=None )
-      Set up the label printer. Parameters are not set if they are None.
-        direct_thermal - True if using direct thermal labels
-        label_height   - tuple (label height, label gap) in dots
-        label_width    - in dots
-
-    z.store_graphic( name, filename )
-      Store a .PCX file on the label printer
-        name     - name to be used on printer
-        filename - local filename
-
-    z.output( commands )
-      Output EPL2 commands to the printer
-
-Note:
-
-- On Mac and *nix, install the printer as a Raw printer, not a Zebra one.
-If you are on a Linux or MacOSX machine using CUPS, you may need to set up a
-printer queue using the admin panel at http://localhost:631
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/README.rst	Tue Sep 01 15:57:24 2020 +0100
@@ -0,0 +1,62 @@
+============
+Zebra-0.1.0
+============
+
+Usage:
+
+::
+
+    from zebra import Zebra
+
+    z = Zebra( [queue] )
+      Constructor with optional printer queue
+
+    z.getqueues()
+      Return a list containing available printer queues
+
+    z.setqueue( queue )
+      Set the printer queue
+
+    z.setup( direct_thermal=None, label_height=None, label_width=None )
+      Set up the label printer using EPL2. Parameters are not set if they are None.
+      Not necessary if using AutoSense (hold feed button while powering on)
+        direct_thermal - True if using direct thermal labels
+        label_height   - tuple (label height, label gap) in dots
+        label_width    - in dots
+
+    z.reset_default()
+      Resets the printer to factory settings using EPL2
+
+    z.reset()
+      Resets the printer using EPL2 - equivalent of switching off/on
+
+    z.autosense()
+      Run AutoSense by sending an EPL2 command
+      Get the printer to detect label and gap length and set the sensor levels 
+
+    z.print_config_label()
+      Send an EPL2 command to print label(s) with current config settings
+
+    z.store_graphic( name, filename )
+      Store a 1 bit .PCX file on the label printer using EPL2
+        name     - name to be used on printer
+        filename - local filename
+
+    z.print_graphic( x, y, width, length, data, qty )
+        Print a label from 1 bit data, using EPL2
+          x,y    - top left coordinates of the image, in dots
+          width  - width of image, in dots.  Must be a multiple of 8.
+          length - length of image, in dots
+          data   - raw graphical data, in bytes
+          qty    - number of labels to print
+
+    z.output( commands )
+      Output raw commands to the printer
+
+    z.print_config_label()
+      Print label(s) containing the current printer configuration using EPL2
+
+Note:
+
+If you are on a Linux or MacOSX machine using CUPS, you may need to set up a
+printer queue using the admin panel at http://localhost:631
--- a/setup.py	Mon Apr 27 11:39:37 2015 +0100
+++ b/setup.py	Tue Sep 01 15:57:24 2020 +0100
@@ -1,11 +1,6 @@
 #!/usr/bin/env python
 import sys
-from distutils.core import setup
-
-try:
-    from distutils.command.build_py import build_py_2to3 as build_py
-except ImportError:
-    from distutils.command.build_py import build_py
+from setuptools import setup
 
 classifiers = ['Development Status :: 5 - Production/Stable',
                'Operating System :: Microsoft :: Windows',
@@ -13,30 +8,21 @@
                "Operating System :: MacOS :: MacOS X",
                'License :: OSI Approved :: MIT License',
                'Intended Audience :: Developers',
-               'Programming Language :: Python :: 2.7',
                'Programming Language :: Python :: 3',
                'Topic :: Printing']
 
-long_description = open('README').read()
-
-if sys.platform.lower().startswith('win'):
-    install_requires = 'win32print'
-else:
-    install_requires = None
-
 setup(name             = 'zebra',
-      version          = '0.0.5',
+      version          = '0.1.0',
       py_modules       = ['zebra'],
       author           = 'Ben Croston',
       author_email     = 'ben@croston.org',
       maintainer       = 'Ben Croston',
       maintainer_email = 'ben@croston.org',
       url              = 'http://www.wyre-it.co.uk/zebra/',
-      description      = 'A package to communicate with (Zebra) label printers using EPL2',
-      long_description = long_description,
+      description      = 'A package to communicate with (Zebra) label printers',
+      long_description = open('README.rst').read() + '\n' + open('CHANGELOG.rst').read(),
+      long_description_content_type = 'text/x-rst',
       platforms        = 'Windows, Unix, MacOSX',
       classifiers      = classifiers,
       license          = 'MIT',
-      cmdclass         = {'build_py': build_py},
-      install_requires = install_requires
-      )
+      install_requires = ["pywin32;platform_system=='Windows'"])
--- a/zebra.py	Mon Apr 27 11:39:37 2015 +0100
+++ b/zebra.py	Tue Sep 01 15:57:24 2020 +0100
@@ -1,6 +1,6 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
-# Copyright (c) 2011-2015 Ben Croston
+# Copyright (c) 2011-2020 Ben Croston
 #
 # Permission is hereby granted, free of charge, to any person obtaining a copy of
 # this software and associated documentation files (the "Software"), to deal in
@@ -30,8 +30,8 @@
     IS_WINDOWS = False
     import subprocess
 
-class zebra(object):
-    """A class to communicate with (Zebra) label printers using EPL2"""
+class Zebra:
+    """A class to communicate with (Zebra) label printers"""
 
     def __init__(self, queue=None):
         """queue - name of the printer queue (optional)"""
@@ -47,7 +47,7 @@
 
     def _output_win(self, commands):
         if self.queue == 'zebra_python_unittest':
-            print commands
+            print(commands)
             return
         hPrinter = win32print.OpenPrinter(self.queue)
         try:
@@ -61,22 +61,26 @@
         finally:
             win32print.ClosePrinter(hPrinter)
 
-    def output(self, commands):
-        """Output EPL2 commands to the label printer
+    def output(self, commands, encoding='cp437'):
+        """Send raw commands to the label printer
 
-        commands - EPL2 commands to send to the printer
+        commands - commands to send to the printer.  Converted to a byte string if necessary.
+        encoding - Encoding used if 'commands' is not a byte string
         """
         assert self.queue is not None
-        if sys.version_info[0] == 3:
-            if type(commands) != bytes:
-                commands = str(commands).encode()
-        else:
-            commands = str(commands).encode()
+        if type(commands) != bytes:
+            commands = str(commands).encode(encoding=encoding)
         if IS_WINDOWS:
             self._output_win(commands)
         else:
             self._output_unix(commands)
 
+    def print_config_label(self):
+        """
+        Send an EPL2 command to print label(s) with current config settings
+        """
+        self.output('\nU\n')
+
     def _getqueues_unix(self):
         queues = []
         try:
@@ -106,7 +110,8 @@
         self.queue = queue
 
     def setup(self, direct_thermal=None, label_height=None, label_width=None):
-        """Set up the label printer. Parameters are not set if they are None.
+        """Set up the label printer using EPL2. Parameters are not set if they are None.
+        Not necessary if using AutoSense (hold feed button while powering on)
 
         direct_thermal - True if using direct thermal labels
         label_height   - tuple (label height, label gap) in dots
@@ -114,15 +119,29 @@
         """
         commands = '\n'
         if direct_thermal:
-            commands += ('OD\n')
+            commands += 'OD\n'
         if label_height:
-           commands += ('Q%s,%s\n'%(label_height[0],label_height[1]))
+           commands += 'Q%s,%s\n'%(label_height[0],label_height[1])
         if label_width:
-            commands += ('q%s\n'%label_width)
+            commands += 'q%s\n'%label_width
         self.output(commands)
 
+    def reset_default(self):
+        """Reset the printer to factory settings using EPL2"""
+        self.output('\n^default\n')
+
+    def reset(self):
+        """Resets the printer using EPL2 - equivalent to switching off/on"""
+        self.output('\n^@\n')
+
+    def autosense(self):
+         """Run AutoSense by sending an EPL2 command
+         Get the printer to detect label and gap length and set the sensor levels
+         """
+         self.output('\nxa\n')
+
     def store_graphic(self, name, filename):
-        """Store a .PCX file on the label printer
+        """Store a 1 bit PCX file on the label printer, using EPL2.
 
         name     - name to be used on printer
         filename - local filename
@@ -135,9 +154,24 @@
         self.output(commands)
         self.output(open(filename,'rb').read())
 
+    def print_graphic(self, x, y, width, length, data, qty):
+        """Print a label from 1 bit data, using EPL2
+
+        x,y    - top left coordinates of the image, in dots
+        width  - width of image, in dots.  Must be a multiple of 8.
+        length - length of image, in dots
+        data   - raw graphical data, in bytes
+        qty    - number of labels to print
+        """
+        assert type(data) == bytes
+        assert width % 8 == 0  # make sure width is a multiple of 8
+        assert (width//8) * length == len(data)
+        commands = b"\nN\nGW%d,%d,%d,%d,%s\nP%d\n"%(x, y, width//8, length, data, qty)
+        self.output(commands)
+
 if __name__ == '__main__':
-    z = zebra()
-    print 'Printer queues found:',z.getqueues()
+    z = Zebra()
+    print('Printer queues found:',z.getqueues())
     z.setqueue('zebra_python_unittest')
     z.setup(direct_thermal=True, label_height=(406,32), label_width=609)    # 3" x 2" direct thermal label
     z.store_graphic('logo','logo.pcx')