zebra-day 1.0.2__py3-none-any.whl → 2.1.4__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 (174) hide show
  1. zebra_day/__init__.py +7 -2
  2. zebra_day/_version.py +1 -0
  3. zebra_day/cli/__init__.py +80 -30
  4. zebra_day/cli/cognito.py +15 -9
  5. zebra_day/cli/gui.py +101 -13
  6. zebra_day/cli/printer.py +34 -27
  7. zebra_day/cli/template.py +19 -15
  8. zebra_day/cmd_mgr.py +3 -6
  9. zebra_day/docs/gx420d-gx430d-ug-en.pdf +0 -0
  10. zebra_day/docs/hardware_config_guide.md +149 -0
  11. zebra_day/docs/programatic_guide.md +181 -0
  12. zebra_day/docs/qln420_zebra_manual.pdf +0 -0
  13. zebra_day/docs/uid_screed_light.md +38 -0
  14. zebra_day/docs/zd620-zd420-ug-en.pdf +0 -0
  15. zebra_day/docs/zebra_day_ui_guide.md +194 -0
  16. zebra_day/etc/printer_config.json +5 -11
  17. zebra_day/etc/printer_config.template.json +5 -11
  18. zebra_day/etc/tmp_printers120.json +10 -0
  19. zebra_day/etc/tmp_printers139.json +10 -0
  20. zebra_day/etc/tmp_printers145.json +10 -0
  21. zebra_day/etc/tmp_printers147.json +10 -0
  22. zebra_day/etc/tmp_printers207.json +10 -0
  23. zebra_day/etc/tmp_printers34.json +10 -0
  24. zebra_day/etc/tmp_printers389.json +10 -0
  25. zebra_day/etc/tmp_printers398.json +10 -0
  26. zebra_day/etc/tmp_printers437.json +10 -0
  27. zebra_day/etc/tmp_printers439.json +10 -0
  28. zebra_day/etc/tmp_printers440.json +10 -0
  29. zebra_day/etc/tmp_printers469.json +10 -0
  30. zebra_day/etc/tmp_printers485.json +10 -0
  31. zebra_day/etc/tmp_printers508.json +10 -0
  32. zebra_day/etc/tmp_printers531.json +10 -0
  33. zebra_day/etc/tmp_printers540.json +10 -0
  34. zebra_day/etc/tmp_printers542.json +10 -0
  35. zebra_day/etc/tmp_printers543.json +10 -0
  36. zebra_day/etc/tmp_printers552.json +10 -0
  37. zebra_day/etc/tmp_printers715.json +10 -0
  38. zebra_day/etc/tmp_printers835.json +10 -0
  39. zebra_day/etc/tmp_printers842.json +10 -0
  40. zebra_day/etc/tmp_printers931.json +10 -0
  41. zebra_day/etc/tmp_printers969.json +10 -0
  42. zebra_day/etc/tmp_printers972.json +10 -0
  43. zebra_day/exceptions.py +1 -1
  44. zebra_day/files/blank_preview.png +0 -0
  45. zebra_day/files/corners_20cmX30cm_preview.png +0 -0
  46. zebra_day/files/corners_smallTube_preview.png +0 -0
  47. zebra_day/files/generic_2inX1in_preview.png +0 -0
  48. zebra_day/files/test_png_12020.png +0 -0
  49. zebra_day/files/test_png_12352.png +0 -0
  50. zebra_day/files/test_png_15472.png +0 -0
  51. zebra_day/files/test_png_24493.png +0 -0
  52. zebra_day/files/test_png_2897.png +0 -0
  53. zebra_day/files/test_png_30069.png +0 -0
  54. zebra_day/files/test_png_31690.png +0 -0
  55. zebra_day/files/test_png_33804.png +0 -0
  56. zebra_day/files/test_png_34737.png +0 -0
  57. zebra_day/files/test_png_4161.png +0 -0
  58. zebra_day/files/test_png_44748.png +0 -0
  59. zebra_day/files/test_png_4635.png +0 -0
  60. zebra_day/files/test_png_47791.png +0 -0
  61. zebra_day/files/test_png_47799.png +0 -0
  62. zebra_day/files/test_png_55588.png +0 -0
  63. zebra_day/files/test_png_56349.png +0 -0
  64. zebra_day/files/test_png_58809.png +0 -0
  65. zebra_day/files/test_png_5936.png +0 -0
  66. zebra_day/files/test_png_64110.png +0 -0
  67. zebra_day/files/test_png_64891.png +0 -0
  68. zebra_day/files/test_png_67242.png +0 -0
  69. zebra_day/files/test_png_69002.png +0 -0
  70. zebra_day/files/test_png_70065.png +0 -0
  71. zebra_day/files/test_png_72366.png +0 -0
  72. zebra_day/files/test_png_77793.png +0 -0
  73. zebra_day/files/test_png_89893.png +0 -0
  74. zebra_day/files/test_png_9572.png +0 -0
  75. zebra_day/files/tube_20mmX30mmA_preview.png +0 -0
  76. zebra_day/imgs/.hold +0 -0
  77. zebra_day/imgs/bar_ltpurp.png +0 -0
  78. zebra_day/imgs/bar_purp.png +0 -0
  79. zebra_day/imgs/bar_purp3.png +0 -0
  80. zebra_day/imgs/bar_red.png +0 -0
  81. zebra_day/imgs/legacy/UBC_gantt_chart.png +0 -0
  82. zebra_day/imgs/legacy/gx420d_network_config.png +0 -0
  83. zebra_day/imgs/legacy/gx420d_printer_config.png +0 -0
  84. zebra_day/imgs/legacy/ngrok.png +0 -0
  85. zebra_day/imgs/legacy/printer_details.png +0 -0
  86. zebra_day/imgs/legacy/quick_start_test_label.png +0 -0
  87. zebra_day/imgs/legacy/quick_start_test_label2.png +0 -0
  88. zebra_day/imgs/legacy/zd620_network_config.png +0 -0
  89. zebra_day/imgs/legacy/zd620_printer_config.png +0 -0
  90. zebra_day/imgs/legacy/zday_quick_gui.png +0 -0
  91. zebra_day/imgs/legacy/zebra_day_alt_css_dog.png +0 -0
  92. zebra_day/imgs/legacy/zebra_day_alt_css_flower.png +0 -0
  93. zebra_day/imgs/legacy/zebra_day_alt_css_main.png +0 -0
  94. zebra_day/imgs/legacy/zebra_day_available_zpl_templates.png +0 -0
  95. zebra_day/imgs/legacy/zebra_day_bkup_pconfig.png +0 -0
  96. zebra_day/imgs/legacy/zebra_day_home.png +0 -0
  97. zebra_day/imgs/legacy/zebra_day_manual_print.png +0 -0
  98. zebra_day/imgs/legacy/zebra_day_printer_fleet_json.png +0 -0
  99. zebra_day/imgs/legacy/zebra_day_quick_ex.png +0 -0
  100. zebra_day/imgs/legacy/zebra_day_zpl_template_IRLa.png +0 -0
  101. zebra_day/imgs/legacy/zebra_day_zpl_template_IRLb.png +0 -0
  102. zebra_day/imgs/ui_api_docs.png +0 -0
  103. zebra_day/imgs/ui_config.png +0 -0
  104. zebra_day/imgs/ui_dashboard.png +0 -0
  105. zebra_day/imgs/ui_print_request.png +0 -0
  106. zebra_day/imgs/ui_printers.png +0 -0
  107. zebra_day/imgs/ui_templates.png +0 -0
  108. zebra_day/logging_config.py +4 -9
  109. zebra_day/mkcert.py +157 -0
  110. zebra_day/paths.py +1 -2
  111. zebra_day/print_mgr.py +261 -185
  112. zebra_day/templates/modern/config.html +7 -0
  113. zebra_day/templates/modern/config_backups.html +59 -0
  114. zebra_day/templates/modern/config_editor.html +95 -0
  115. zebra_day/templates/modern/config_new.html +93 -0
  116. zebra_day/templates/modern/print_request.html +70 -8
  117. zebra_day/templates/modern/printer_detail.html +161 -34
  118. zebra_day/templates/modern/printers.html +17 -6
  119. zebra_day/templates/modern/template_editor.html +7 -4
  120. zebra_day/web/__init__.py +1 -1
  121. zebra_day/web/app.py +99 -17
  122. zebra_day/web/auth.py +17 -15
  123. zebra_day/web/middleware.py +8 -5
  124. zebra_day/web/routers/__init__.py +0 -1
  125. zebra_day/web/routers/api.py +330 -31
  126. zebra_day/web/routers/ui.py +174 -591
  127. zebra_day/zpl_renderer.py +45 -34
  128. {zebra_day-1.0.2.dist-info → zebra_day-2.1.4.dist-info}/METADATA +144 -74
  129. zebra_day-2.1.4.dist-info/RECORD +240 -0
  130. zebra_day/bin/fetch_zebra_config.py +0 -15
  131. zebra_day/bin/generate_coord_grid_zpl.py +0 -50
  132. zebra_day/bin/print_zpl_from_file.py +0 -21
  133. zebra_day/bin/probe_new_label_dimensions.py +0 -75
  134. zebra_day/bin/scan_for_networed_zebra_printers.py +0 -23
  135. zebra_day/bin/scan_for_networed_zebra_printers_arp_scan.sh +0 -1
  136. zebra_day/bin/scan_for_networed_zebra_printers_curl.sh +0 -30
  137. zebra_day/bin/zserve.py +0 -1062
  138. zebra_day/templates/base.html +0 -36
  139. zebra_day/templates/bpr.html +0 -72
  140. zebra_day/templates/build_new_config.html +0 -36
  141. zebra_day/templates/build_print_request.html +0 -32
  142. zebra_day/templates/chg_ui_style.html +0 -19
  143. zebra_day/templates/edit_template.html +0 -128
  144. zebra_day/templates/edit_zpl.html +0 -37
  145. zebra_day/templates/index.html +0 -82
  146. zebra_day/templates/legacy/base.html +0 -37
  147. zebra_day/templates/legacy/bpr.html +0 -72
  148. zebra_day/templates/legacy/build_new_config.html +0 -36
  149. zebra_day/templates/legacy/build_print_request.html +0 -32
  150. zebra_day/templates/legacy/chg_ui_style.html +0 -19
  151. zebra_day/templates/legacy/edit_template.html +0 -128
  152. zebra_day/templates/legacy/edit_zpl.html +0 -37
  153. zebra_day/templates/legacy/index.html +0 -82
  154. zebra_day/templates/legacy/list_prior_configs.html +0 -24
  155. zebra_day/templates/legacy/print_result.html +0 -30
  156. zebra_day/templates/legacy/printer_details.html +0 -25
  157. zebra_day/templates/legacy/printer_status.html +0 -70
  158. zebra_day/templates/legacy/save_result.html +0 -17
  159. zebra_day/templates/legacy/send_print_request.html +0 -34
  160. zebra_day/templates/legacy/simple_print.html +0 -94
  161. zebra_day/templates/legacy/view_pstation_json.html +0 -29
  162. zebra_day/templates/list_prior_configs.html +0 -24
  163. zebra_day/templates/print_result.html +0 -30
  164. zebra_day/templates/printer_details.html +0 -25
  165. zebra_day/templates/printer_status.html +0 -70
  166. zebra_day/templates/save_result.html +0 -17
  167. zebra_day/templates/send_print_request.html +0 -34
  168. zebra_day/templates/simple_print.html +0 -94
  169. zebra_day/templates/view_pstation_json.html +0 -29
  170. zebra_day-1.0.2.dist-info/RECORD +0 -179
  171. {zebra_day-1.0.2.dist-info → zebra_day-2.1.4.dist-info}/WHEEL +0 -0
  172. {zebra_day-1.0.2.dist-info → zebra_day-2.1.4.dist-info}/entry_points.txt +0 -0
  173. {zebra_day-1.0.2.dist-info → zebra_day-2.1.4.dist-info}/licenses/LICENSE +0 -0
  174. {zebra_day-1.0.2.dist-info → zebra_day-2.1.4.dist-info}/top_level.txt +0 -0
