zebra-day 0.0.37__py3-none-any.whl → 1.0.2__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 (181) hide show
  1. zebra_day/__init__.py +35 -0
  2. zebra_day/bin/__init__.py +0 -0
  3. zebra_day/bin/fetch_zebra_config.py +15 -0
  4. zebra_day/bin/generate_coord_grid_zpl.py +50 -0
  5. zebra_day/bin/print_zpl_from_file.py +21 -0
  6. zebra_day/bin/probe_new_label_dimensions.py +75 -0
  7. zebra_day/bin/scan_for_networed_zebra_printers_arp_scan.sh +1 -0
  8. zebra_day/bin/scan_for_networed_zebra_printers_curl.sh +30 -0
  9. zebra_day/bin/zserve.py +701 -259
  10. zebra_day/cli/__init__.py +240 -0
  11. zebra_day/cli/cognito.py +121 -0
  12. zebra_day/cli/gui.py +255 -0
  13. zebra_day/cli/printer.py +168 -0
  14. zebra_day/cli/template.py +176 -0
  15. zebra_day/cmd_mgr.py +35 -0
  16. zebra_day/etc/Monoid-Regular-HalfTight-Dollar-0-1-l.ttf +0 -0
  17. zebra_day/etc/label_styles/blank.zpl +0 -0
  18. zebra_day/etc/label_styles/cornersStripOf4Squares_1inX1in.zpl +55 -0
  19. zebra_day/etc/label_styles/corners_1inX2in.zpl +28 -0
  20. zebra_day/etc/label_styles/corners_20cmX30cm.zpl +6 -0
  21. zebra_day/etc/label_styles/corners_smallTube.zpl +7 -0
  22. zebra_day/etc/label_styles/corners_unspecifiedDimensions.zpl +15 -0
  23. zebra_day/etc/label_styles/generic_2inX1in.zpl +21 -0
  24. zebra_day/etc/label_styles/plate_1inX0.25in.zpl +9 -0
  25. zebra_day/etc/label_styles/plate_1inX0.25inHD.zpl +9 -0
  26. zebra_day/etc/label_styles/smallTubeWdotHD_prod.zpl +8 -0
  27. zebra_day/etc/label_styles/smallTubeWdot_corners.zpl +7 -0
  28. zebra_day/etc/label_styles/smallTubeWdot_prod.zpl +8 -0
  29. zebra_day/etc/label_styles/smallTubeWdot_prodAlt1.zpl +6 -0
  30. zebra_day/etc/label_styles/smallTubeWdot_prodAlt1b.zpl +3 -0
  31. zebra_day/etc/label_styles/smallTubeWdot_prodV2.zpl +8 -0
  32. zebra_day/etc/label_styles/smallTubeWdot_reagent.zpl +29 -0
  33. zebra_day/etc/label_styles/stripOf4Squares_1inX1in.zpl +32 -0
  34. zebra_day/etc/label_styles/test_800dX800dCoordinateArray.zpl +1 -0
  35. zebra_day/etc/label_styles/tmps/.hold +0 -0
  36. zebra_day/etc/label_styles/tmps/tmp_zpl_templates.here +0 -0
  37. zebra_day/etc/label_styles/tube_20mmX30mmA.zpl +7 -0
  38. zebra_day/etc/label_styles/tube_2inX0.3in.zpl +15 -0
  39. zebra_day/etc/label_styles/tube_2inX0.5in.zpl +15 -0
  40. zebra_day/etc/label_styles/tube_2inX0.5inHD.zpl +15 -0
  41. zebra_day/etc/label_styles/tube_2inX1in.zpl +25 -0
  42. zebra_day/etc/label_styles/tube_2inX1inHD.zpl +22 -0
  43. zebra_day/etc/label_styles/tube_2inX1inHDv3.zpl +21 -0
  44. zebra_day/etc/old_printer_config/.hold +0 -0
  45. zebra_day/etc/old_printer_config/2026-02-01_01:50:25.022846_printer_config.json +1 -0
  46. zebra_day/etc/old_printer_config/2026-02-01_01:50:25.033657_printer_config.json +1 -0
  47. zebra_day/etc/old_printer_config/2026-02-01_01:50:25.039597_printer_config.json +3 -0
  48. zebra_day/etc/old_printer_config/2026-02-01_01:50:25.047295_printer_config.json +1 -0
  49. zebra_day/etc/old_printer_config/2026-02-01_01:50:25.055804_printer_config.json +1 -0
  50. zebra_day/etc/old_printer_config/2026-02-01_01:50:25.061337_printer_config.json +3 -0
  51. zebra_day/etc/old_printer_config/2026-02-01_01:51:24.073326_printer_config.json +1 -0
  52. zebra_day/etc/old_printer_config/2026-02-01_01:51:24.081950_printer_config.json +1 -0
  53. zebra_day/etc/old_printer_config/2026-02-01_01:51:24.088251_printer_config.json +3 -0
  54. zebra_day/etc/old_printer_config/2026-02-01_01:51:24.096501_printer_config.json +1 -0
  55. zebra_day/etc/old_printer_config/2026-02-01_01:51:24.104767_printer_config.json +1 -0
  56. zebra_day/etc/old_printer_config/2026-02-01_01:51:24.110364_printer_config.json +3 -0
  57. zebra_day/etc/old_printer_config/2026-02-01_01:51:24.118239_printer_config.json +1 -0
  58. zebra_day/etc/old_printer_config/2026-02-01_01:51:24.125950_printer_config.json +1 -0
  59. zebra_day/etc/old_printer_config/2026-02-01_01:51:24.349866_printer_config.json +1 -0
  60. zebra_day/etc/old_printer_config/2026-02-01_01:51:24.361085_printer_config.json +3 -0
  61. zebra_day/etc/old_printer_config/2026-02-01_01:51:24.558323_printer_config.json +1 -0
  62. zebra_day/etc/old_printer_config/2026-02-01_01:51:24.565756_printer_config.json +3 -0
  63. zebra_day/etc/old_printer_config/2026-02-01_01:51:29.739070_printer_config.json +16 -0
  64. zebra_day/etc/old_printer_config/2026-02-01_01:51:29.753796_printer_config.json +1 -0
  65. zebra_day/etc/old_printer_config/2026-02-01_01:51:29.760201_printer_config.json +3 -0
  66. zebra_day/etc/old_printer_config/2026-02-01_01:51:29.768747_printer_config.json +1 -0
  67. zebra_day/etc/old_printer_config/2026-02-01_01:51:29.775312_printer_config.json +3 -0
  68. zebra_day/etc/old_printer_config/2026-02-01_01:51:29.782533_printer_config.json +1 -0
  69. zebra_day/etc/old_printer_config/2026-02-01_01:51:29.789287_printer_config.json +1 -0
  70. zebra_day/etc/old_printer_config/2026-02-01_01:51:29.794230_printer_config.json +3 -0
  71. zebra_day/etc/old_printer_config/2026-02-01_01:51:29.800021_printer_config.json +5 -0
  72. zebra_day/etc/printer_config.json +16 -0
  73. zebra_day/etc/printer_config.template.json +16 -0
  74. zebra_day/etc/tmp_printers0.json +5 -0
  75. zebra_day/etc/tmp_printers374.json +5 -0
  76. zebra_day/etc/tmp_printers383.json +5 -0
  77. zebra_day/etc/tmp_printers450.json +5 -0
  78. zebra_day/etc/tmp_printers504.json +5 -0
  79. zebra_day/etc/tmp_printers608.json +5 -0
  80. zebra_day/etc/tmp_printers657.json +5 -0
  81. zebra_day/etc/tmp_printers838.json +5 -0
  82. zebra_day/etc/tmp_printers839.json +5 -0
  83. zebra_day/etc/tmp_printers933.json +5 -0
  84. zebra_day/etc/tmp_printers957.json +5 -0
  85. zebra_day/exceptions.py +88 -0
  86. zebra_day/files/.hold +0 -0
  87. zebra_day/files/hold +0 -0
  88. zebra_day/files/test_png_17696.png +0 -0
  89. zebra_day/files/test_png_23477.png +0 -0
  90. zebra_day/files/test_png_28157.png +0 -0
  91. zebra_day/files/test_png_35832.png +0 -0
  92. zebra_day/files/test_png_36400.png +0 -0
  93. zebra_day/files/test_png_40816.png +0 -0
  94. zebra_day/files/test_png_49564.png +0 -0
  95. zebra_day/files/test_png_53848.png +0 -0
  96. zebra_day/files/test_png_62542.png +0 -0
  97. zebra_day/files/test_png_91597.png +0 -0
  98. zebra_day/files/test_png_93633.png +0 -0
  99. zebra_day/files/tmpbjo3k7q1.png +0 -0
  100. zebra_day/files/tmpigtr4pwy.png +0 -0
  101. zebra_day/files/zpl_label_tube_2inX1in_2026-02-01_01:51:24.370964.png +0 -0
  102. zebra_day/logging_config.py +74 -0
  103. zebra_day/logs/.hold +0 -0
  104. zebra_day/logs/print_requests.log +2 -0
  105. zebra_day/paths.py +143 -0
  106. zebra_day/print_mgr.py +487 -103
  107. zebra_day/static/datschund.css +140 -0
  108. zebra_day/static/datschund.png +0 -0
  109. zebra_day/static/daylily.png +0 -0
  110. zebra_day/static/favicon.svg +20 -0
  111. zebra_day/static/general.css +99 -0
  112. zebra_day/static/js/zebra_modern.js +172 -0
  113. zebra_day/static/lsmc.css +354 -0
  114. zebra_day/static/moon.jpeg +0 -0
  115. zebra_day/static/oakland.css +197 -0
  116. zebra_day/static/petrichor.css +150 -0
  117. zebra_day/static/popday_daylily.css +140 -0
  118. zebra_day/static/style.css +183 -0
  119. zebra_day/static/triangles.css +122 -0
  120. zebra_day/static/tron.css +277 -0
  121. zebra_day/static/zebra_modern.css +771 -0
  122. zebra_day/static/zebras.css +176 -0
  123. zebra_day/templates/base.html +36 -0
  124. zebra_day/templates/bpr.html +72 -0
  125. zebra_day/templates/build_new_config.html +36 -0
  126. zebra_day/templates/build_print_request.html +32 -0
  127. zebra_day/templates/chg_ui_style.html +19 -0
  128. zebra_day/templates/edit_template.html +128 -0
  129. zebra_day/templates/edit_zpl.html +37 -0
  130. zebra_day/templates/index.html +82 -0
  131. zebra_day/templates/legacy/base.html +37 -0
  132. zebra_day/templates/legacy/bpr.html +72 -0
  133. zebra_day/templates/legacy/build_new_config.html +36 -0
  134. zebra_day/templates/legacy/build_print_request.html +32 -0
  135. zebra_day/templates/legacy/chg_ui_style.html +19 -0
  136. zebra_day/templates/legacy/edit_template.html +128 -0
  137. zebra_day/templates/legacy/edit_zpl.html +37 -0
  138. zebra_day/templates/legacy/index.html +82 -0
  139. zebra_day/templates/legacy/list_prior_configs.html +24 -0
  140. zebra_day/templates/legacy/print_result.html +30 -0
  141. zebra_day/templates/legacy/printer_details.html +25 -0
  142. zebra_day/templates/legacy/printer_status.html +70 -0
  143. zebra_day/templates/legacy/save_result.html +17 -0
  144. zebra_day/templates/legacy/send_print_request.html +34 -0
  145. zebra_day/templates/legacy/simple_print.html +94 -0
  146. zebra_day/templates/legacy/view_pstation_json.html +29 -0
  147. zebra_day/templates/list_prior_configs.html +24 -0
  148. zebra_day/templates/modern/base.html +98 -0
  149. zebra_day/templates/modern/config.html +141 -0
  150. zebra_day/templates/modern/dashboard.html +160 -0
  151. zebra_day/templates/modern/print_request.html +141 -0
  152. zebra_day/templates/modern/print_result.html +88 -0
  153. zebra_day/templates/modern/printer_detail.html +117 -0
  154. zebra_day/templates/modern/printers.html +133 -0
  155. zebra_day/templates/modern/save_result.html +46 -0
  156. zebra_day/templates/modern/template_editor.html +172 -0
  157. zebra_day/templates/modern/templates.html +122 -0
  158. zebra_day/templates/print_result.html +30 -0
  159. zebra_day/templates/printer_details.html +25 -0
  160. zebra_day/templates/printer_status.html +70 -0
  161. zebra_day/templates/save_result.html +17 -0
  162. zebra_day/templates/send_print_request.html +34 -0
  163. zebra_day/templates/simple_print.html +94 -0
  164. zebra_day/templates/view_pstation_json.html +29 -0
  165. zebra_day/web/__init__.py +9 -0
  166. zebra_day/web/app.py +171 -0
  167. zebra_day/web/auth.py +172 -0
  168. zebra_day/web/middleware.py +159 -0
  169. zebra_day/web/routers/__init__.py +2 -0
  170. zebra_day/web/routers/api.py +163 -0
  171. zebra_day/web/routers/ui.py +1051 -0
  172. zebra_day/zpl_renderer.py +273 -0
  173. zebra_day-1.0.2.dist-info/METADATA +786 -0
  174. zebra_day-1.0.2.dist-info/RECORD +179 -0
  175. {zebra_day-0.0.37.dist-info → zebra_day-1.0.2.dist-info}/WHEEL +1 -1
  176. zebra_day-1.0.2.dist-info/entry_points.txt +4 -0
  177. zebra_day/bin/te.py +0 -905
  178. zebra_day-0.0.37.dist-info/METADATA +0 -1177
  179. zebra_day-0.0.37.dist-info/RECORD +0 -10
  180. {zebra_day-0.0.37.dist-info → zebra_day-1.0.2.dist-info/licenses}/LICENSE +0 -0
  181. {zebra_day-0.0.37.dist-info → zebra_day-1.0.2.dist-info}/top_level.txt +0 -0
