Mercurial > hg > zebra
annotate zebra.py @ 26:20f6df6d3f42
- Fix for empty printer list
- Updated to 0.0.4a
- Altered to use pip
author | Ben Croston <ben@croston.org> |
---|---|
date | Sat, 16 Nov 2013 17:17:15 +0000 |
parents | fc1a7cf3f92c |
children | 7c132e01c281 |
rev | line source |
---|---|
0 | 1 #!/usr/bin/env python |
25 | 2 |
26 | 3 # Copyright (c) 2011-2013 Ben Croston |
25 | 4 # |
5 # Permission is hereby granted, free of charge, to any person obtaining a copy of | |
6 # this software and associated documentation files (the "Software"), to deal in | |
7 # the Software without restriction, including without limitation the rights to | |
8 # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies | |
9 # of the Software, and to permit persons to whom the Software is furnished to do | |
10 # so, subject to the following conditions: | |
11 # | |
12 # The above copyright notice and this permission notice shall be included in all | |
13 # copies or substantial portions of the Software. | |
14 # | |
15 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
16 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
17 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
18 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
19 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
20 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
21 # SOFTWARE. | |
22 | |
0 | 23 import os.path |
24 import sys | |
10 | 25 |
0 | 26 if sys.platform.lower().startswith('win'): |
10 | 27 IS_WINDOWS = True |
0 | 28 import win32print |
10 | 29 else: |
30 IS_WINDOWS = False | |
22 | 31 import subprocess |
0 | 32 |
33 class zebra(object): | |
10 | 34 """A class to communicate with (Zebra) label printers using EPL2""" |
35 | |
0 | 36 def __init__(self, queue=None): |
10 | 37 """queue - name of the printer queue (optional)""" |
0 | 38 self.queue = queue |
39 | |
40 def _output_unix(self, commands): | |
41 if self.queue == 'zebra_python_unittest': | |
42 p = subprocess.Popen(['cat','-'], stdin=subprocess.PIPE) | |
43 else: | |
44 p = subprocess.Popen(['lpr','-P%s'%self.queue], stdin=subprocess.PIPE) | |
17
a9dacd180597
Does not work in python 2.6 after all
Ben Croston <ben@croston.org>
parents:
14
diff
changeset
|
45 p.communicate(commands) |
0 | 46 p.stdin.close() |
47 | |
48 def _output_win(self, commands): | |
8 | 49 if self.queue == 'zebra_python_unittest': |
50 print commands | |
51 return | |
52 hPrinter = win32print.OpenPrinter(self.queue) | |
53 try: | |
54 hJob = win32print.StartDocPrinter(hPrinter, 1, ('Label',None,'RAW')) | |
55 try: | |
56 win32print.StartPagePrinter(hPrinter) | |
57 win32print.WritePrinter(hPrinter, commands) | |
58 win32print.EndPagePrinter(hPrinter) | |
59 finally: | |
60 win32print.EndDocPrinter(hPrinter) | |
61 finally: | |
62 win32print.ClosePrinter(hPrinter) | |
26 | 63 |
0 | 64 def output(self, commands): |
10 | 65 """Output EPL2 commands to the label printer |
66 | |
67 commands - EPL2 commands to send to the printer | |
68 """ | |
0 | 69 assert self.queue is not None |
17
a9dacd180597
Does not work in python 2.6 after all
Ben Croston <ben@croston.org>
parents:
14
diff
changeset
|
70 if sys.version_info[0] == 3: |
a9dacd180597
Does not work in python 2.6 after all
Ben Croston <ben@croston.org>
parents:
14
diff
changeset
|
71 if type(commands) != bytes: |
a9dacd180597
Does not work in python 2.6 after all
Ben Croston <ben@croston.org>
parents:
14
diff
changeset
|
72 commands = str(commands).encode() |
a9dacd180597
Does not work in python 2.6 after all
Ben Croston <ben@croston.org>
parents:
14
diff
changeset
|
73 else: |
a9dacd180597
Does not work in python 2.6 after all
Ben Croston <ben@croston.org>
parents:
14
diff
changeset
|
74 commands = str(commands).encode() |
10 | 75 if IS_WINDOWS: |
0 | 76 self._output_win(commands) |
77 else: | |
14 | 78 self._output_unix(commands) |
0 | 79 |
80 def _getqueues_unix(self): | |
81 queues = [] | |
26 | 82 try: |
83 output = subprocess.check_output(['lpstat','-p'], universal_newlines=True) | |
84 except subprocess.CalledProcessError: | |
85 return [] | |
0 | 86 for line in output.split('\n'): |
87 if line.startswith('printer'): | |
88 queues.append(line.split(' ')[1]) | |
89 return queues | |
90 | |
91 def _getqueues_win(self): | |
8 | 92 printers = [] |
93 for (a,b,name,d) in win32print.EnumPrinters(win32print.PRINTER_ENUM_LOCAL): | |
94 printers.append(name) | |
95 return printers | |
0 | 96 |
97 def getqueues(self): | |
10 | 98 """Returns a list of printer queues on local machine""" |
99 if IS_WINDOWS: | |
0 | 100 return self._getqueues_win() |
101 else: | |
102 return self._getqueues_unix() | |
103 | |
1 | 104 def setqueue(self, queue): |
10 | 105 """Set the printer queue""" |
0 | 106 self.queue = queue |
107 | |
2
ad9d9bf61243
Change direct transfer to direct thermal
Ben Croston <ben@fuzzyduckbrewery.co.uk>
parents:
1
diff
changeset
|
108 def setup(self, direct_thermal=None, label_height=None, label_width=None): |
10 | 109 """Set up the label printer. Parameters are not set if they are None. |
110 | |
111 direct_thermal - True if using direct thermal labels | |
112 label_height - tuple (label height, label gap) in dots | |
113 label_width - in dots | |
114 """ | |
0 | 115 commands = '\n' |
2
ad9d9bf61243
Change direct transfer to direct thermal
Ben Croston <ben@fuzzyduckbrewery.co.uk>
parents:
1
diff
changeset
|
116 if direct_thermal: |
0 | 117 commands += ('OD\n') |
118 if label_height: | |
119 commands += ('Q%s,%s\n'%(label_height[0],label_height[1])) | |
120 if label_width: | |
121 commands += ('q%s\n'%label_width) | |
122 self.output(commands) | |
123 | |
124 def store_graphic(self, name, filename): | |
10 | 125 """Store a .PCX file on the label printer |
126 | |
127 name - name to be used on printer | |
128 filename - local filename | |
129 """ | |
130 assert filename.lower().endswith('.pcx') | |
0 | 131 commands = '\nGK"%s"\n'%name |
132 commands += 'GK"%s"\n'%name | |
133 size = os.path.getsize(filename) | |
134 commands += 'GM"%s"%s\n'%(name,size) | |
135 self.output(commands) | |
136 self.output(open(filename,'rb').read()) | |
137 | |
138 if __name__ == '__main__': | |
139 z = zebra() | |
140 print 'Printer queues found:',z.getqueues() | |
141 z.setqueue('zebra_python_unittest') | |
2
ad9d9bf61243
Change direct transfer to direct thermal
Ben Croston <ben@fuzzyduckbrewery.co.uk>
parents:
1
diff
changeset
|
142 z.setup(direct_thermal=True, label_height=(406,32), label_width=609) # 3" x 2" direct thermal label |
1 | 143 z.store_graphic('logo','logo.pcx') |
0 | 144 label = """ |
145 N | |
146 GG419,40,"logo" | |
147 A40,80,0,4,1,1,N,"Tangerine Duck 4.4%" | |
148 A40,198,0,3,1,1,N,"Duty paid on 39.9l" | |
1 | 149 A40,240,0,3,1,1,N,"Gyle: 127 Best Before: 16/09/2011" |
0 | 150 A40,320,0,4,1,1,N,"Pump & Truncheon" |
151 P1 | |
152 """ | |
153 z.output(label) | |
154 |