zebra-day 1.0.2__py3-none-any.whl → 2.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. zebra_day/cli/gui.py +89 -6
  2. zebra_day/etc/printer_config.json +2 -14
  3. zebra_day/etc/printer_config.template.json +17 -9
  4. zebra_day/etc/tmp_printers120.json +10 -0
  5. zebra_day/etc/tmp_printers145.json +10 -0
  6. zebra_day/etc/tmp_printers207.json +10 -0
  7. zebra_day/etc/tmp_printers469.json +10 -0
  8. zebra_day/etc/tmp_printers485.json +10 -0
  9. zebra_day/etc/tmp_printers531.json +10 -0
  10. zebra_day/etc/tmp_printers540.json +10 -0
  11. zebra_day/etc/tmp_printers542.json +10 -0
  12. zebra_day/etc/tmp_printers552.json +10 -0
  13. zebra_day/etc/tmp_printers715.json +10 -0
  14. zebra_day/etc/tmp_printers972.json +10 -0
  15. zebra_day/files/blank_preview.png +0 -0
  16. zebra_day/files/corners_20cmX30cm_preview.png +0 -0
  17. zebra_day/files/generic_2inX1in_preview.png +0 -0
  18. zebra_day/files/test_png_12020.png +0 -0
  19. zebra_day/files/test_png_12352.png +0 -0
  20. zebra_day/files/test_png_15472.png +0 -0
  21. zebra_day/files/test_png_24493.png +0 -0
  22. zebra_day/files/test_png_30069.png +0 -0
  23. zebra_day/files/test_png_47791.png +0 -0
  24. zebra_day/files/test_png_47799.png +0 -0
  25. zebra_day/files/test_png_55588.png +0 -0
  26. zebra_day/files/test_png_58809.png +0 -0
  27. zebra_day/files/test_png_67242.png +0 -0
  28. zebra_day/files/test_png_89893.png +0 -0
  29. zebra_day/files/tube_20mmX30mmA_preview.png +0 -0
  30. zebra_day/print_mgr.py +136 -80
  31. zebra_day/templates/modern/config_backups.html +59 -0
  32. zebra_day/templates/modern/config_editor.html +95 -0
  33. zebra_day/templates/modern/config_new.html +93 -0
  34. zebra_day/templates/modern/print_request.html +9 -5
  35. zebra_day/templates/modern/printer_detail.html +161 -34
  36. zebra_day/templates/modern/printers.html +17 -6
  37. zebra_day/templates/modern/template_editor.html +7 -4
  38. zebra_day/web/app.py +84 -7
  39. zebra_day/web/routers/api.py +155 -5
  40. zebra_day/web/routers/ui.py +155 -570
  41. {zebra_day-1.0.2.dist-info → zebra_day-2.0.0.dist-info}/METADATA +74 -13
  42. {zebra_day-1.0.2.dist-info → zebra_day-2.0.0.dist-info}/RECORD +46 -57
  43. zebra_day/bin/fetch_zebra_config.py +0 -15
  44. zebra_day/bin/generate_coord_grid_zpl.py +0 -50
  45. zebra_day/bin/print_zpl_from_file.py +0 -21
  46. zebra_day/bin/probe_new_label_dimensions.py +0 -75
  47. zebra_day/bin/scan_for_networed_zebra_printers.py +0 -23
  48. zebra_day/bin/scan_for_networed_zebra_printers_arp_scan.sh +0 -1
  49. zebra_day/bin/scan_for_networed_zebra_printers_curl.sh +0 -30
  50. zebra_day/bin/zserve.py +0 -1062
  51. zebra_day/templates/base.html +0 -36
  52. zebra_day/templates/bpr.html +0 -72
  53. zebra_day/templates/build_new_config.html +0 -36
  54. zebra_day/templates/build_print_request.html +0 -32
  55. zebra_day/templates/chg_ui_style.html +0 -19
  56. zebra_day/templates/edit_template.html +0 -128
  57. zebra_day/templates/edit_zpl.html +0 -37
  58. zebra_day/templates/index.html +0 -82
  59. zebra_day/templates/legacy/base.html +0 -37
  60. zebra_day/templates/legacy/bpr.html +0 -72
  61. zebra_day/templates/legacy/build_new_config.html +0 -36
  62. zebra_day/templates/legacy/build_print_request.html +0 -32
  63. zebra_day/templates/legacy/chg_ui_style.html +0 -19
  64. zebra_day/templates/legacy/edit_template.html +0 -128
  65. zebra_day/templates/legacy/edit_zpl.html +0 -37
  66. zebra_day/templates/legacy/index.html +0 -82
  67. zebra_day/templates/legacy/list_prior_configs.html +0 -24
  68. zebra_day/templates/legacy/print_result.html +0 -30
  69. zebra_day/templates/legacy/printer_details.html +0 -25
  70. zebra_day/templates/legacy/printer_status.html +0 -70
  71. zebra_day/templates/legacy/save_result.html +0 -17
  72. zebra_day/templates/legacy/send_print_request.html +0 -34
  73. zebra_day/templates/legacy/simple_print.html +0 -94
  74. zebra_day/templates/legacy/view_pstation_json.html +0 -29
  75. zebra_day/templates/list_prior_configs.html +0 -24
  76. zebra_day/templates/print_result.html +0 -30
  77. zebra_day/templates/printer_details.html +0 -25
  78. zebra_day/templates/printer_status.html +0 -70
  79. zebra_day/templates/save_result.html +0 -17
  80. zebra_day/templates/send_print_request.html +0 -34
  81. zebra_day/templates/simple_print.html +0 -94
  82. zebra_day/templates/view_pstation_json.html +0 -29
  83. {zebra_day-1.0.2.dist-info → zebra_day-2.0.0.dist-info}/WHEEL +0 -0
  84. {zebra_day-1.0.2.dist-info → zebra_day-2.0.0.dist-info}/entry_points.txt +0 -0
  85. {zebra_day-1.0.2.dist-info → zebra_day-2.0.0.dist-info}/licenses/LICENSE +0 -0
  86. {zebra_day-1.0.2.dist-info → zebra_day-2.0.0.dist-info}/top_level.txt +0 -0