zebra_day/bin/zserve.py CHANGED
@@ -9,69 +9,100 @@ import json
9
9
  import tempfile
10
10
 
11
11
  import zebra_day.print_mgr as zdpm
12
+ import zebra_day.cmd_mgr as zdcm
12
13
 
13
- FILES_DIR = "zebra_day/etc/label_styles"
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
14
17
 
15
- ENVCHECK = os.environ.get('ZDAY','skip') # Start zserve.py like: export ZDAY=somestring && python zebra_day/bin/zserve.py and the index (for now) will not load unless you send along the same string with the HTTP request using the envcheck variable. If not detected, set to skip and this is not checked. NOTE! This is hugely crude and something much better needs to be done before anything here is exposed routinely in the wild. A quick improvement coming soon, session level auth and so on.
16
18
 
17
19
  class Zserve(object):
20
+ def st(self):
21
+ self.css_file = "static/style.css"
18
22
 
19
- def __init__(self):
23
+ def __init__(self, relpath, abpath):
24
+ self.rel_p = relpath
25
+ self.abs_p = abpath
20
26
  self.zp = zdpm.zpl()
21
- self.css_file = "zebra_day/static/style.css"
27
+ self.css_file = "static/oakland.css"
22
28
  try:
23
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"
24
30
  print(ipcmd)