@@ -2,26 +2,22 @@
2
2
  UI router for zebra_day web interface.
3
3
 
4
4
  Provides HTML endpoints for the web-based management interface.
5
- Supports dual interfaces:
6
- - Modern UI: Root routes (/, /printers, /print, /templates, /config)
7
- - Legacy UI: Routes under /legacy prefix
5
+ All routes use the modern UI design with responsive layouts.
8
6
  """
7
+
9
8
  from __future__ import annotations
10
9
 
11
10
  import json
12
- import os
13
- import subprocess
14
11
  import tempfile
15
12
  import time
16
13
  from datetime import datetime
17
14
  from pathlib import Path
18
- from typing import Optional
19
15
 
20
- from fastapi import APIRouter, Request, Form, HTTPException
16
+ from fastapi import APIRouter, Form, HTTPException, Request
21
17
  from fastapi.responses import HTMLResponse, RedirectResponse, Response
22
18
 
23
- from zebra_day.logging_config import get_logger
24
19
  import zebra_day.cmd_mgr as zdcm
20
+ from zebra_day.logging_config import get_logger
25
21
 
26
22
  _log = get_logger(__name__)
27
23
 
@@ -29,7 +25,7 @@ router = APIRouter()
29
25
 
30
26
 
31
27
  def get_template_context(request: Request, **kwargs) -> dict:
32
- """Build common template context for legacy templates."""
28
+ """Build common template context for templates."""
33
29
  return {
34
30
  "request": request,
35
31
  "css_theme": f"static/{request.app.state.css_theme}",
@@ -73,7 +69,8 @@ def get_templates_list(pkg_path: Path) -> tuple[list, list]:
73
69
  def get_stats(zp, pkg_path: Path) -> dict:
74
70
  """Calculate dashboard statistics."""
75
71
  labs = zp.printers.get("labs", {})
76
- total_printers = sum(len(printers) for printers in labs.values())
72
+ # Count printers via nested 'printers' key (v2 schema)
73
+ total_printers = sum(len(lab_data.get("printers", {})) for lab_data in labs.values())
77
74
  stable, draft = get_templates_list(pkg_path)
78
75
 
79
76
  # Count backup files
@@ -93,6 +90,7 @@ def get_stats(zp, pkg_path: Path) -> dict:
93
90
  # MODERN UI ROUTES (root level)
94
91
  # =============================================================================
95
92
 
93
+
96
94
  @router.get("/", response_class=HTMLResponse)
97
95
  async def modern_dashboard(request: Request):
98
96
  """Modern dashboard - home page."""
@@ -141,16 +139,26 @@ async def modern_printers_by_lab(request: Request, lab: str):
141
139
  if lab not in zp.printers.get("labs", {}):
142
140
  raise HTTPException(status_code=404, detail=f"Lab '{lab}' not found")
143
141
 
142
+ lab_data = zp.printers["labs"][lab]
143
+ lab_printers = lab_data.get("printers", {})
144
+
144
145
  printers = []
145
- for name, info in zp.printers["labs"][lab].items():
146
- printers.append({
147
- "name": name,
148
- "ip_address": info.get("ip_address", ""),
149
- "model": info.get("model", ""),
150
- "serial": info.get("serial", ""),
151
- "label_zpl_styles": info.get("label_zpl_styles", []),
152
- "status": "online" if info.get("ip_address") else "unknown",
153
- })
146
+ for name, info in lab_printers.items():
147
+ printers.append(
148
+ {
149
+ "id": name,
150
+ "name": info.get("printer_name") or name, # Display name or fallback to ID
151
+ "printer_name": info.get("printer_name"),
152
+ "ip_address": info.get("ip_address", ""),
153
+ "lab_location": info.get("lab_location"),
154
+ "manufacturer": info.get("manufacturer", "zebra"),
155
+ "model": info.get("model", ""),
156
+ "serial": info.get("serial", ""),
157
+ "label_zpl_styles": info.get("label_zpl_styles", []),
158
+ "status": "online" if info.get("ip_address") else "unknown",
159
+ "notes": info.get("notes", ""),
160
+ }
161
+ )
154
162
 
155
163
  ip_root = ".".join(request.app.state.local_ip.split(".")[:-1])
156
164
 
@@ -160,23 +168,29 @@ async def modern_printers_by_lab(request: Request, lab: str):
160
168
  labs=list(zp.printers.get("labs", {}).keys()),
161
169
  printers=printers,
162
170
  lab=lab,
171
+ lab_name=lab_data.get("lab_name", lab),
172
+ available_locations=lab_data.get("available_locations", []),
163
173
  ip_root=ip_root,
164
174
  )
165
175
  return templates.TemplateResponse("modern/printers.html", context)
166
176
 
167
177
 
168
- @router.get("/printers/{lab}/{printer_name}", response_class=HTMLResponse)
169
- async def modern_printer_detail(request: Request, lab: str, printer_name: str):
178
+ @router.get("/printers/{lab}/{printer_id}", response_class=HTMLResponse)
179
+ async def modern_printer_detail(request: Request, lab: str, printer_id: str):
170
180
  """Modern printer detail page."""
171
181
  zp = request.app.state.zp
172
182
  templates = request.app.state.templates
173
183
 
174
184
  if lab not in zp.printers.get("labs", {}):
175
185
  raise HTTPException(status_code=404, detail=f"Lab '{lab}' not found")
176
- if printer_name not in zp.printers["labs"][lab]:
177
- raise HTTPException(status_code=404, detail=f"Printer '{printer_name}' not found")
178
186
 
179
- printer_info = zp.printers["labs"][lab][printer_name]
187
+ lab_data = zp.printers["labs"][lab]
188
+ lab_printers = lab_data.get("printers", {})
189
+
190
+ if printer_id not in lab_printers:
191
+ raise HTTPException(status_code=404, detail=f"Printer '{printer_id}' not found")
192
+
193
+ printer_info = lab_printers[printer_id]
180
194
 
181
195
  # Try to get printer configuration
182
196
  printer_config = ""
@@ -190,8 +204,11 @@ async def modern_printer_detail(request: Request, lab: str, printer_name: str):
190
204
  context = get_modern_context(
191
205
  request,
192
206
  active_page="printers",
193
- printer_name=printer_name,
207
+ printer_id=printer_id,
208
+ printer_name=printer_info.get("printer_name") or printer_id,
194
209
  lab=lab,
210
+ lab_name=lab_data.get("lab_name", lab),
211
+ available_locations=lab_data.get("available_locations", []),
195
212
  printer_info=printer_info,
196
213
  printer_config=printer_config,
197
214
  )
@@ -278,6 +295,53 @@ async def modern_template_edit(
278
295
  return templates.TemplateResponse("modern/template_editor.html", context)
279
296
 
280
297
 
298
+ @router.get("/templates/preview")
299
+ async def modern_template_preview(
300
+ request: Request,
301
+ filename: str,
302
+ dtype: str = "",
303
+ ):
304
+ """Generate a PNG preview of a ZPL template.
305
+
306
+ Returns the PNG image directly or redirects to the generated file.
307
+ """
308
+ zp = request.app.state.zp
309
+ pkg_path = request.app.state.pkg_path
310
+
311
+ # Find the template file
312
+ if dtype:
313
+ filepath = pkg_path / "etc" / "label_styles" / dtype / filename
314
+ else:
315
+ # Try with .zpl extension if not provided
316
+ if not filename.endswith(".zpl"):
317
+ filepath = pkg_path / "etc" / "label_styles" / f"{filename}.zpl"
318
+ else:
319
+ filepath = pkg_path / "etc" / "label_styles" / filename
320
+
321
+ if not filepath.exists():
322
+ raise HTTPException(status_code=404, detail=f"Template '{filename}' not found")
323
+
324
+ try:
325
+ # Read template content
326
+ zpl_content = filepath.read_text()
327
+
328
+ # Generate PNG preview
329
+ output_dir = pkg_path / "files"
330
+ output_dir.mkdir(parents=True, exist_ok=True)
331
+
332
+ # Use template name for output file
333
+ template_name = filepath.stem
334
+ output_path = output_dir / f"{template_name}_preview.png"
335
+
336
+ zp.generate_label_png(zpl_content, str(output_path), False)
337
+
338
+ # Return redirect to the generated file
339
+ return RedirectResponse(url=f"/files/{template_name}_preview.png", status_code=303)
340
+
341
+ except Exception as e:
342
+ raise HTTPException(status_code=500, detail=f"Preview generation failed: {e}") from None
343
+
344
+
281
345
  @router.get("/config", response_class=HTMLResponse)
282
346
  async def modern_config(request: Request):
283
347
  """Modern configuration page."""
@@ -297,438 +361,89 @@ async def modern_config(request: Request):
297
361
  "backups": stats["backups"],
298
362
  }
299
363
 
364
+ # Get the config file path that was loaded
365
+ config_file_path = getattr(zp, "printers_filename", "Unknown")
366
+
300
367
  context = get_modern_context(
301
368
  request,
302
369
  active_page="config",
303
370
  labs=labs,
304
371
  ip_root=ip_root,
305
372
  config_summary=config_summary,
373
+ config_file_path=config_file_path,
306
374
  )
307
375
  return templates.TemplateResponse("modern/config.html", context)
308
376
 
309
377
 
310
378
  @router.get("/config/view", response_class=HTMLResponse)
311
379
  async def modern_config_view(request: Request):
312
- """View printer configuration JSON (redirects to legacy for now)."""
313
- return RedirectResponse(url="/legacy/view_pstation_json", status_code=303)
314
-
315
-
316
- @router.get("/config/edit", response_class=HTMLResponse)
317
- async def modern_config_edit(request: Request):
318
- """Edit printer configuration JSON (redirects to legacy for now)."""
319
- return RedirectResponse(url="/legacy/view_pstation_json", status_code=303)
320
-
321
-
322
- @router.get("/config/backups", response_class=HTMLResponse)
323
- async def modern_config_backups(request: Request):
324
- """List prior config files (redirects to legacy for now)."""
325
- return RedirectResponse(url="/legacy/list_prior_printer_config_files", status_code=303)
326
-
327
-
328
- @router.get("/config/new", response_class=HTMLResponse)
329
- async def modern_config_new(request: Request):
330
- """Build new config (redirects to legacy for now)."""
331
- return RedirectResponse(url="/legacy/build_new_printers_config_json", status_code=303)
332
-
333
-
334
- @router.get("/config/scan", response_class=HTMLResponse)
335
- async def modern_config_scan(
336
- request: Request,
337
- ip_stub: str = "192.168.1",
338
- scan_wait: str = "0.25",
339
- lab: str = "scan-results",
340
- ):
341
- """Scan network for printers."""
342
- zp = request.app.state.zp
343
- zp.probe_zebra_printers_add_to_printers_json(
344
- ip_stub=ip_stub, scan_wait=scan_wait, lab=lab
345
- )
346
- time.sleep(2.2)
347
- return RedirectResponse(url=f"/printers/{lab}", status_code=303)
348
-
349
-
350
- @router.get("/_print_label", response_class=HTMLResponse)
351
- async def modern_print_label(
352
- request: Request,
353
- lab: Optional[str] = None,
354
- printer: str = "",
355
- printer_ip: str = "",
356
- label_zpl_style: str = "",
357
- uid_barcode: str = "",
358
- alt_a: str = "",
359
- alt_b: str = "",
360
- alt_c: str = "",
361
- alt_d: str = "",
362
- alt_e: str = "",
363
- alt_f: str = "",
364
- labSelect: str = "",
365
- ):
366
- """Execute print request - modern UI."""
380
+ """View printer configuration JSON."""
367
381
  zp = request.app.state.zp
368
382
  templates = request.app.state.templates
369
- rate_limiter = request.app.state.print_rate_limiter
370
-
371
- if lab is None:
372
- lab = labSelect
373
-
374
- client_ip = request.client.host if request.client else "unknown"
375
383
 
376
- # Check rate limit
377
- allowed, reason = await rate_limiter.acquire(client_ip)
378
- if not allowed:
379
- raise HTTPException(status_code=429, detail=reason)
380
-
381
- try:
382
- result = zp.print_zpl(
383
- lab=lab,
384
- printer_name=printer,
385
- label_zpl_style=label_zpl_style,
386
- uid_barcode=uid_barcode,
387
- alt_a=alt_a,
388
- alt_b=alt_b,
389
- alt_c=alt_c,
390
- alt_d=alt_d,
391
- alt_e=alt_e,
392
- alt_f=alt_f,
393
- client_ip=client_ip,
394
- )
395
- finally:
396
- rate_limiter.release()
397
-
398
- # Build the full URL for reference
399
- full_url = str(request.url)
400
-
401
- png_url = None
402
- if result and ".png" in str(result):
403
- png_name = str(result).split("/")[-1]
404
- png_url = f"/files/{png_name}"
405
-
406
- context = get_modern_context(
407
- request,
408
- title="Print Result",
409
- success=True,
410
- full_url=full_url,
411
- png_url=png_url,
412
- )
413
- return templates.TemplateResponse("modern/print_result.html", context)
414
-
415
-
416
- @router.post("/save", response_class=HTMLResponse)
417
- async def modern_save_template(
418
- request: Request,
419
- filename: str = Form(...),
420
- content: str = Form(...),
421
- ftag: str = Form("na"),
422
- lab: str = Form(""),
423
- printer: str = Form(""),
424
- ):
425
- """Save ZPL template as a new draft file - modern UI."""
426
- templates = request.app.state.templates
427
- pkg_path = request.app.state.pkg_path
428
-
429
- rec_date = str(datetime.now()).replace(" ", "_")
430
- new_filename = filename.replace(".zpl", f".{ftag}.{rec_date}.zpl")
431
-
432
- tmps_dir = pkg_path / "etc" / "label_styles" / "tmps"
433
- tmps_dir.mkdir(parents=True, exist_ok=True)
434
-
435
- temp_filepath = tmps_dir / new_filename
436
- temp_filepath.write_text(content)
437
-
438
- context = get_modern_context(
439
- request,
440
- title="Template Saved",
441
- new_filename=new_filename,
442
- )
443
- return templates.TemplateResponse("modern/save_result.html", context)
444
-
445
-
446
- @router.post("/png_renderer")
447
- async def modern_png_renderer(
448
- request: Request,
449
- filename: str = Form(...),
450
- content: str = Form(...),
451
- lab: str = Form(""),
452
- printer: str = Form(""),
453
- ftag: str = Form(""),
454
- ):
455
- """Render ZPL content to PNG - modern UI."""
456
- zp = request.app.state.zp
457
- pkg_path = request.app.state.pkg_path
458
-
459
- files_dir = pkg_path / "files"
460
- files_dir.mkdir(parents=True, exist_ok=True)
461
-
462
- png_tmp_f = tempfile.NamedTemporaryFile(
463
- suffix=".png", dir=str(files_dir), delete=False
464
- ).name
465
-
466
- zp.generate_label_png(content, png_fn=png_tmp_f)
467
-
468
- # Return just the relative path for the img src
469
- return Response(
470
- content=f"files/{Path(png_tmp_f).name}",
471
- media_type="text/plain",
472
- )
473
-
474
-
475
- # =============================================================================
476
- # LEGACY UI ROUTES (under /legacy prefix)
477
- # =============================================================================
478
-
479
- @router.get("/legacy", response_class=HTMLResponse)
480
- async def legacy_index(request: Request):
481
- """Legacy home page."""
482
- zp = request.app.state.zp
483
- templates = request.app.state.templates
484
-
485
- labs = list(zp.printers.get("labs", {}).keys())
486
-
487
- context = get_template_context(
488
- request,
489
- title="Zebra Day - Home",
490
- labs=labs,
491
- )
492
- return templates.TemplateResponse("legacy/index.html", context)
493
-
494
-
495
- @router.get("/legacy/printer_status", response_class=HTMLResponse)
496
- async def legacy_printer_status(request: Request, lab: str = "scan-results"):
497
- """Legacy printer status page for a lab."""
498
- zp = request.app.state.zp
499
- templates = request.app.state.templates
500
-
501
- if lab not in zp.printers.get("labs", {}):
502
- raise HTTPException(status_code=404, detail=f"Lab '{lab}' not found")
503
-
504
- printers = []
505
- for name, info in zp.printers["labs"][lab].items():
506
- printer_data = {
507
- "name": name,
508
- "ip_address": info.get("ip_address", ""),
509
- "model": info.get("model", ""),
510
- "serial": info.get("serial", ""),
511
- "label_zpl_styles": info.get("label_zpl_styles", []),
512
- "arp_data": info.get("arp_data", ""),
513
- "status": "unknown",
514
- }
515
-
516
- # Try to get printer status (curl check)
517
- if info.get("ip_address") and info["ip_address"] != "dl_png":
518
- try:
519
- result = subprocess.run(
520
- ["curl", "-m", "4", info["ip_address"]],
521
- capture_output=True,
522
- text=True,
523
- timeout=5,
524
- )
525
- for line in result.stdout.splitlines():
526
- if "Status:" in line:
527
- printer_data["status"] = line.strip()
528
- break
529
- except Exception:
530
- printer_data["status"] = "Unable to connect"
531
-
532
- printers.append(printer_data)
533
-
534
- ip_root = ".".join(request.app.state.local_ip.split(".")[:-1])
384
+ config_json = json.dumps(zp.printers, indent=4)
535
385
 
536
386
  context = get_template_context(
537
387
  request,
538
- title=f"Printer Status - {lab}",
539
- lab=lab,
540
- printers=printers,
541
- ip_root=ip_root,
542
- labs=list(zp.printers.get("labs", {}).keys()),
388
+ title="View Configuration",
389
+ config_json=config_json,
390
+ mode="view",
543
391
  )
544
- return templates.TemplateResponse("legacy/printer_status.html", context)
392
+ return templates.TemplateResponse("modern/config_editor.html", context)
545
393
 
546
394
 
547
- @router.get("/legacy/simple_print_request", response_class=HTMLResponse)
548
- async def legacy_simple_print_request(request: Request):
549
- """Legacy simple print request form."""
550
- zp = request.app.state.zp
551
- templates = request.app.state.templates
552
-
553
- pkg_path = request.app.state.pkg_path
554
- styles_dir = pkg_path / "etc" / "label_styles"
555
-
556
- template_names = []
557
- if styles_dir.exists():
558
- for f in sorted(styles_dir.iterdir()):
559
- if f.is_file() and f.suffix == ".zpl":
560
- template_names.append(f.stem)
561
-
562
- labs_and_printers = {
563
- lab: list(printers.keys())
564
- for lab, printers in zp.printers.get("labs", {}).items()
565
- }
566
-
567
- context = get_template_context(
568
- request,
569
- title="Print Label",
570
- templates=template_names,
571
- labs=list(zp.printers.get("labs", {}).keys()),
572
- labs_and_printers=json.dumps(labs_and_printers),
573
- )
574
- return templates.TemplateResponse("legacy/simple_print.html", context)
575
-
576
-
577
- @router.get("/legacy/edit_zpl", response_class=HTMLResponse)
578
- async def legacy_edit_zpl(request: Request):
579
- """Legacy list ZPL templates for editing."""
580
- templates = request.app.state.templates
581
- pkg_path = request.app.state.pkg_path
582
- styles_dir = pkg_path / "etc" / "label_styles"
583
-
584
- stable_templates = []
585
- draft_templates = []
586
-
587
- if styles_dir.exists():
588
- for f in sorted(styles_dir.iterdir()):
589
- if f.is_file() and f.suffix == ".zpl":
590
- stable_templates.append(f.name)
591
-
592
- tmps_dir = styles_dir / "tmps"
593
- if tmps_dir.exists():
594
- for f in sorted(tmps_dir.iterdir()):
595
- if f.is_file() and f.suffix == ".zpl":
596
- draft_templates.append(f.name)
597
-
598
- context = get_template_context(
599
- request,
600
- title="Edit ZPL Templates",
601
- stable_templates=stable_templates,
602
- draft_templates=draft_templates,
603
- )
604
- return templates.TemplateResponse("legacy/edit_zpl.html", context)
605
-
606
-
607
- @router.get("/legacy/chg_ui_style", response_class=HTMLResponse)
608
- async def legacy_chg_ui_style(request: Request, css_file: Optional[str] = None):
609
- """Legacy change UI style or show available styles."""
610
- if css_file:
611
- request.app.state.css_theme = css_file
612
- return RedirectResponse(url="/legacy", status_code=303)
613
-
614
- templates = request.app.state.templates
615
- pkg_path = request.app.state.pkg_path
616
- static_dir = pkg_path / "static"
617
-
618
- css_files = []
619
- if static_dir.exists():
620
- for f in sorted(static_dir.iterdir()):
621
- if f.suffix == ".css":
622
- css_files.append(f.name)
623
-
624
- context = get_template_context(request, title="Change UI Style", css_files=css_files)
625
- return templates.TemplateResponse("legacy/chg_ui_style.html", context)
626
-
627
-
628
- @router.get("/legacy/printer_details", response_class=HTMLResponse)
629
- async def legacy_printer_details(request: Request, printer_name: str, lab: str):
630
- """Legacy show detailed printer information."""
631
- zp = request.app.state.zp
632
- templates = request.app.state.templates
633
-
634
- if lab not in zp.printers.get("labs", {}):
635
- raise HTTPException(status_code=404, detail=f"Lab '{lab}' not found")
636
- if printer_name not in zp.printers["labs"][lab]:
637
- raise HTTPException(status_code=404, detail=f"Printer '{printer_name}' not found")
638
-
639
- printer_info = zp.printers["labs"][lab][printer_name]
640
-
641
- # Try to get printer configuration
642
- printer_config = ""
643
- ip_addr = printer_info.get("ip_address", "")
644
- if ip_addr and ip_addr != "dl_png":
645
- try:
646
- printer_config = zdcm.ZebraPrinter(ip_addr).get_configuration()
647
- except Exception as e:
648
- printer_config = f"Unable to retrieve config: {e}"
649
-
650
- context = get_template_context(
651
- request,
652
- title=f"Printer Details - {printer_name}",
653
- printer_name=printer_name,
654
- lab=lab,
655
- printer_info=printer_info,
656
- printer_config=printer_config,
657
- )
658
- return templates.TemplateResponse("legacy/printer_details.html", context)
659
-
660
-
661
- @router.get("/legacy/view_pstation_json", response_class=HTMLResponse)
662
- async def legacy_view_pstation_json(request: Request, error_msg: Optional[str] = None):
663
- """Legacy view and edit printer configuration JSON."""
395
+ @router.get("/config/edit", response_class=HTMLResponse)
396
+ async def modern_config_edit(request: Request, error_msg: str | None = None):
397
+ """Edit printer configuration JSON."""
664
398
  zp = request.app.state.zp
665
399
  templates = request.app.state.templates
666
400
 
667
- config_data = json.dumps(zp.printers, indent=4)
401
+ config_json = json.dumps(zp.printers, indent=4)
668
402
 
669
403
  context = get_template_context(
670
404
  request,
671
- title="View Printer Config JSON",
672
- config_data=config_data,
405
+ title="Edit Configuration",
406
+ config_json=config_json,
407
+ mode="edit",
673
408
  error_msg=error_msg,
674
409
  )
675
- return templates.TemplateResponse("legacy/view_pstation_json.html", context)
410
+ return templates.TemplateResponse("modern/config_editor.html", context)
676
411
 
677
412
 
678
- @router.post("/legacy/save_pstation_json")
679
- async def legacy_save_pstation_json(request: Request, json_data: str = Form(...)):
680
- """Legacy save edited printer configuration JSON."""
413
+ @router.post("/config/save")
414
+ async def modern_config_save(request: Request, json_data: str = Form(...)):
415
+ """Save edited printer configuration JSON."""
681
416
  zp = request.app.state.zp
417
+ pkg_path = request.app.state.pkg_path
682
418
 
683
419
  try:
684
- data = json.loads(json_data)
685
- except json.JSONDecodeError as e:
686
- return RedirectResponse(
687
- url=f"/legacy/view_pstation_json?error_msg=Invalid+JSON:+{str(e)}",
688
- status_code=303,
689
- )
420
+ # Validate JSON
421
+ new_config = json.loads(json_data)
690
422
 
691
- try:
692
- # Backup and save
693
- zp.save_printer_json()
423
+ # Backup current config
424
+ json_file = pkg_path / "etc" / "printer_config.json"
425
+ if json_file.exists():
426
+ bkup_dir = pkg_path / "etc" / "old_printer_config"
427
+ bkup_dir.mkdir(parents=True, exist_ok=True)
428
+ rec_date = str(datetime.now()).replace(" ", "_")
429
+ bkup_file = bkup_dir / f"printer_config.{rec_date}.json"
430
+ bkup_file.write_text(json_file.read_text())
694
431
 
695
- # Write new config
696
- with open(zp.printers_filename, "w") as f:
697
- json.dump(data, f, indent=4)
432
+ # Save new config
433
+ json_file.write_text(json.dumps(new_config, indent=4))
698
434
 
699
435
  # Reload config
700
436
  zp.load_printer_json(json_file=zp.printers_filename, relative=False)
701
437
 
702
- return RedirectResponse(url="/legacy", status_code=303)
703
-
704
- except Exception as e:
705
- return RedirectResponse(
706
- url=f"/legacy/view_pstation_json?error_msg=Error+saving:+{str(e)}",
707
- status_code=303,
708
- )
709
-
438
+ return RedirectResponse(url="/config", status_code=303)
710
439
 
711
- @router.get("/legacy/clear_printers_json")
712
- async def legacy_clear_printers_json(request: Request):
713
- """Legacy clear the printer configuration JSON."""
714
- zp = request.app.state.zp
715
- zp.clear_printers_json()
716
- time.sleep(1.2)
717
- return RedirectResponse(url="/legacy", status_code=303)
718
-
719
-
720
- @router.get("/legacy/reset_pstation_json")
721
- async def legacy_reset_pstation_json(request: Request):
722
- """Legacy reset printer config from template."""
723
- zp = request.app.state.zp
724
- zp.replace_printer_json_from_template()
725
- time.sleep(1.2)
726
- return RedirectResponse(url="/legacy", status_code=303)
440
+ except json.JSONDecodeError as e:
441
+ return RedirectResponse(url=f"/config/edit?error_msg=Invalid JSON: {e}", status_code=303)
727
442
 
728
443
 
729
- @router.get("/legacy/list_prior_printer_config_files", response_class=HTMLResponse)
730
- async def legacy_list_prior_printer_config_files(request: Request):
731
- """Legacy list backed up printer config files."""
444
+ @router.get("/config/backups", response_class=HTMLResponse)
445
+ async def modern_config_backups(request: Request):
446
+ """List prior config files."""
732
447
  templates = request.app.state.templates
733
448
  pkg_path = request.app.state.pkg_path
734
449
  bkup_dir = pkg_path / "etc" / "old_printer_config"
@@ -741,15 +456,15 @@ async def legacy_list_prior_printer_config_files(request: Request):
741
456
 
742
457
  context = get_template_context(
743
458
  request,
744
- title="Prior Printer Config Files",
459
+ title="Configuration Backups",
745
460
  backup_files=backup_files,
746
461
  )
747
- return templates.TemplateResponse("legacy/list_prior_configs.html", context)
462
+ return templates.TemplateResponse("modern/config_backups.html", context)
748
463
 
749
464
 
750
- @router.get("/legacy/build_new_printers_config_json", response_class=HTMLResponse)
751
- async def legacy_build_new_printers_config_json(request: Request):
752
- """Legacy show network scan form."""
465
+ @router.get("/config/new", response_class=HTMLResponse)
466
+ async def modern_config_new(request: Request):
467
+ """Build new config page."""
753
468
  zp = request.app.state.zp
754
469
  templates = request.app.state.templates
755
470
 
@@ -757,109 +472,49 @@ async def legacy_build_new_printers_config_json(request: Request):
757
472
 
758
473
  context = get_template_context(
759
474
  request,
760
- title="Scan Network for Printers",
475
+ title="New Configuration",
761
476
  ip_root=ip_root,
762
477
  labs=list(zp.printers.get("labs", {}).keys()),
763
478
  )
764
- return templates.TemplateResponse("legacy/build_new_config.html", context)
479
+ return templates.TemplateResponse("modern/config_new.html", context)
765
480
 
766
481
 
767
- @router.get("/legacy/probe_zebra_printers_add_to_printers_json")
768
- async def legacy_probe_zebra_printers(
769
- request: Request,
770
- ip_stub: str = "192.168.1",
771
- scan_wait: str = "0.25",
772
- lab: str = "scan-results",
773
- ):
774
- """Legacy probe network for Zebra printers and add to config."""
775
- zp = request.app.state.zp
776
- zp.probe_zebra_printers_add_to_printers_json(
777
- ip_stub=ip_stub, scan_wait=scan_wait, lab=lab
778
- )
779
- time.sleep(2.2)
780
- return RedirectResponse(url=f"/legacy/printer_status?lab={lab}", status_code=303)
781
-
782
-
783
- @router.get("/legacy/bpr", response_class=HTMLResponse)
784
- async def legacy_bpr(request: Request):
785
- """Legacy build print request - select lab, printer, template."""
482
+ @router.get("/config/reset")
483
+ async def modern_config_reset(request: Request):
484
+ """Reset printer config from template."""
786
485
  zp = request.app.state.zp
787
- templates = request.app.state.templates
788
- pkg_path = request.app.state.pkg_path
789
-
790
- styles_dir = pkg_path / "etc" / "label_styles"
791
-
792
- stable_templates = []
793
- draft_templates = []
794
-
795
- if styles_dir.exists():
796
- for f in sorted(styles_dir.iterdir()):
797
- if f.is_file() and f.suffix == ".zpl":
798
- stable_templates.append(f.stem)
799
-
800
- tmps_dir = styles_dir / "tmps"
801
- if tmps_dir.exists():
802
- for f in sorted(tmps_dir.iterdir()):
803
- if f.is_file() and f.suffix == ".zpl":
804
- draft_templates.append(f.stem)
805
-
806
- labs_dict = zp.printers.get("labs", {})
807
-
808
- context = get_template_context(
809
- request,
810
- title="Build Print Request",
811
- labs=list(labs_dict.keys()),
812
- labs_dict=json.dumps(labs_dict),
813
- stable_templates=stable_templates,
814
- draft_templates=draft_templates,
815
- )
816
- return templates.TemplateResponse("legacy/bpr.html", context)
486
+ zp.replace_printer_json_from_template()
487
+ time.sleep(1.2)
488
+ return RedirectResponse(url="/config", status_code=303)
817
489
 
818
490
 
819
- @router.get("/legacy/send_print_request", response_class=HTMLResponse)
820
- async def legacy_send_print_request(request: Request):
821
- """Legacy send print request - stable templates only."""
491
+ @router.get("/config/clear")
492
+ async def modern_config_clear(request: Request):
493
+ """Clear the printer configuration JSON."""
822
494
  zp = request.app.state.zp
823
- templates = request.app.state.templates
824
-
825
- context = get_template_context(
826
- request,
827
- title="Send Print Request",
828
- labs=zp.printers.get("labs", {}),
829
- )
830
- return templates.TemplateResponse("legacy/send_print_request.html", context)
495
+ zp.clear_printers_json()
496
+ time.sleep(1.2)
497
+ return RedirectResponse(url="/config", status_code=303)
831
498
 
832
499
 
833
- @router.get("/legacy/build_print_request", response_class=HTMLResponse)
834
- async def legacy_build_print_request(
500
+ @router.get("/config/scan", response_class=HTMLResponse)
501
+ async def modern_config_scan(
835
502
  request: Request,
836
- lab: str = "",
837
- printer: str = "",
838
- printer_ip: str = "",
839
- label_zpl_style: str = "",
840
- filename: str = "",
503
+ ip_stub: str = "192.168.1",
504
+ scan_wait: str = "0.25",
505
+ lab: str = "scan-results",
841
506
  ):
842
- """Legacy show print request form with pre-filled values."""
843
- templates = request.app.state.templates
844
-
845
- if label_zpl_style in ["", "None"] and filename not in ["", "None"]:
846
- label_zpl_style = filename.replace(".zpl", "")
847
-
848
- context = get_template_context(
849
- request,
850
- title="Build Print Request",
851
- lab=lab,
852
- printer=printer,
853
- printer_ip=printer_ip,
854
- label_zpl_style=label_zpl_style,
855
- )
856
- return templates.TemplateResponse("legacy/build_print_request.html", context)
507
+ """Scan network for printers."""
508
+ zp = request.app.state.zp
509
+ zp.probe_zebra_printers_add_to_printers_json(ip_stub=ip_stub, scan_wait=scan_wait, lab=lab)
510
+ time.sleep(2.2)
511
+ return RedirectResponse(url=f"/printers/{lab}", status_code=303)
857
512
 
858
513
 
859
- @router.get("/legacy/_print_label", response_class=HTMLResponse)
860
- async def legacy_print_label(
514
+ @router.get("/_print_label", response_class=HTMLResponse)
515
+ async def modern_print_label(
861
516
  request: Request,
862
- lab: Optional[str] = None,
517
+ lab: str | None = None,
863
518
  printer: str = "",
864
519
  printer_ip: str = "",
865
520
  label_zpl_style: str = "",
@@ -872,7 +527,7 @@ async def legacy_print_label(
872
527
  alt_f: str = "",
873
528
  labSelect: str = "",
874
529
  ):
875
- """Legacy execute print request."""
530
+ """Execute print request - modern UI."""
876
531
  zp = request.app.state.zp
877
532
  templates = request.app.state.templates
878
533
  rate_limiter = request.app.state.print_rate_limiter
@@ -910,55 +565,20 @@ async def legacy_print_label(
910
565
  png_url = None
911
566
  if result and ".png" in str(result):
912
567
  png_name = str(result).split("/")[-1]
913
- png_url = f"/files/{png_name}"
568
+ png_url = f"/generated/{png_name}"
914
569
 
915
- context = get_template_context(
570
+ context = get_modern_context(
916
571
  request,
917
572
  title="Print Result",
918
573
  success=True,
919
574
  full_url=full_url,
920
575
  png_url=png_url,
921
576
  )
922
- return templates.TemplateResponse("legacy/print_result.html", context)
923
-
924
-
925
- @router.get("/legacy/edit", response_class=HTMLResponse)
926
- async def legacy_edit_template(
927
- request: Request,
928
- filename: str,
929
- dtype: str = "",
930
- ):
931
- """Legacy edit a ZPL template file."""
932
- zp = request.app.state.zp
933
- templates = request.app.state.templates
934
- pkg_path = request.app.state.pkg_path
935
-
936
- if dtype:
937
- filepath = pkg_path / "etc" / "label_styles" / dtype / filename
938
- else:
939
- filepath = pkg_path / "etc" / "label_styles" / filename
940
-
941
- if not filepath.exists():
942
- raise HTTPException(status_code=404, detail=f"Template '{filename}' not found")
943
-
944
- content = filepath.read_text()
945
-
946
- labs_dict = zp.printers.get("labs", {})
947
-
948
- context = get_template_context(
949
- request,
950
- title=f"Edit: {filename}",
951
- filename=filename,
952
- content=content,
953
- dtype=dtype,
954
- labs=list(labs_dict.keys()),
955
- labs_dict=json.dumps(labs_dict),
956
- )
957
- return templates.TemplateResponse("legacy/edit_template.html", context)
577
+ return templates.TemplateResponse("modern/print_result.html", context)
958
578
 
959
579
 
960
- @router.post("/legacy/save", response_class=HTMLResponse)
961
- async def legacy_save_template(
580
+ @router.post("/save", response_class=HTMLResponse)
581
+ async def modern_save_template(
962
582
  request: Request,
963
583
  filename: str = Form(...),
964
584
  content: str = Form(...),
@@ -966,7 +586,7 @@ async def legacy_save_template(
966
586
  lab: str = Form(""),
967
587
  printer: str = Form(""),
968
588
  ):
969
- """Legacy save ZPL template as a new draft file."""
589
+ """Save ZPL template as a new draft file - modern UI."""
970
590
  templates = request.app.state.templates
971
591
  pkg_path = request.app.state.pkg_path
972
592
 
@@ -979,16 +599,16 @@ async def legacy_save_template(
979
599
  temp_filepath = tmps_dir / new_filename
980
600
  temp_filepath.write_text(content)
981
601
 
982
- context = get_template_context(
602
+ context = get_modern_context(
983
603
  request,
984
604
  title="Template Saved",
985
605
  new_filename=new_filename,
986
606
  )
987
- return templates.TemplateResponse("legacy/save_result.html", context)
607
+ return templates.TemplateResponse("modern/save_result.html", context)
988
608
 
989
609
 
990
- @router.post("/legacy/png_renderer")
991
- async def legacy_png_renderer(
610
+ @router.post("/png_renderer")
611
+ async def modern_png_renderer(
992
612
  request: Request,
993
613
  filename: str = Form(...),
994
614
  content: str = Form(...),
@@ -996,16 +616,14 @@ async def legacy_png_renderer(
996
616
  printer: str = Form(""),
997
617
  ftag: str = Form(""),
998
618
  ):
999
- """Legacy render ZPL content to PNG."""
619
+ """Render ZPL content to PNG - modern UI."""
1000
620
  zp = request.app.state.zp
1001
621
  pkg_path = request.app.state.pkg_path
1002
622
 
1003
623
  files_dir = pkg_path / "files"
1004
624
  files_dir.mkdir(parents=True, exist_ok=True)
1005
625
 
1006
- png_tmp_f = tempfile.NamedTemporaryFile(
1007
- suffix=".png", dir=str(files_dir), delete=False
1008
- ).name
626
+ png_tmp_f = tempfile.NamedTemporaryFile(suffix=".png", dir=str(files_dir), delete=False).name
1009
627
 
1010
628
  zp.generate_label_png(content, png_fn=png_tmp_f)
1011
629
 
@@ -1014,38 +632,3 @@ async def legacy_png_renderer(
1014
632
  content=f"files/{Path(png_tmp_f).name}",
1015
633
  media_type="text/plain",
1016
634
  )
1017
-
1018
-
1019
- @router.post("/legacy/build_and_send_raw_print_request")
1020
- async def legacy_build_and_send_raw_print_request(
1021
- request: Request,
1022
- lab: str = Form(...),
1023
- printer: str = Form(...),
1024
- content: str = Form(...),
1025
- printer_ip: str = Form(""),
1026
- label_zpl_style: str = Form(""),
1027
- filename: str = Form(""),
1028
- ftag: str = Form(""),
1029
- ):
1030
- """Legacy send raw ZPL content to printer."""
1031
- zp = request.app.state.zp
1032
- rate_limiter = request.app.state.print_rate_limiter
1033
- client_ip = request.client.host if request.client else "unknown"
1034
-
1035
- # Check rate limit
1036
- allowed, reason = await rate_limiter.acquire(client_ip)
1037
- if not allowed:
1038
- raise HTTPException(status_code=429, detail=reason)
1039
-
1040
- try:
1041
- zp.print_zpl(
1042
- lab=lab,
1043
- printer_name=printer,
1044
- label_zpl_style=None,
1045
- zpl_content=content,
1046
- client_ip=client_ip,
1047
- )
1048
- finally:
1049
- rate_limiter.release()
1050
-
1051
- return {"status": "sent"}