zebra_day/bin/zserve.py DELETED
@@ -1,1062 +0,0 @@
1
- import cherrypy
2
- import os
3
- import sys
4
- import time
5
- from datetime import datetime, timedelta, date
6
- import pytz
7
- import yaml
8
- import json
9
- import tempfile
10
-
11
- import zebra_day.print_mgr as zdpm
12
- import zebra_day.cmd_mgr as zdcm
13
-
14
- ENVCHECK = os.environ.get(
15
- "ZDAY", "skip"
16
- ) # If this envvar is set when starring zday, requests to index are ignored unless accomanied by the matching ?envcheck string
17
-
18
-
19
- class Zserve(object):
20
- def st(self):
21
- self.css_file = "static/style.css"
22
-
23
- def __init__(self, relpath, abpath):
24
- self.rel_p = relpath
25
- self.abs_p = abpath
26
- self.zp = zdpm.zpl()
27
- self.css_file = "static/oakland.css"
28
- try:
29
- ipcmd = "(ip addr show | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1' || ifconfig | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1') 2>/dev/null"
30
- print(ipcmd)
31
- self.ip = os.popen(ipcmd).readline().rstrip()
32
- self.ip_root = ".".join(self.ip.split(".")[:-1])
33
- except Exception as e:
34
- self.ip = "192.168.1.0" # FAILS
35
- self.ip_root = "192.168.1" # FAILS
36
-
37
- @cherrypy.expose
38
- def chg_ui_style(self, css_file=None):
39
- if css_file not in [None]:
40
- self.css_file = "static/" + css_file
41
- raise cherrypy.HTTPRedirect("/")
42
-
43
- ret_html = "<h1>Change The Zebra Day UI Style</h1><ul><small><a href=/>home</a></small><br><ul><hr><br><ul>Available Style CSS Files:<br><ul>"
44
- for i in sorted(os.listdir(self.rel_p + "/static")):
45
- if i.endswith(".css"):
46
- ret_html += f"<li><a href=chg_ui_style?css_file={i} >{i}</a>"
47
- ret_html += "</ul></ul></ul>"
48
-
49
- return self.wrap_content(ret_html)
50
-
51
- @cherrypy.expose
52
- def printer_details(self, printer_name=None, lab=None):
53
-
54
- ret_html = f"""<h1>Printer Information For {printer_name} In Lab {lab}</h1>
55
- <ul><small><a href=/>HOME</a> ... <a href=printer_status?lab={lab}>printer status report</a></small>
56
- <hr><ul>
57
- <ul>
58
- <h2>Json Stored Data</h2>
59
- <ul><ul>"""
60
-
61
- for i in sorted(self.zp.printers['labs'][lab][printer_name]):
62
- ret_html += f"<li>{i} :::: {self.zp.printers['labs'][lab][printer_name][i]}"
63
-
64
- ret_html += "</ul></ul><br><h2>Configuration Retrieved From The Zebra Printer</h2><ul><ul>"
65
-
66
- ret_html += "<li>".join(zdcm.ZebraPrinter(self.zp.printers['labs'][lab][printer_name]['ip_address']).get_configuration().splitlines())
67
- ret_html += "</pre></ul>"
68
-
69
- return self.wrap_content(ret_html)
70
-
71
- @cherrypy.expose
72
- def probe_network_for_zebra_printers(self, ip_stub=None, scan_wait="0.25"):
73
- if ip_stub in [None]:
74
- ip_stub = ".".join(self.ip.split(".")[:-1])
75
- ret_html = f"<h1>Probing {ip_stub} For Zebra Printers</h1><br><a href=printer_status>BACK TO THE NETWORK ZEBRA REPORT</a><ul><hr><ul>"
76
- try:
77
- self.detected_printer_ips = {}
78
- except Exception as e:
79
- self.detected_printer_ips = {}
80
-
81
- res = os.popen(
82
- self.rel_p
83
- + f"/bin/scan_for_networed_zebra_printers_curl.sh {ip_stub} {scan_wait}"
84
- )
85
- for i in res.readlines():
86
- ii = i.rstrip()
87
- sl = ii.split("|")
88
- if len(sl) > 1:
89
- zp = sl[0]
90
- ip = sl[1]
91
- model = sl[2]
92
- serial = sl[3]
93
- status = sl[4]
94
- arp_data = sl[5]
95
- self.detected_printer_ips[ip] = [model, serial, status, arp_data]
96
- ret_html = (
97
- ret_html
98
- + f"""
99
- <li>{zp} ::: <a href=http://{ip} target=new>{ip}</a> ::: {model} ::: {serial} ::: {status} ::: {arp_data}"""
100
- )
101
-
102
- self._restart()
103
-
104
- return self.wrap_content(ret_html)
105
-
106
- @cherrypy.expose
107
- def list_prior_printer_config_files(self):
108
- ret_html = """
109
- <h1> Saved Printer Config JSON Files</h1><ul><small><a href=/>home</a></small><br><ul><hr><ul>
110
- If you wish to restore from one of these files, download the one you'd like, open in a text editor, then copy the contents of the file into <a href=view_pstation_json>the printers json editing form</a> and save a new json file. <br><ul><i><small>note: the existing file will have a backup created and accessible here</small></i>.<br><br><ul><hr><br>
111
- <ul>"""
112
-
113
- bkup_d = self.rel_p + "/etc/old_printer_config/"
114
-
115
- for i in sorted(os.listdir(bkup_d)):
116
- bkup_fn = f"etc/old_printer_config/{i}"
117
- ret_html = ret_html + f"<li><a href=etc/old_printer_config/{i} >{i}</a>"
118
-
119
- return self.wrap_content(ret_html)
120
-
121
- @cherrypy.expose
122
- def probe_zebra_printers_add_to_printers_json(
123
- self, ip_stub="192.168.1", scan_wait="0.25", lab="scan-results"
124
- ):
125
- self.zp.probe_zebra_printers_add_to_printers_json(
126
- ip_stub=ip_stub, scan_wait=scan_wait, lab=lab
127
- )
128
-
129
- os.system("sleep 2.2")
130
- raise cherrypy.HTTPRedirect(f"printer_status?lab={lab}")
131
-
132
- @cherrypy.expose
133
- def printer_status(self, lab="scan-results"):
134
- if lab not in self.zp.printers["labs"]:
135
- return f"ERROR-- there is no record for this lab, {lab} in the printers.json. Please go <a href=/>home</a> and check the printers.json record to confirm it is valid. If necessary, you may clear the json and re-build it from a network scan."
136
-
137
- printer_deets = {}
138
- ret_html = f"""<h1>Printer Status Summary For {lab}</h1><small><a href=/>BACK HOME</a></small><ul><hr> <br> <ul><table border=1 ><tr><th>Printer Name</th><th>Printer IP</th><th>Label Style Available</th><th>Status on Network</th></tr>"""
139
-
140
- pips = {}
141
- try:
142
- pips = self.detected_printer_ips.copy()
143
- except Exception as e:
144
- self.detected_printer_ips = {}
145
-
146
- for pname in self.zp.printers["labs"][lab]:
147
- pip = self.zp.printers["labs"][lab][pname]["ip_address"]
148
- if pip in self.detected_printer_ips:
149
- del pips[pip]
150
-
151
- serial = self.zp.printers["labs"][lab][pname]["serial"].replace(" ", "_")
152
- model = self.zp.printers["labs"][lab][pname]["model"]
153
- lzs_links = "<small>"
154
- default = " >"
155
- for lzs in self.zp.printers["labs"][lab][pname]["label_zpl_styles"]:
156
- lzs_links += f"""<small>{default} <a href=edit_zpl >{lzs}</a> (<a target=pl href="_print_label?lab={lab}&printer={pname}&printer_ip={pip}&label_zpl_style={lzs}&uid_barcode={pip}&alt_a={model}&alt_b={serial}&alt_c={lab}&alt_d={lab}" >test</a>)<br>"""
157
- if default in [" >"]:
158
- lzs_links += "<br><ul><div style='height: 1px; background-color: pink; width:97%;' class=hrTiny >"
159
- default = ""
160
- lzs_links += "</ul></small>"
161
-
162
- printer_deets[pname] = [
163
- pip,
164
- lzs_links,
165
- ] # "...".join(self.zp.printers['labs'][lab][pname]['label_zpl_styles'])]
166
- print(pname, pip)
167
- print(f"curl -m {pip}")
168
- cres = os.popen(f"curl -m 4 {pip}").readlines()
169
- for ci in cres:
170
- if len(ci.split("Status:")) > 1:
171
- printer_deets[pname].append(ci)
172
-
173
- ptype = ""
174
- for pret in printer_deets:
175
- try:
176
- pip2 = printer_deets[pret][0]
177
-
178
- pip2a = f"<small>{self.zp.printers['labs'][lab][pret]['model']} <br>{self.zp.printers['labs'][lab][pret]['serial']}</small>" # "" if pip2 not in self.detected_printer_ips else " / ".join(self.detected_printer_ips[pip2])
179
- ptype = printer_deets[pret][1]
180
- pconnect = printer_deets[pret][2]
181
- serial = self.zp.printers["labs"][lab][pret]["serial"].replace(" ", "_")
182
- model = self.zp.printers["labs"][lab][pret]["model"]
183
- arp_data = self.zp.printers["labs"][lab][pret]["arp_data"]
184
- ret_html = (
185
- ret_html
186
- + f"<tr><td>{pret}<br><small>{pip2a}</small></td><td><a href=http://{pip2} target=pcheck>{pip2}</a><br><small>{arp_data}</small><br></td><td valign=top ><br>{ptype}</td><td>{pconnect} <small>if state=PAUSED, each printer has a specific pause/unpause button, not one of the menu buttons, which is likely flashing and needs to be pressed</small><small><a target=new href=printer_details?printer_name={pret}&lab={lab} >...printer deets</a></small></td></tr>"
187
- )
188
- except Exception as e:
189
- print(e)
190
- ret_html = (
191
- ret_html
192
- + f"<tr><td>{pret}</td><td><a href=http://{pip2} target=pcheck>{pip2}</a></td><td>{ptype}<br></td><td>UNABLE TO CONNECT<br><small><a target=new href=printer_details?printer_name={pret}&lab={lab} >...printer deets</a></small></td></tr>"
193
- )
194
-
195
- zaddl = ""
196
- for zi in pips:
197
- zaddl = zaddl + f"<li>{zi} :: {pips[zi]}"
198
-
199
- ret_html = (
200
- ret_html
201
- + f"""</table></ul><ul>
202
- </ul><br><hr>
203
- <h2>Build New Printers Config json // Scan Network For Discoverable Printers</h2><ul>this will probe for printers, and with all discovered printers will create a new printers json and over-write the current fleet data for this lab. <form id='myForm'action=probe_zebra_printers_add_to_printers_json >Enter IP Root To Scan: <input type=text value={self.ip_root} name=ip_stub >
204
- Select (or enter new) lab:
205
- {self._get_labs_datalist()}
206
- <input type=submit></form> <a href=list_prior_printer_config_files>the current printers json will be backed up and can be foud here.</a> </ul>
207
- """
208
- )
209
-
210
- return self.wrap_content(ret_html)
211
-
212
- def _get_labs_datalist(self):
213
- dat_list = "<input type=text name=lab list=lab_names><datalist id=lab_names>"
214
- for ln in sorted(self.zp.printers["labs"].keys()):
215
- dat_list += f"<option value={ln}>{ln}</option>"
216
- dat_list += "</datalist>"
217
- return dat_list
218
-
219
- @cherrypy.expose
220
- def index(self, envcheck="skip"):
221
- if envcheck != ENVCHECK:
222
- # client_ip = cherrypy.request.remote.ip
223
- os.system("sleep 31")
224
- return ""
225
-
226
- llinks = ""
227
- try:
228
- for lb in self.zp.printers["labs"].keys():
229
- llinks = (
230
- llinks
231
- + f"<li><a href=printer_status?lab={lb} > {lb} Zebra Printer Status </a>"
232
- )
233
- except Exception as e:
234
- llinks = (
235
- llinks + "<li> no labs found. try scanning and resetting printers.json"
236
- )
237
-
238
- llinks = llinks + "<li> __end__ </ul>"
239
-
240
- ret_html = (
241
- """
242
- <h1>Daylily Zebra Printer And Print Request Manager</h1><ul><small>ip address detected :: """
243
- + self.ip
244
- + """</small>
245
- <hr><ul>
246
- <hr>
247
- <h2>Zebra Printer Fleet Status, By Site</h2>
248
- <ul>detected sites:
249
- <ul><ul>"""
250
- + llinks
251
- + """</ul><br></ul>
252
- <hr>
253
- <h2>Print Labels Manually UI</h2>
254
- <ul>this tool is meant to for infrequent use, the intention of `zebra` is to be used to create more fully featured tools/systems.
255
- <ul><ul>
256
- <li><a href=simple_print_request>print labels manually</a>
257
- </ul></ul></ul>
258
- <hr><br>
259
-
260
- <h2>Zebra Printer JSON Config</h2>
261
- <ul>this json file defines the zebra printers available to the package
262
- <ul><ul>
263
- <li><a href=view_pstation_json >view and edit json</a>
264
- <br>
265
-
266
- <li><a href=list_prior_printer_config_files>view backed up printers json config files</a>
267
- <li><a href=build_new_printers_config_json>build a new printers config json</a></ul><br>
268
- </ul></ul>
269
- <hr>
270
- <h2>Send Print Requests</h2>
271
- <ul>to accessible zebra printers
272
- <ul><ul><ul>
273
- <li><a href=bpr >(use me) select lab + printer + label style</a>
274
- <li><a href=send_print_request >same as above, but only stable label templates</a>
275
- </ul><br>
276
- </ul></ul>
277
- <hr><h2>Edit Label Templates</h2>
278
- <ul>modify existing templates, create new templates, preview changes & test print new designs
279
- <ul><ul>
280
- <li><a href=edit_zpl>edit zpl files</a></ul><br>
281
- </ul></ul>
282
- <hr><h2>Github Docs</h2>
283
- <ul>for this and other daylily repos
284
- <ul><ul><small>
285
- <li><a href=https://github.com/Daylily-Informatics/zebra_day >zebra_day</a>
286
- <li><a href=https://github.com/Daylily-Informatics/fedex_tracking_day >fedex_tracking_day</a>
287
- <li><a href=https://github.com/Daylily-Informatics/yaml_config_day >yaml_config_day</a>
288
- </small>
289
- </ul></ul>
290
- </ul></ul></ul>
291
- <div style="position: fixed; border:5px; bottom: 0; right: 0;padding: 8px; text-decoration:none;" ><a href=chg_ui_style style='font-size: 18px;' id="bottomRightLink">change ui style</a></div>
292
- """
293
- )
294
-
295
- return self.wrap_content(ret_html)
296
-
297
- @cherrypy.expose
298
- def build_new_printers_config_json(self):
299
- ret_html = f"""
300
- <h2>Scan Network For Zebra Printers</h2><ul><small><a href=/>home</a></small><br><ul>this will probe for printers, and with all discovered printers will create a new printers json and over-write the current fleet data for this lab. <form id='myForm' action=probe_zebra_printers_add_to_printers_json >
301
- Choose Existing, Or Enter New Lab Code: {self._get_labs_datalist()}
302
- Enter IP Root To Scan: <input type=text value={self.ip_root} name=ip_stub > <input type=submit></form> <a href=list_prior_printer_config_files>the current printers json will be backed up and can be foud here.</a>
303
- """
304
- return self.wrap_content(ret_html)
305
-
306
- @cherrypy.expose
307
- def test_spinner(self):
308
- ret_html = f"""
309
- <h2>Test Spinner On Submit</h2>
310
- <a href=/>XXXX</a>
311
- <form id='myForm' action=x >
312
- <input type=submit></form>
313
- """
314
- return self.wrap_content(ret_html)
315
-
316
- @cherrypy.expose
317
- def x(self, s=15):
318
- os.system(f"sleep {s}")
319
- return self.wrap_content("<div align=center><a href=/>home</a></div>")
320
-
321
- @cherrypy.expose
322
- def send_print_request(self):
323
- ret_html = ""
324
-
325
- for lab in sorted(self.zp.printers["labs"]):
326
- ret_html = (
327
- ret_html
328
- + f"<h1>Lab {lab}</h1><small><a href=/>home</a><br><ul><hr><table width=90% align=center ><tr width=100% ><td width=40%><ul>"
329
- )
330
- for printer in sorted(self.zp.printers["labs"][lab]):
331
- pip = self.zp.printers["labs"][lab][printer]["ip_address"]
332
- plab = self.zp.printers["labs"][lab][printer]["label_zpl_styles"]
333
- ret_html = ret_html + f"<li>{printer} .. {pip}<ul>"
334
- for plabi in sorted(plab):
335
- ret_html = (
336
- ret_html
337
- + f"<li>{plabi} ----- <a href=build_print_request?lab='{lab}'&printer='{printer}'&printer_ip='{pip}'&label_zpl_style='{plabi}'>PRINT THIS TYPE</a>"
338
- )
339
- ret_html = ret_html + "</ul><br>"
340
-
341
- # was going to expose the in development labels styles... maybe latter, as they can be manu
342
- # for ft in sorted(os.listdir(self.rel_p+'/etc/label_styles/tmps/')):
343
-
344
- ret_html += "</td><td width=40% align=center>"
345
-
346
- ret_html = ret_html + " </td></tr></table>"
347
-
348
- return self.wrap_content(ret_html)
349
-
350
- @cherrypy.expose
351
- def build_and_send_raw_print_request(
352
- self,
353
- lab,
354
- printer,
355
- printer_ip="",
356
- label_zpl_style="",
357
- content="",
358
- filename="",
359
- ftag="",
360
- ):
361
- # override zpl_label_style
362
- client_ip = cherrypy.request.remote.ip
363
-
364
- self.zp.print_zpl(
365
- lab=lab,
366
- printer_name=printer,
367
- label_zpl_style=None,
368
- zpl_content=content,
369
- client_ip=client_ip,
370
- )
371
-
372
- @cherrypy.expose
373
- def simple_print_request(self):
374
-
375
- filename = ""
376
- ftag = ""
377
- files = [
378
- f
379
- for f in os.listdir(self.rel_p + "/etc/label_styles/")
380
- if os.path.isfile(os.path.join(self.rel_p + "/etc/label_styles/", f))
381
- ]
382
-
383
-
384
- # Create options for the select element
385
- options = ""
386
- for file in files:
387
- filename = file.split('.zpl')[0] # Remove the .zpl suffix
388
- options += f'<option value="{filename}">{filename}</option>\n'
389
-
390
- # Build the HTML for the select element
391
- select_html = f'<select name="label_zpl_style" id="label_zpl_style">\n{options}</select>'
392
-
393
-
394
- # Fetch the labs and printers data
395
- labs_and_printers = self.zp.printers['labs']
396
- labs_options = '\n'.join([f'<option value="{lab}">{lab}</option>' for lab in labs_and_printers.keys()])
397
-
398
- ret_html = f"""
399
- <h1>Send Label Print Request</h1>
400
- <ul><small><a href=/>home</a></small><hr><ul>
401
- <h3> .. .. .. </h3><ul><hr><ul>
402
- <form action=_print_label>
403
-
404
- <li>UID for Barcode : <input type=text name=uid_barcode ></input><br>
405
- <li>ALT-A : <input type=text name=alt_a ></input><br>
406
- <li>ALT-B : <input type=text name=alt_b ></input><br>
407
- <li>ALT-C : <input type=text name=alt_c ></input><br>
408
- <li>ALT-D : <input type=text name=alt_d ></input><br>
409
- <li>ALT-E : <input type=text name=alt_e ></input><br>
410
- <li>ALT-F : <input type=text name=alt_f ></input><br>
411
-
412
- <!-- Other inputs here -->
413
- <li>Select Lab:
414
- <select id="labSelect" name="lab" onchange="updatePrinters()">
415
- <option value="">Select a Lab</option>
416
- {labs_options}
417
- </select><br>
418
- <li>Select Printer:
419
- <select id="printerSelect" name="printer">
420
- <option value="">Select a Printer</option>
421
- </select><br>
422
- Label ZPL Style (be sure it is apporpriate for the label stock): {select_html} <br>
423
- <input type=submit>
424
- </form>
425
- <script>
426
- function updatePrinters() {{
427
- var labSelect = document.getElementById('labSelect');
428
- var printerSelect = document.getElementById('printerSelect');
429
- var selectedLab = labSelect.value;
430
- var printers = {json.dumps({lab: list(printers.keys()) for lab, printers in labs_and_printers.items()})};
431
-
432
- // Clear current printer options
433
- printerSelect.innerHTML = '<option value="">Select a Printer</option>';
434
-
435
- if (selectedLab in printers) {{
436
- printers[selectedLab].forEach(function(printer) {{
437
- var option = document.createElement('option');
438
- option.value = printer;
439
- option.text = printer;
440
- printerSelect.appendChild(option);
441
- }});
442
- }}
443
- }}
444
- </script>
445
- """
446
-
447
- return self.wrap_content(ret_html)
448
-
449
- @cherrypy.expose
450
- def build_print_request(
451
- self,
452
- lab,
453
- printer,
454
- printer_ip="",
455
- label_zpl_style="",
456
- content="",
457
- filename="",
458
- ftag="",
459
- ):
460
- if label_zpl_style in ["", "None", None] and filename not in ["", "None", None]:
461
- label_zpl_style = filename.split(".zpl")[0]
462
-
463
- ret_html = f"""
464
- <h1>Send Label Print Request</h1>
465
- <ul><small><a href=/>home</a></small><hr><ul>
466
- <h3>{lab} .. {printer} .. {printer_ip} .. {label_zpl_style}</h3><ul><hr><ul>
467
- """
468
-
469
- ret_html = (
470
- ret_html
471
- + """
472
- <form action=_print_label>
473
- <li>UID for Barcode : <input type=text name=uid_barcode ></input><br>
474
- <li>ALT-A : <input type=text name=alt_a ></input><br>
475
- <li>ALT-B : <input type=text name=alt_b ></input><br>
476
- <li>ALT-C : <input type=text name=alt_c ></input><br>
477
- <li>ALT-D : <input type=text name=alt_d ></input><br>
478
- <li>ALT-E : <input type=text name=alt_e ></input><br>
479
- <li>ALT-F : <input type=text name=alt_f ></input><br>
480
- """
481
- )
482
- ret_html = (
483
- ret_html
484
- + f"""
485
- Override Lab: <input type=text name=lab value={lab} ><br>
486
- Override Printer: <input type=text name=printer value={printer} ><br>
487
- Override IP: <input type=text name=printer_ip value={printer_ip} ><br>
488
- Over-Ride label_style_zpl: <input type=text name=label_zpl_style value={label_zpl_style} ><br>
489
- <input type=submit>
490
- </form>
491
- """
492
- )
493
-
494
- return self.wrap_content(ret_html)
495
-
496
- @cherrypy.expose
497
- def _print_label(
498
- self,
499
- lab=None,
500
- printer='',
501
- printer_ip="",
502
- label_zpl_style="",
503
- uid_barcode="",
504
- alt_a="",
505
- alt_b="",
506
- alt_c="",
507
- alt_d="",
508
- alt_e="",
509
- alt_f="",
510
- labSelect=""
511
- ):
512
- if lab == None:
513
- lab = labSelect
514
-
515
- client_ip = cherrypy.request.remote.ip
516
-
517
- ret_s = self.zp.print_zpl(
518
- lab=lab,
519
- printer_name=printer,
520
- label_zpl_style=label_zpl_style,
521
- uid_barcode=uid_barcode,
522
- alt_a=alt_a,
523
- alt_b=alt_b,
524
- alt_c=alt_c,
525
- alt_d=alt_d,
526
- alt_e=alt_e,
527
- alt_f=alt_f,
528
- client_ip=client_ip,
529
- )
530
-
531
- full_url = (
532
- cherrypy.url()
533
- + f"?lab={lab}&printer={printer}&printer_ip={printer_ip}&label_zpl_style={label_zpl_style}&uid_barcode={uid_barcode}&alt_a={alt_a}&alt_b={alt_b}&alt_c={alt_c}&alt_d={alt_d}&alt_e={alt_e}&alt_f={alt_f}"
534
- )
535
-
536
- addl_html = f"<h2>Zday Label Print Request Sent</h2><ul>The URL for this print request(which you can edit and use incurl) is: {full_url}<hr><ul>SUCCESS, LABEL PRINTED<br><ul>"
537
- if len(ret_s.split(".png")) > 1:
538
- addl_html = f"<a href=/>home</a><br><br>SUCCESFULLY CREATED PNG<br><img src=files/{ret_s.split('/')[-1]}><br>"
539
- ret_html = addl_html + "<a href=/>home</a>"
540
-
541
- return self.wrap_content(ret_html)
542
-
543
- @cherrypy.expose
544
- def _restart(self):
545
- os.system(f"touch {self.rel_p}/bin/zserve.py")
546
- os.system("sleep 4")
547
- ret_html = "server restarted"
548
- return self.wrap_content(ret_html)
549
-
550
- @cherrypy.expose
551
- def dl_bin_file(self, fn=None):
552
- # Set the content type and disposition headers for the file
553
- cherrypy.response.headers["Content-Type"] = "image/png"
554
- cherrypy.response.headers[
555
- "Content-Disposition"
556
- ] = f'attachment; filename="{fn}"'
557
-
558
- # Open and serve the PNG file as a static file
559
- try:
560
- with open(fn, "rb") as f:
561
- return f.read()
562
- except FileNotFoundError:
563
- return self.wrap_content("File not found.")
564
-
565
- @cherrypy.expose
566
- def view_pstation_json(self, error_msg=None):
567
- with open(self.zp.printers_filename, "r") as f:
568
- data = json.load(f)
569
- error_display = f'<p style="color:red;">{error_msg}</p>' if error_msg else ""
570
- ret_html = f"""
571
- <br><a href=/>home</a><br>
572
- {error_display}
573
- <form action="save_pstation_json" method="post">
574
- <textarea name="json_data" rows="45" cols="50">{json.dumps(data, indent=4)}</textarea><br>
575
- <input type="submit" value="Save New Printers Config Json & Make Active">
576
- </form>
577
- <ul><ul><hr>
578
- <li><a href=list_prior_printer_config_files>view backed up printers json config files</a>
579
- <ul><Ul>
580
- <hr><hr>
581
- <li>!! <a href=reset_pstation_json>Restore Printer Settings From Default JSON (THIS WILL DELETE YOUR CURRENT FILE!!)</a>
582
- <ul><ul>
583
- <hr><hr><hr>
584
- <li>!! <a href=clear_printers_json>CLEAR contents of current printers.json file !!!! This Cannot Be Undone</a>
585
-
586
- """
587
-
588
- return self.wrap_content(ret_html)
589
-
590
- @cherrypy.expose
591
- def clear_printers_json(self):
592
- self.zp.clear_printers_json()
593
- self._restart()
594
- os.system("sleep 1.2")
595
- referrer = cherrypy.request.headers.get("Referer", "/")
596
- raise cherrypy.HTTPRedirect(referrer)
597
-
598
- @cherrypy.expose
599
- def reset_pstation_json(self):
600
- self.zp.replace_printer_json_from_template()
601
- self._restart()
602
- os.system("sleep 1.2")
603
- referrer = cherrypy.request.headers.get("Referer", "/")
604
- raise cherrypy.HTTPRedirect(referrer)
605
-
606
- @cherrypy.expose
607
- def save_pstation_json(self, json_data):
608
- rec_date = str(datetime.now()).replace(" ", "_")
609
- bkup_pconfig_fn = (
610
- f"{self.rel_p}/etc/old_printer_config/{rec_date}_printer_config.json"
611
- )
612
-
613
- try:
614
- os.system(f"cp {self.zp.printers_filename} {bkup_pconfig_fn}")
615
-
616
- try:
617
- data = json.loads(json_data)
618
- with open(self.zp.printers_filename, "w") as f:
619
- json.dump(data, f, indent=4)
620
-
621
- self.zp.load_printer_json(
622
- json_file=self.zp.printers_filename, relative=False
623
- )
624
-
625
- os.system("sleep 2")
626
- self._restart()
627
- referrer = cherrypy.request.headers.get("Referer", "/")
628
- raise cherrypy.HTTPRedirect(referrer)
629
-
630
- except json.JSONDecodeError as e:
631
- return self.wrap_content(
632
- "<br><br><br><h2>POSSIBLE ERROR SAVING CONFIG JSON</h2><br><ul><ul>Please <a href=/ > go back to the home page, and then visit this page agian</a> .... *IF* you do not see your edits when coming back from the home page (not refreshing this page), then try clearing the json file using a link below the text box.<br>Further error details:<br<ul>"
633
- + self.view_pstation_json(error_msg=str(e))
634
- )
635
-
636
- except Exception as ee:
637
- return self.wrap_content(
638
- "<br><br><br><h2>POSSIBLE ERROR SAVING CONFIG JSON</h2><br><ul><ul>Please <a href=/ > go back to the home page, and then visit this page agian</a> .... *IF* you do not see your edits when coming back from the home page (not refreshing this page), then try clearing the json file the link below the text box.<br>Further error details:<br<ul>"
639
- + self.view_pstation_json(error_msg=str(ee))
640
- )
641
-
642
- return self.wrap_content("how did you get here?.")
643
-
644
- @cherrypy.expose
645
- def edit_zpl(self):
646
- files = [
647
- f
648
- for f in os.listdir(self.rel_p + "/etc/label_styles/")
649
- if os.path.isfile(os.path.join(self.rel_p + "/etc/label_styles/", f))
650
- ]
651
-
652
- file_links = ['<a href="/edit?filename={}">{}</a>'.format(f, f) for f in sorted(files)]
653
-
654
- if not os.path.exists(self.rel_p + "/etc/label_styles/tmps/"):
655
- os.makedirs(self.rel_p + "/etc/label_styles/tmps/")
656
-
657
- filest = [
658
- ft
659
- for ft in os.listdir(self.rel_p + "/etc/label_styles/tmps/")
660
- if os.path.isfile(os.path.join(self.rel_p + "/etc/label_styles/tmps/", ft))
661
- ]
662
-
663
- file_linkst = [
664
- '<a href="/edit?dtype=tmps&filename={}">{}</a>'.format(ft, ft)
665
- for ft in sorted(filest)
666
- ]
667
-
668
- ret_html = """
669
- <a href=/>home</a><br><ul>
670
- To specify a template to use (via the programatic API or <a href=send_print_request>this GUI</a>), use the file name string (not including the path prefix) and remove the trailing '.zpl'. <ul><br><br><ul> ie: <b>test_2inX1in</b></ul> <br><ul><hr><ul><br>stable ZPL templates<br>
671
-
672
- {}
673
- </ul>
674
-
675
- <br><br><hr><br>draft ZPL templates<ul> {} </ul>
676
- """.format(
677
- "<li>" + "</li><li>".join(file_links) + "</li>",
678
- "<li>" + "</li><li>".join(file_linkst) + "</li>",
679
- )
680
-
681
- return self.wrap_content(ret_html)
682
-
683
- @cherrypy.expose
684
- def edit(self, filename=None, dtype=""):
685
- if not filename:
686
- return self.wrap_content("No file selected")
687
-
688
- filepath = os.path.join(
689
- self.rel_p + "/etc/label_styles/" + dtype + "/", filename
690
- )
691
-
692
- with open(filepath, "r") as file:
693
- content = file.read()
694
-
695
- self.labs_dict = self.zp.printers
696
- labs = self.labs_dict["labs"].keys()
697
-
698
- ll = ""
699
- for lab in labs:
700
- ll += f'<option value="{lab}">{lab}</option>'
701
-
702
- ret_html = (
703
- """
704
- <script>
705
- function populatePrinters() {
706
- var lab = document.getElementById("labsDropdown").value;
707
- var printersDropdown = document.getElementById("printersDropdown");
708
- printersDropdown.innerHTML = "";
709
- var labs = """
710
- + str(self.labs_dict["labs"])
711
- + """;
712
- for (var printer in labs[lab]) {
713
- var option = document.createElement("option");
714
- option.text = printer;
715
- option.value = printer;
716
- printersDropdown.add(option);
717
- }
718
- }
719
- </script>
720
- </head>
721
- <body>
722
- <h2>Editing: """
723
- + filename
724
- + """</h2><small><ul><hr><a href=/>home</a> /// <a href=edit_zpl >back to label list</a> /// <a href=https://labelary.com/zpl.html target=x >zpl intro</a></small><br>
725
- <table border=1><tr><td style="vertical-align: top;" >
726
- <form method="post" action="/save" id="textForm">
727
- <textarea name="content" rows="26" cols="40">{cont}</textarea><br/>
728
- <input type="hidden" name="filename" value="{fn}">
729
- <br>TMP File Tag (added to new file name): <input style="width: 100px;" type=text name=ftag value=na >
730
- <input type="submit" value="save draft"> <input type="button" value="Render PNG" onclick="submitToPNGrenderer();">
731
- <hr>
732
- <hr>
733
- <br><h3>PRINT IRL:</h3>
734
- <select id="labsDropdown" name=lab onchange="populatePrinters()">
735
- <option value="">Select Lab</option>{ll}
736
- </select>
737
- <select id="printersDropdown" name=printer>
738
- <option value="">Select Printer</option>
739
- </select>
740
-
741
- <input type="button" value="just format keys from ZPL" onclick="submitToRealPrint();">
742
- <input type="button" value="w/ data inserted to format keys" onclick="submitToLocPrint();">
743
- </form>
744
- </td><td>
745
- <div style="border: 1;" id="pngContainer"></div>
746
- <ul><h2>How To Use This Tool</h2>
747
- <div class=hrMed > </div>
748
- <small><a href=https://labelary.com/viewer.html target=labels>Become Aquainted With ZPL (public docs and tools)</a></small><ul>
749
- <h3>Before Labels, Printers</h3>
750
- <ul>
751
- <li> Each printer supports a maximum area it can print, and the label stock only presents a specific area (ie: 1inch X 1 inch) which the printer can print on. If you are getting unexpected behavior, like partial or no printed data, check these things. Zebra printers will not error if asked to print outside their range, or off the label stock label size.
752
- </ul>
753
- <h3>ZPL Tempate Files</h3>
754
- <ul>
755
- <a href=edit_zpl >stable and draft zpl template files can be found here</a>.
756
- <li>The template filenames follow the pattern (/path/to/file/)(partA_partB.)(zpl)
757
- <ul>
758
- <li>zebra_day identifies templates with '(partA_partB)'
759
- <li>please do not use '_' in tags you specify for template draft file. Otherwise, these can really be any strings you'd like. I try to follow the pattern partA=general description, partB=dimensions.
760
- </ul>
761
- <h4>Stable ZPL Files</h4><ul>
762
- A set of files in active use. These can not be overwritten.
763
- </ul>
764
- <h4>Draft ZPL Files</h4>
765
- <ul>
766
- All template files created using this tool. These also can not be overwritten, each save from this tool creates a new template file (all of which can be used for print requests, hence their immutability)
767
- <br>
768
- Moving a draft to the stable tempates is done by moving the zpl file to the reside with the other stable zpls (done manually).
769
- </ul>
770
- <h3>Create A Template</h3>
771
- <ul>
772
- <h4>Manually</h4>
773
- Draft a zpl file and save to the appropriate place.
774
- <h4>From An Existing Template</h4><ul>
775
- Any stable or draft template can be the starting point for a new draft. <a href=edit_zpl>Select from among these</a>.
776
- <ul>
777
- <li>When you select a template and land on this page, try rendering it to PNG to make sure it behaves as expected. The png renderer prints what edits to this template will look like, the buttons at the bottom use the unedited template.
778
-
779
- </ul>
780
- <li>From <a href=edit_zpl >the list of stable and draft zpl files</a>, click on one youd like to use as a template.
781
- <li>On the following screen (this one), you may edit the file in the text area.
782
- <li>Test your edits by <b>rendering as a png</b> (which will present the label in this 1/2 of the page). There are two other buttons which work not on the edits to this file, but assuming the original template. Use one to print the label zpl with the format keys printed as text, use the other to specify values to be used for format keys.
783
-
784
- <h5>Format Keys</h5>
785
- <ul>
786
- Each ZPL template file can specify points to allow insertion of variables when creating a specific print requrest. These format keys are denoted by {{}}, and there are 7 supported. You may use the same format key multiple times in a zpl template file. You may also use none of the keys. The keys are: <i>{{uid_barcode}} and {{alt_a}} {{alt_a}} {{alt_c}} {{alt_d}} {{alt_e}} {{alt_f}} </i>.<br>These may be used however you'd like in your template, 'uid_barcode' is named differently as a convenience.
787
- <li>The PNG rendering tool here will not substite in your data to these formay points. It will print them as if they were just text to print. You can also send these raw requests to be printed by a physical printer (with no data inserted).
788
- </ul>
789
- </ul>
790
- <h3>Save A Template</h3>
791
- <ul>
792
- Specify a tag to be inserted to your new tempate file, and save when you are ready. Each save will create a new template file.
793
- <h3>Elevate A Draft Template To Stable</h3>
794
- <ul><li>move your draft to a new file which follows the naming conventions to etc/label_styles/.</ul>
795
-
796
- <h2>Use A Template</h2>
797
- <ul>
798
- <li>Determine the template name from the filename. For /path/to/template_root/partA_partB.zpl, the value for the 'label_zpl_style' would be 'partA_partB' ( via this UI and programatically).
799
- <h3>UI</h3>
800
- <ul>
801
- <li> You can send print requests from <a href=build_print_reques >this UI</a> (which is not intended for routine use, but for design of labels and managing/bebugging printer issues) .. <a href=build_print_request?lab=scan-results&printer=Download-Label-png&printer_ip=dl_png&label_zpl_style=test_2inX1in >this is an example using the tube_2inX1in zpl template to send a print request to the PNG rederer</a>. And this is an example using a draft template <a href=build_print_request?lab=scan-results&printer=Download-Label-png&printer_ip=dl_png&label_zpl_style=tube_2inX1in.exampleDraft.2023-10-29_01:29:56.342244 >tube_2inX1in.exampleDraft.2023-10-29_01:29:56.342244</a>
802
- </ul>
803
- <h3>Progamatically</h3>
804
- <ul>
805
- <li>Instantiate a zebra_day print manager
806
-
807
- <br>
808
- <br>
809
- <code>
810
- from zebra_day import print_mgr as zd
811
- </code>
812
- <br><code>
813
- zd_pm = zd.zpl()
814
- </code>
815
- <br><br><br>
816
-
817
- <li> Determine the label style code as above, and use it in the <b>print_zpl</b> call. For the 2 examples above, this would look like:
818
- <br><Br>
819
- <li>for the stable template <b>tube_2inX1in</b>
820
- <br><ul><br>
821
- <code>
822
- d_pm.print_zpl( lab="scan-results", printer_name="Download-Label-png", uid_barcode="somebarcode", alt_a="additional info", label_zpl_style="tube_2inX1in")
823
- </code>
824
- </ul><br><br>
825
-
826
- <li>for the draft template <b> tube_2inX1in.exampleDraft.2023-10-29_01:29:56.342244</b>
827
- <br><br>
828
- <ul> <code>
829
- zd_pm.print_zpl( lab="scan-results", printer_name="Download-Label-png", uid_barcode="somebarcode", alt_a="additional info", label_zpl_style="tube_2inX1in.exampleDraft.2023-10-29_01:29:56.342244")
830
- </code></ul></ul>
831
-
832
- </ul></ul>
833
- <h2>to do</h2>
834
- <ul>
835
- ... use the template file names directly.
836
- </ul>
837
-
838
- </td></tr></table>
839
-
840
- <script>
841
- function submitToLocPrint() {{
842
- var form = document.getElementById('textForm');
843
- form.action = '/build_print_request';
844
- form.submit();
845
- }}
846
-
847
- function submitToRealPrint() {{
848
- var form = document.getElementById('textForm');
849
- var formData = new FormData(form);
850
-
851
- // Create an XMLHttpRequest object
852
- var xhr = new XMLHttpRequest();
853
-
854
- // Set up the request
855
- xhr.open('POST', '/build_and_send_raw_print_request', true);
856
-
857
- // Handle the response (optional, but can be useful for debugging or feedback)
858
- xhr.onload = function() {{
859
- if (xhr.status == 200) {{
860
- console.log('Request was successful. Response:', xhr.responseText);
861
- }} else {{
862
- console.log('Request failed. Returned status:', xhr.status);
863
- }}
864
- }};
865
-
866
- // Send the form data
867
- xhr.send(formData);
868
- }}
869
- </script>
870
- <script>
871
- function submitToPNGrenderer() {{
872
- var form = document.getElementById('textForm');
873
- var formData = new FormData(form);
874
-
875
- fetch('/png_renderer', {{
876
- method: 'POST',
877
- body: formData
878
- }})
879
- .then(response => response.text()) // Treat the response as plain text
880
- .then(pngPath => {{
881
- const pngImage = document.createElement('img');
882
- pngImage.src = pngPath;
883
- const container = document.getElementById('pngContainer');
884
- container.innerHTML = ''; // Clear previous images if any
885
- container.appendChild(pngImage);
886
- }})
887
- .catch(error => {{
888
- console.error('Error:', error);
889
- }});
890
-
891
- event.preventDefault(); // Prevent form from actually submitting and refreshing page
892
- }}
893
-
894
- </script>
895
-
896
- """.format(
897
- cont=content, fn=filename, ll=ll
898
- )
899
- )
900
-
901
- # self.wrap_content(ret_html, close_head_section=False, add_spinner=False)
902
- return self.wrap_content(ret_html)
903
-
904
- @cherrypy.expose
905
- def bpr(self):
906
- self.labs_dict = self.zp.printers
907
- labs = self.labs_dict["labs"].keys()
908
-
909
- ll = ""
910
- for lab in labs:
911
- ll += f'<option value="{lab}">{lab}</option>'
912
-
913
- template_sel = "<select name=label_zpl_style ><option value='select one'>select one</option><option value=stable>--stable templates--</option>"
914
-
915
- for zs in sorted(os.listdir(self.rel_p + "/etc/label_styles/")):
916
- if zs.endswith(".zpl"):
917
- zs = zs.removesuffix(".zpl")
918
- template_sel += f"<option value='{zs}'>{zs}</option>"
919
-
920
- template_sel += f"<option value=draft>--draft templates--</option>"
921
-
922
- for zs in sorted(os.listdir(self.rel_p + "/etc/label_styles/tmps/")):
923
- if zs.endswith(".zpl"):
924
- zs = zs.removesuffix(".zpl")
925
- template_sel += f"<option value='{zs}'>{zs}</option>"
926
- template_sel += f"</select>"
927
-
928
- ret_html = (
929
- """
930
- <script>
931
- function populatePrinters() {
932
- var lab = document.getElementById("labsDropdown").value;
933
- var printersDropdown = document.getElementById("printersDropdown");
934
- printersDropdown.innerHTML = "";
935
- var labs = """
936
- + str(self.labs_dict["labs"])
937
- + """;
938
- for (var printer in labs[lab]) {
939
- var option = document.createElement("option");
940
- option.text = printer;
941
- option.value = printer;
942
- printersDropdown.add(option);
943
- }
944
- }
945
- </script>
946
- </head>
947
- <body>
948
- <h1>Formulate Print Request, step 1</h1>
949
- <ul><small><a href=/>home</a></smal>
950
- <h2>Select Lab + Printer + ZPL Template</h2>
951
- <ul><hr><br>
952
- <p align=center>You will be prompted for the data to print on the next page</p><br><br><ul><br>
953
- <form name=bpr_form action=build_print_request align=center >
954
- select a lab: <select id="labsDropdown" name=lab onchange="populatePrinters()">
955
- <option value="">Select Lab</option>"""
956
- + ll
957
- + """
958
- </select>
959
-
960
- select a printer: <select id="printersDropdown" name=printer>
961
- <option value="">Select Printer</option>
962
- </select>
963
- <br>select a template"""
964
- + template_sel
965
- + """<br>
966
- <input type=submit>
967
- </form>
968
- """
969
- )
970
-
971
- return self.wrap_content(ret_html, close_head_section=False, add_spinner=False)
972
-
973
- @cherrypy.expose
974
- def png_renderer(self, filename, content, lab="", printer="", ftag=""):
975
- png_tmp_f = tempfile.NamedTemporaryFile(
976
- suffix=".png", dir=self.rel_p + "/files", delete=False
977
- ).name
978
-
979
- self.zp.generate_label_png(content, png_fn=png_tmp_f)
980
-
981
- return "files/" + png_tmp_f.split("/")[-1]
982
-
983
- @cherrypy.expose
984
- def save(self, filename, content, lab="", printer="", ftag=""):
985
- rec_date = str(datetime.now()).replace(" ", "_")
986
-
987
- tfn = filename.replace(".zpl", f".{ftag}.{rec_date}.zpl")
988
-
989
- temp_filepath = os.path.join(self.rel_p + "/etc/label_styles/tmps/", tfn)
990
-
991
- with open(temp_filepath, "w") as file:
992
- file.write(content)
993
-
994
- ret_html = "Changes saved to temp file! <br>You may either: (<a href=edit_zpl >go back to the zpl file list</a>) -or- (<a href='/'>go home</a>)"
995
-
996
- return self.wrap_content(ret_html)
997
-
998
- def wrap_content(self, content, close_head_section=True, add_spinner=True):
999
- header = f"""
1000
- <html>
1001
- <head>
1002
- <link rel="stylesheet" href="static/general.css">
1003
- <link rel="stylesheet" href="{self.css_file}">
1004
- """
1005
-
1006
- if close_head_section:
1007
- header += """
1008
- </head>
1009
- """
1010
- if add_spinner:
1011
- header += """
1012
- <body>
1013
- <div id="spinner" class="spinner-hidden">
1014
- <div class="loader"></div>
1015
- </div>
1016
- """
1017
-
1018
- footer = """
1019
- <script>
1020
- document.getElementById('myForm').addEventListener('submit', function(event) {
1021
- // When the form is submitted, show the spinner
1022
- document.getElementById('spinner').classList.remove('spinner-hidden');
1023
-
1024
- // The actual submission will proceed, and the new page will start loading.
1025
- // As the new page loads, the current page (and spinner) will be unloaded.
1026
- });
1027
- </script>
1028
- </body>
1029
- </html>
1030
- """
1031
-
1032
- return header + content + footer
1033
-
1034
-
1035
- if __name__ == "__main__":
1036
- rel_path_to_pkg_dir = sys.argv[1]
1037
- cwd_path = os.path.abspath(rel_path_to_pkg_dir)
1038
-
1039
- # munge the two paths to get a clean prefix to use
1040
- # disabled, was causing problems
1041
- lng = cwd_path
1042
- srt = rel_path_to_pkg_dir
1043
- if len(lng.split("/")) < len(srt.split("/")):
1044
- raise Exception(
1045
- f" This path is converting to absolute longer than the relative.... problems. {lng} ... {srt}"
1046
- )
1047
-
1048
- cherrypy.config.update(
1049
- {
1050
- "tools.staticdir.on": True,
1051
- "tools.staticdir.dir": cwd_path,
1052
- "tools.staticdir.index": "index.html",
1053
- "server.socket_host": "0.0.0.0",
1054
- "server.socket_port": 8118,
1055
- "server.thread_pool": 20,
1056
- "server.socket_queue_size": 20,
1057
- "tools.sessions.on": True,
1058
- "tools.sessions.timeout": 199, # Session timeout in minutes
1059
- }
1060
- )
1061
-
1062
- cherrypy.quickstart(Zserve(f"{srt}", f"/{cwd_path}"), "/")