25
31
  self.ip = os.popen(ipcmd).readline().rstrip()
26
- self.ip_root = ".".join(self.ip.split('.')[:-1])
32
+ self.ip_root = ".".join(self.ip.split(".")[:-1])
27
33
  except Exception as e:
28
- self.ip = '192.168.1.0' # FAILS
29
- self.ip_root = '192.168.1' # FAILS
30
-
34
+ self.ip = "192.168.1.0" # FAILS
35
+ self.ip_root = "192.168.1" # FAILS
31
36
 
32
37
  @cherrypy.expose
33
- def chg_ui_style(self,css_file=None):
34
-
38
+ def chg_ui_style(self, css_file=None):
35
39
  if css_file not in [None]:
36
- self.css_file = "zebra_day/static/"+css_file
37
- raise cherrypy.HTTPRedirect("/")
38
-
40
+ self.css_file = "static/" + css_file
41
+ raise cherrypy.HTTPRedirect("/")
42
+
39
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>"
40
- for i in sorted(os.listdir('zebra_day/static')):
41
- if i.endswith('.css'):
44
+ for i in sorted(os.listdir(self.rel_p + "/static")):
45
+ if i.endswith(".css"):
42
46
  ret_html += f"<li><a href=chg_ui_style?css_file={i} >{i}</a>"
43
47
  ret_html += "</ul></ul></ul>"
44
48
 
45
49
  return self.wrap_content(ret_html)
46
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>"""
47
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
+
48
71
  @cherrypy.expose
49
- def probe_network_for_zebra_printers(self, ip_stub="192.168.1", scan_wait="0.25"):
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])
50
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>"
51
76
  try:
52
77
  self.detected_printer_ips = {}
53
78
  except Exception as e:
54
79
  self.detected_printer_ips = {}
55
80
 
56
- res = os.popen(f"zebra_day/bin/scan_for_networed_zebra_printers_curl.sh {ip_stub} {scan_wait}")
81
+ res = os.popen(
82
+ self.rel_p
83
+ + f"/bin/scan_for_networed_zebra_printers_curl.sh {ip_stub} {scan_wait}"
84
+ )
57
85
  for i in res.readlines():
58
86
  ii = i.rstrip()
59
- sl = ii.split('|')
87
+ sl = ii.split("|")
60
88
  if len(sl) > 1:
61
89
  zp = sl[0]
62
90
  ip = sl[1]
63
91
  model = sl[2]
64
92
  serial = sl[3]
65
93
  status = sl[4]
66
- self.detected_printer_ips[ip] = [model, serial, status]
67
- ret_html = ret_html + f"""
68
- <li>{zp} ::: <a href={ip} target=new>{ip}</a> ::: {model} ::: {serial} ::: {status}"""
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
+ )
69
101
 
70
102
  self._restart()
71
103
 
72
104
  return self.wrap_content(ret_html)
73
105
 
74
-
75
106
  @cherrypy.expose
76
107
  def list_prior_printer_config_files(self):
77
108
  ret_html = """
@@ -79,40 +110,32 @@ class Zserve(object):
79
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>
80
111
  <ul>"""
81
112
 
82
- bkup_d = "zebra_day/etc/old_printer_config/"
113
+ bkup_d = self.rel_p + "/etc/old_printer_config/"
83
114
 
84
115
  for i in sorted(os.listdir(bkup_d)):
85
- bkup_fn = f"{bkup_d}{i}"
86
- ret_html = ret_html + f"<li><a href={bkup_fn} >{bkup_fn}</a>"
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>"
87
118
 
88
119
  return self.wrap_content(ret_html)
89
120
 
90
-
91
121
  @cherrypy.expose
92
- def clear_printers_json(self):
93
- self.zp.clear_printers_json()
94
- ret_html = "printers json file has been cleared.<br><a href=/>home</a>"
95
- self._restart()
96
- return self.wrap_content(ret_html)
97
-
98
-
99
- @cherrypy.expose
100
- def probe_zebra_printers_add_to_printers_json(self, ip_stub="192.168.1", scan_wait="0.25",lab="scan-results"):
101
-
102
- self.zp.probe_zebra_printers_add_to_printers_json(ip_stub=ip_stub, scan_wait=scan_wait ,lab=lab)
103
-
104
- ret_html = "<a href=/>home</a><br><br><br>New Json Object:" + str(self.zp.printers)
105
- return self.wrap_content(ret_html)
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
+ )
106
128
 
129
+ os.system("sleep 2.2")
130
+ raise cherrypy.HTTPRedirect(f"printer_status?lab={lab}")
107
131
 
108
132
  @cherrypy.expose
109
- def printer_status(self,lab="scan-results"):
110
-
111
- if lab not in self.zp.printers['labs']:
133
+ def printer_status(self, lab="scan-results"):
134
+ if lab not in self.zp.printers["labs"]:
112
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."
113
136
 
114
137
  printer_deets = {}
115
- ret_html = f"<h1>Printer Status Summary For {lab}</h1><small><a href=/>BACK HOME</a></small><br><ul><hr>Scan Network For Zebra Printers : <form action=probe_network_for_zebra_printers id='myForm' > Network Stub To Scan : <input type=text name=ip_stub value='{self.ip_root}' class='navigational-link' > Scan Wait(s)<input type=text name=scan_wait value='0.25'><input type=submit></form><br><ul><table border=1 ><tr><th>Printer Name</th><th>Printer IP</th><th>Label Style</th><th>Status on Network</th></tr>"
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>"""
116
139
 
117
140
  pips = {}
118
141
  try:
@@ -120,79 +143,135 @@ class Zserve(object):
120
143
  except Exception as e:
121
144
  self.detected_printer_ips = {}
122
145
 
123
-
124
- for pname in self.zp.printers['labs'][lab]:
125
- pip = self.zp.printers['labs'][lab][pname]['ip_address']
146
+ for pname in self.zp.printers["labs"][lab]:
147
+ pip = self.zp.printers["labs"][lab][pname]["ip_address"]
126
148
  if pip in self.detected_printer_ips:
127
- del(pips[pip])
128
-
129
- printer_deets[pname] = [pip, "<small><a href=edit_zpl >available zpl templates here</a></small>"] # "...".join(self.zp.printers['labs'][lab][pname]['label_zpl_styles'])]
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'])]
130
166
  print(pname, pip)
167
+ print(f"curl -m {pip}")
131
168
  cres = os.popen(f"curl -m 4 {pip}").readlines()
132
169
  for ci in cres:
133
- if len(ci.split('Status:')) > 1:
170
+ if len(ci.split("Status:")) > 1:
134
171
  printer_deets[pname].append(ci)
135
172
 
136
- ptype = ''
173
+ ptype = ""
137
174
  for pret in printer_deets:
138
175
  try:
139
176
  pip2 = printer_deets[pret][0]
140
177
 
141
- pip2a = f"{self.zp.printers['labs'][lab][pret]['model']} / {self.zp.printers['labs'][lab][pret]['serial']}" # "" if pip2 not in self.detected_printer_ips else " / ".join(self.detected_printer_ips[pip2])
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])
142
179
  ptype = printer_deets[pret][1]
143
180
  pconnect = printer_deets[pret][2]
144
- serial = self.zp.printers['labs'][lab][pret]['serial'].replace(' ','_')
145
- model = self.zp.printers['labs'][lab][pret]['model']
146
- ret_html = ret_html + f'<tr><td>{pret}<br><small>{pip2a}</small></td><td><a href=http://{pip2} target=pcheck>{pip2}</a><br><br><small><a target=pl href="_print_label?lab={lab}&printer={pret}&printer_ip={pip2}&label_zpl_style=labware_2inX1in&uid_barcode={pip2}&alt_a={model}&alt_b={serial}&alt_c={pret}&alt_d={lab}" >print-test-label</a></small></td><td>{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></td></tr>'
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
+ )
147
188
  except Exception as e:
148
189
  print(e)
149
- ret_html = ret_html + f"<tr><td>{pret}</td><td><a href=http://{pip2} target=pcheck>{pip2}</a></td><td>{ptype}<br></td><td>UNABLE TO CONNECT</td></tr>"
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
+ )
150
194
 
151
195
  zaddl = ""
152
196
  for zi in pips:
153
197
  zaddl = zaddl + f"<li>{zi} :: {pips[zi]}"
154
198
 
155
- ret_html = ret_html + "</table></ul><h3>Detected, But Not Configured, Zebra Printers</h3><small>you must scan the network before this will present info</small><ul>" + zaddl + "</ul></ul>"
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
+ )
156
209
 
157
210
  return self.wrap_content(ret_html)
158
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
159
218
 
160
219
  @cherrypy.expose
161
- def index(self,envcheck='skip'):
220
+ def index(self, envcheck="skip"):
162
221
  if envcheck != ENVCHECK:
163
- #client_ip = cherrypy.request.remote.ip
164
- os.system('sleep 31')
165
- return ''
166
-
222
+ # client_ip = cherrypy.request.remote.ip
223
+ os.system("sleep 31")
224
+ return ""
225
+
167
226
  llinks = ""
168
227
  try:
169
- for lb in self.zp.printers['labs'].keys():
170
- llinks = llinks + f"<li><a href=printer_status?lab={lb} > {lb} Zebra Printer Status </a>"
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
+ )
171
233
  except Exception as e:
172
- llinks = llinks + "<li> no labs found. try scanning and resetting printers.json"
234
+ llinks = (
235
+ llinks + "<li> no labs found. try scanning and resetting printers.json"
236
+ )
173
237
 
174
238
  llinks = llinks + "<li> __end__ </ul>"
175
239
 
176
- ret_html = """
177
- <h1>Daylily Zebra Printer And Print Request Manager</h1><ul><small>ip address detected :: """+self.ip+"""</small>
240
+ ret_html = (
241
+ """
242
+ <h1>Daylily Zebra Printer And Print Request Manager</h1><ul><small>ip address detected :: """
243
+ + self.ip
244
+ + """</small>
178
245
  <hr><ul>
179
246
  <hr>
180
247
  <h2>Zebra Printer Fleet Status, By Site</h2>
181
248
  <ul>detected sites:
182
- <ul><ul>"""+llinks+"""</ul><br></ul>
249
+ <ul><ul>"""
250
+ + llinks
251
+ + """</ul><br></ul>
183
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
+
184
260
  <h2>Zebra Printer JSON Config</h2>
185
261
  <ul>this json file defines the zebra printers available to the package
186
262
  <ul><ul>
187
263
  <li><a href=view_pstation_json >view and edit json</a>
188
264
  <br>
189
- <br><li><small>scan network for new zebra printers, and add to printers.json config used by this package <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 > <input type=submit></form> </small><li><a href=list_prior_printer_config_files>view backed up printers json config files</a> </ul><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>
190
268
  </ul></ul>
191
269
  <hr>
192
270
  <h2>Send Print Requests</h2>
193
271
  <ul>to accessible zebra printers
194
- <ul><ul>
195
- <li><a href=send_print_request>manually compose & send print request</a>
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>
196
275
  </ul><br>
197
276
  </ul></ul>
198
277
  <hr><h2>Edit Label Templates</h2>
@@ -209,34 +288,177 @@ class Zserve(object):
209
288
  </small>
210
289
  </ul></ul>
211
290
  </ul></ul></ul>
212
- <small> <a href=chg_ui_style style='position: fixed; bottom: 0; right: 0;padding: 10px; text-decoration:none;' id="bottomRightLink">change ui style</a></small>
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>
213
303
  """
304
+ return self.wrap_content(ret_html)
214
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
+ """
215
314
  return self.wrap_content(ret_html)
216
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>")
217
320
 
218
321
  @cherrypy.expose
219
322
  def send_print_request(self):
220
323
  ret_html = ""
221
324
 
222
- for lab in sorted(self.zp.printers['labs']):
223
- ret_html = ret_html + f"<h1>Lab {lab}</h1><small><a href=/>home</a><br><ul><hr><ul>"
224
- for printer in sorted(self.zp.printers['labs'][lab]):
225
- pip = self.zp.printers['labs'][lab][printer]['ip_address']
226
- plab = self.zp.printers['labs'][lab][printer]['label_zpl_styles']
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"]
227
333
  ret_html = ret_html + f"<li>{printer} .. {pip}<ul>"
228
334
  for plabi in sorted(plab):
229
- ret_html = ret_html + f"<li>{plabi} ----- <a href=build_print_request?lab='{lab}'&printer='{printer}'&printer_ip='{pip}'&label_zpl_style='{plabi}'>PRINT THIS TYPE</a>"
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
+ )
230
339
  ret_html = ret_html + "</ul><br>"
231
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
+
232
348
  return self.wrap_content(ret_html)
233
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
+ )
234
371
 
235
372
  @cherrypy.expose
236
- def build_print_request(self, lab, printer, printer_ip='', label_zpl_style='',content='', filename='',ftag=''):
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
+ """
237
446
 
238
- if label_zpl_style in ['','None', None] and filename not in ['','None',None]:
239
- label_zpl_style = filename.split('.zpl')[0]
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]
240
462
 
241
463
  ret_html = f"""
242
464
  <h1>Send Label Print Request</h1>
@@ -244,7 +466,9 @@ class Zserve(object):
244
466
  <h3>{lab} .. {printer} .. {printer_ip} .. {label_zpl_style}</h3><ul><hr><ul>
245
467
  """
246
468
 
247
- ret_html = ret_html + """
469
+ ret_html = (
470
+ ret_html
471
+ + """
248
472
  <form action=_print_label>
249
473
  <li>UID for Barcode : <input type=text name=uid_barcode ></input><br>
250
474
  <li>ALT-A : <input type=text name=alt_a ></input><br>
@@ -254,7 +478,10 @@ class Zserve(object):
254
478
  <li>ALT-E : <input type=text name=alt_e ></input><br>
255
479
  <li>ALT-F : <input type=text name=alt_f ></input><br>
256
480
  """
257
- ret_html = ret_html + f"""
481
+ )
482
+ ret_html = (
483
+ ret_html
484
+ + f"""
258
485
  Override Lab: <input type=text name=lab value={lab} ><br>
259
486
  Override Printer: <input type=text name=printer value={printer} ><br>
260
487
  Override IP: <input type=text name=printer_ip value={printer_ip} ><br>
@@ -262,54 +489,84 @@ class Zserve(object):
262
489
  <input type=submit>
263
490
  </form>
264
491
  """
492
+ )
265
493
 
266
494
  return self.wrap_content(ret_html)
267
495
 
268
-
269
496
  @cherrypy.expose
270
- def _print_label(self, lab, printer, printer_ip='', label_zpl_style='', uid_barcode='', alt_a='', alt_b='', alt_c='', alt_d='', alt_e='', alt_f=''):
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
+
271
515
  client_ip = cherrypy.request.remote.ip
272
516
 
273
- ret_s = self.zp.print_zpl(lab=lab ,printer_name=printer, 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, client_ip=client_ip)
274
-
275
- full_url = cherrypy.url() + 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}"
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
+ )
276
535
 
277
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>"
278
- if len(ret_s.split('.png')) > 1:
279
- addl_html = f"<a href=/>home</a><br><br>SUCCESFULLY CREATED PNG<br><img src={ret_s}><br>"
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>"
280
539
  ret_html = addl_html + "<a href=/>home</a>"
281
- return self.wrap_content(ret_html)
282
540
 
541
+ return self.wrap_content(ret_html)
283
542
 
284
543
  @cherrypy.expose
285
544
  def _restart(self):
286
- os.system(f"touch zebra_day/bin/zserve.py")
287
- os.system('sleep 4')
288
- ret_html = 'server restarted'
545
+ os.system(f"touch {self.rel_p}/bin/zserve.py")
546
+ os.system("sleep 4")
547
+ ret_html = "server restarted"
289
548
  return self.wrap_content(ret_html)
290
549
 
291
-
292
550
  @cherrypy.expose
293
551
  def dl_bin_file(self, fn=None):
294
-
295
552
  # Set the content type and disposition headers for the file
296
- cherrypy.response.headers['Content-Type'] = 'image/png'
297
- cherrypy.response.headers['Content-Disposition'] = f'attachment; filename="{fn}"'
553
+ cherrypy.response.headers["Content-Type"] = "image/png"
554
+ cherrypy.response.headers[
555
+ "Content-Disposition"
556
+ ] = f'attachment; filename="{fn}"'
298
557
 
299
558
  # Open and serve the PNG file as a static file
300
559
  try:
301
- with open(fn, 'rb') as f:
560
+ with open(fn, "rb") as f:
302
561
  return f.read()
303
562
  except FileNotFoundError:
304
- return "File not found."
305
-
563
+ return self.wrap_content("File not found.")
306
564
 
307
565
  @cherrypy.expose
308
566
  def view_pstation_json(self, error_msg=None):
309
-
310
- with open(self.zp.printers_filename, 'r') as f:
567
+ with open(self.zp.printers_filename, "r") as f:
311
568
  data = json.load(f)
312
- error_display = f'<p style="color:red;">{error_msg}</p>' if error_msg else ''
569
+ error_display = f'<p style="color:red;">{error_msg}</p>' if error_msg else ""
313
570
  ret_html = f"""
314
571
  <br><a href=/>home</a><br>
315
572
  {error_display}
@@ -330,106 +587,109 @@ class Zserve(object):
330
587
 
331
588
  return self.wrap_content(ret_html)
332
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)
333
597
 
334
598
  @cherrypy.expose
335
599
  def reset_pstation_json(self):
336
600
  self.zp.replace_printer_json_from_template()
337
- ret_html = "Done. <a href=/>home</a>."
338
- ret_html = ret_html + "<br>server is restarted? " + self._restart()
339
- return self.wrap_content(ret_html)
340
-
601
+ self._restart()
602
+ os.system("sleep 1.2")
603
+ referrer = cherrypy.request.headers.get("Referer", "/")
604
+ raise cherrypy.HTTPRedirect(referrer)
341
605
 
342
606
  @cherrypy.expose
343
607
  def save_pstation_json(self, json_data):
344
- rec_date = str(datetime.now()).replace(' ','_')
345
- bkup_pconfig_fn = f"zebra_day/etc/old_printer_config/{rec_date}_printer_config.json"
346
-
347
- os.system(f"cp {self.zp.printers_filename} {bkup_pconfig_fn}")
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
+ )
348
612
 
349
613
  try:
350
- data = json.loads(json_data)
351
- with open(self.zp.printers_filename, 'w') as f:
352
- json.dump(data, f, indent=4)
353
- self.zp.load_printer_json(json_file=self.zp.printers_filename)
354
- self._restart()
355
- return "JSON saved successfully!<br><br>Print Stations Updated.<br><br><a href=/>home</a><br><br><a href=view_pstation_json>open current print station json</a>"
356
- except json.JSONDecodeError as e:
357
- return self.view_pstation_json(error_msg=str(e))
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
+ )
358
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?.")
359
643
 
360
644
  @cherrypy.expose
361
645
  def edit_zpl(self):
362
- files = [f for f in os.listdir(FILES_DIR) if os.path.isfile(os.path.join(FILES_DIR, f))]
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
+ ]
363
651
 
364
- file_links = ['<a href="/edit?filename={}">{}</a>'.format(f, f) for f in files]
652
+ file_links = ['<a href="/edit?filename={}">{}</a>'.format(f, f) for f in sorted(files)]
365
653
 
366
- filest = [ft for ft in os.listdir(FILES_DIR+'/tmps/') if os.path.isfile(os.path.join(FILES_DIR+'/tmps/', ft))]
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
+ ]
367
662
 
368
- file_linkst = ['<a href="/edit?dtype=tmps&filename={}">{}</a>'.format(ft, ft) for ft in filest]
663
+ file_linkst = [
664
+ '<a href="/edit?dtype=tmps&filename={}">{}</a>'.format(ft, ft)
665
+ for ft in sorted(filest)
666
+ ]
369
667
 
370
668
  ret_html = """
371
669
  <a href=/>home</a><br><ul>
372
- 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'. ie: test_2inX1in' <br><ul><hr><br>stable ZPL templates<br>
373
- <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
+
374
672
  {}
375
673
  </ul>
376
674
 
377
675
  <br><br><hr><br>draft ZPL templates<ul> {} </ul>
378
- """.format("<li>" + "</li><li>".join(file_links) + "</li>", "<li>" + "</li><li>".join(file_linkst) + "</li>")
676
+ """.format(
677
+ "<li>" + "</li><li>".join(file_links) + "</li>",
678
+ "<li>" + "</li><li>".join(file_linkst) + "</li>",
679
+ )
379
680
 
380
681
  return self.wrap_content(ret_html)
381
682
 
382
-
383
683
  @cherrypy.expose
384
- def qqqxxx(self):
385
- self.labs_dict = self.zp.printers
386
- labs = self.labs_dict["labs"].keys()
387
-
388
- html = """<html>
389
- <head>
390
- <script>
391
- function populatePrinters() {
392
- var lab = document.getElementById("labsDropdown").value;
393
- var printersDropdown = document.getElementById("printersDropdown");
394
- printersDropdown.innerHTML = "";
395
- var labs = """ + str(self.labs_dict["labs"]) + """;
396
- for (var printer in labs[lab]) {
397
- var option = document.createElement("option");
398
- option.text = printer;
399
- option.value = printer;
400
- printersDropdown.add(option);
401
- }
402
- }
403
- </script>
404
- </head>
405
- <body>
406
- <form>
407
- <select id="labsDropdown" onchange="populatePrinters()">
408
- <option value="">Select Lab</option>"""
409
-
410
- for lab in labs:
411
- html += f'<option value="{lab}">{lab}</option>'
412
-
413
- html += """
414
- </select>
415
- <select id="printersDropdown">
416
- <option value="">Select Printer</option>
417
- </select>
418
- </form>
419
- </body>
420
- </html>"""
421
-
422
- return html
423
-
424
-
425
- @cherrypy.expose
426
- def edit(self, filename=None, dtype=''):
684
+ def edit(self, filename=None, dtype=""):
427
685
  if not filename:
428
- return "No file selected"
686
+ return self.wrap_content("No file selected")
429
687
 
430
- filepath = os.path.join(FILES_DIR + '/' + dtype + '/', filename)
688
+ filepath = os.path.join(
689
+ self.rel_p + "/etc/label_styles/" + dtype + "/", filename
690
+ )
431
691
 
432
- with open(filepath, 'r') as file:
692
+ with open(filepath, "r") as file:
433
693
  content = file.read()
434
694
 
435
695
  self.labs_dict = self.zp.printers
@@ -439,16 +699,16 @@ class Zserve(object):
439
699
  for lab in labs:
440
700
  ll += f'<option value="{lab}">{lab}</option>'
441
701
 
442
-
443
- return """<html>
444
- <head>
445
- <link rel="stylesheet" href="""+self.css_file+""">
702
+ ret_html = (
703
+ """
446
704
  <script>
447
705
  function populatePrinters() {
448
706
  var lab = document.getElementById("labsDropdown").value;
449
707
  var printersDropdown = document.getElementById("printersDropdown");
450
708
  printersDropdown.innerHTML = "";
451
- var labs = """ + str(self.labs_dict["labs"]) + """;
709
+ var labs = """
710
+ + str(self.labs_dict["labs"])
711
+ + """;
452
712
  for (var printer in labs[lab]) {
453
713
  var option = document.createElement("option");
454
714
  option.text = printer;
@@ -459,68 +719,155 @@ class Zserve(object):
459
719
  </script>
460
720
  </head>
461
721
  <body>
462
- <h2>Editing: """+filename+"""</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>
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>
463
725
  <table border=1><tr><td style="vertical-align: top;" >
464
726
  <form method="post" action="/save" id="textForm">
465
- <textarea name="content" rows="30" cols="40">{cont}</textarea><br/>
727
+ <textarea name="content" rows="26" cols="40">{cont}</textarea><br/>
466
728
  <input type="hidden" name="filename" value="{fn}">
467
- TMP File Tag (added to new file name): <input type=text name=ftag value=na >
468
- <input type="submit" value="Save Temp File">
469
- <hr>
470
- <input type="button" value="Render PNG Of ZPL Label" onclick="submitToPNGrenderer();">
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();">
471
731
  <hr>
472
- <b>choose a 'Lab' and 'Printer' to test print to</b><select id="labsDropdown" name=lab onchange="populatePrinters()">
732
+ <hr>
733
+ <br><h3>PRINT IRL:</h3>
734
+ <select id="labsDropdown" name=lab onchange="populatePrinters()">
473
735
  <option value="">Select Lab</option>{ll}
474
736
  </select>
475
737
  <select id="printersDropdown" name=printer>
476
738
  <option value="">Select Printer</option>
477
739
  </select>
478
- <input type="button" value="Test Print To Local Zebra" onclick="submitToRealPrint();">
479
- </form><br>
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>
480
744
  </td><td>
481
745
  <div style="border: 1;" id="pngContainer"></div>
482
- <ul><h3>How To Use This Tool</h3>
483
- <small><a href=https://labelary.com/viewer.html target=labels>For More On ZPL (docs and tools)</a></small><ul>
484
- <ul><li>Load existing ZPL format files, make edits and preview the effects by producing a PNG.
485
- <li>When you wish to save a ZPL format you have worked on here, click 'Save As Temp'. This will use the original ZPL file name to create a timestamped new file with your changes saved to it, the new file name will contain the TAG you specify. <b>THE ORIGINAL FILE IS NOT CHANGED OR DELETED</b>.
486
- <li><a href=edit_zpl >Your New File Appears Here</a>
487
- <li>To print using this ZPL template to a printer available on your network, <a href=send_print_request >navigate to available printers</a>. When you arrive at the <b>build_print_request</b> form for a specific printer, you are able to enter in any of the format replacement values specified in the ZPL you created. <b>important</b>, new ZPL files are not default available to use for printing. However, you can override the label_style_zpl value to select a different ZPL file. Valid strings for label_style_zpl are the label style zpl file name, minus the .zpl extension, and no path. So, for 'plate_1inX0.25in.zpl' you would enter 'plate_1inX0.25in' to use this zpl format. For any non-default ZPL template files which have been created, the same process applies. Given a draft ZPL file created on this page, ie: 'tube_2inX1in.2023-10-22_05:25:05.004018.zpl', you may use this template by trimming off the .zpl and entering 'tube_2inX1in.2023-10-22_05:25:05.004018'.
488
- </ul>
489
- <li>A good way to proceed when designing a new label. Use the labely tool to generate your ZPL. Create a zpl template file here with the format wildcards added. Test using this ZPL, with format substitutions, on the printers you will be using you new template on.
490
-
491
- <li> <b>When A ZPL File Is Ready For Wider Use...</b> For now, the file needs to be manually moved to a permanent ZPL file name. A tool to do this will be available everntually.
492
- </ul>
493
-
494
- <h3>ZPL Template Wildcards</h3>
495
- This tool is a very simple interface to tinker with the overall features of a ZPL label. You may add format wildcards to the ZPL you edit here, but this interface does not execute format replacement of the ZPL previews generated.
496
- <ul><hr>
497
- The templates used by this system provide for a set of format wildcards which can be embedded in the ZPL specification file, and values inserted with each new print request. Not all ZPL formats support all format replacements. The preview pdf generation on this page will not template any values in. To use a zpl template, and specify format replacement values, <a href=send_print_request >use this interface</a>. <br>The wildcards supported:
498
- <ul>
499
- <li>{{uid_barcode}} = This will be encoded as the scannable barcode and presented in human readable form (at least for all default label templates)
500
- <li>{{alt_a}} = the 'alt_*' wildcards are placehoders for additional information that may be presented beyond the . These alt_* fields may be used howeever you like with your ZPL templates.
501
- <li>{{alt_b}} = <a href=send_print_request >use this interface to test sending wildcards to ZPL templates.</a>
502
- <li>... through {{alt_f}}
503
- </ul></ul>
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
+
504
838
  </td></tr></table>
505
839
 
506
840
  <script>
507
841
  function submitToLocPrint() {{
508
- var form = document.getElementById('textForm'); var formData = new FormData(form);
509
-
510
- fetch('/build_print_request', {{
511
- method: 'POST',
512
- body: formData
513
- }})}}
514
- </script>
515
- <script>
516
- function submitToRealPrint() {{
517
- var form = document.getElementById('textForm');
518
- form.action = '/build_print_request';
519
- form.submit();
520
- }}
521
- </script>
522
- </script>
523
- <script>
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>
524
871
  function submitToPNGrenderer() {{
525
872
  var form = document.getElementById('textForm');
526
873
  var formData = new FormData(form);
@@ -545,49 +892,129 @@ class Zserve(object):
545
892
  }}
546
893
 
547
894
  </script>
548
- </body>
549
- </html>
550
- """.format(cont=content, fn=filename,ll=ll)
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)
551
903
 
552
904
  @cherrypy.expose
553
- def png_renderer(self,filename,content,lab='',printer='', ftag=''):
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>"
554
914
 
555
- png_tmp_f = tempfile.NamedTemporaryFile(suffix='.png', dir='zebra_day/files', delete=False).name
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>"
556
919
 
557
- self.zp.generate_label_png(content,png_fn=png_tmp_f)
920
+ template_sel += f"<option value=draft>--draft templates--</option>"
558
921
 
559
- return "zebra_day/files/" + png_tmp_f.split('/')[-1]
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>"
560
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)
561
980
 
981
+ return "files/" + png_tmp_f.split("/")[-1]
562
982
 
563
983
  @cherrypy.expose
564
- def save(self, filename, content, lab='',printer='', ftag=''):
565
- rec_date = str(datetime.now()).replace(' ','_')
984
+ def save(self, filename, content, lab="", printer="", ftag=""):
985
+ rec_date = str(datetime.now()).replace(" ", "_")
566
986
 
567
- tfn = filename.replace('.zpl',f'.{ftag}.{rec_date}.zpl')
987
+ tfn = filename.replace(".zpl", f".{ftag}.{rec_date}.zpl")
568
988
 
569
- temp_filepath = os.path.join(FILES_DIR, 'tmps/', tfn)
989
+ temp_filepath = os.path.join(self.rel_p + "/etc/label_styles/tmps/", tfn)
570
990
 
571
- with open(temp_filepath, 'w') as file:
991
+ with open(temp_filepath, "w") as file:
572
992
  file.write(content)
573
993
 
574
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>)"
575
995
 
576
996
  return self.wrap_content(ret_html)
577
997
 
578
-
579
- def wrap_content(self, content):
998
+ def wrap_content(self, content, close_head_section=True, add_spinner=True):
580
999
  header = f"""
581
1000
  <html>
582
1001
  <head>
1002
+ <link rel="stylesheet" href="static/general.css">
583
1003
  <link rel="stylesheet" href="{self.css_file}">
584
- </head>
585
- <body>
586
- <div id="spinner" class="spinner-hidden">
587
- <div class="loader"></div>
588
- </div>
589
1004
  """
590
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
+
591
1018
  footer = """
592
1019
  <script>
593
1020
  document.getElementById('myForm').addEventListener('submit', function(event) {
@@ -605,16 +1032,31 @@ class Zserve(object):
605
1032
  return header + content + footer
606
1033
 
607
1034
 
608
- if __name__ == '__main__':
609
- cw_dir = os.path.abspath('.')
610
- cherrypy.config.update( {
611
- 'tools.staticdir.on': True,
612
- 'tools.staticdir.dir': cw_dir,
613
- 'server.socket_host': '0.0.0.0',
614
- 'server.socket_port': 8118,
615
- 'server.thread_pool' : 20,
616
- 'server.socket_queue_size': 20,
617
- 'tools.sessions.on': True,
618
- 'tools.sessions.timeout': 199, # Session timeout in minutes
619
- })
620
- cherrypy.quickstart(Zserve(),'/')
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}"), "/")