zebra-day 1.0.2__py3-none-any.whl → 2.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- zebra_day/cli/gui.py +89 -6
- zebra_day/etc/printer_config.json +2 -14
- zebra_day/etc/printer_config.template.json +17 -9
- zebra_day/etc/tmp_printers120.json +10 -0
- zebra_day/etc/tmp_printers145.json +10 -0
- zebra_day/etc/tmp_printers207.json +10 -0
- zebra_day/etc/tmp_printers469.json +10 -0
- zebra_day/etc/tmp_printers485.json +10 -0
- zebra_day/etc/tmp_printers531.json +10 -0
- zebra_day/etc/tmp_printers540.json +10 -0
- zebra_day/etc/tmp_printers542.json +10 -0
- zebra_day/etc/tmp_printers552.json +10 -0
- zebra_day/etc/tmp_printers715.json +10 -0
- zebra_day/etc/tmp_printers972.json +10 -0
- zebra_day/files/blank_preview.png +0 -0
- zebra_day/files/corners_20cmX30cm_preview.png +0 -0
- zebra_day/files/generic_2inX1in_preview.png +0 -0
- zebra_day/files/test_png_12020.png +0 -0
- zebra_day/files/test_png_12352.png +0 -0
- zebra_day/files/test_png_15472.png +0 -0
- zebra_day/files/test_png_24493.png +0 -0
- zebra_day/files/test_png_30069.png +0 -0
- zebra_day/files/test_png_47791.png +0 -0
- zebra_day/files/test_png_47799.png +0 -0
- zebra_day/files/test_png_55588.png +0 -0
- zebra_day/files/test_png_58809.png +0 -0
- zebra_day/files/test_png_67242.png +0 -0
- zebra_day/files/test_png_89893.png +0 -0
- zebra_day/files/tube_20mmX30mmA_preview.png +0 -0
- zebra_day/print_mgr.py +136 -80
- zebra_day/templates/modern/config_backups.html +59 -0
- zebra_day/templates/modern/config_editor.html +95 -0
- zebra_day/templates/modern/config_new.html +93 -0
- zebra_day/templates/modern/print_request.html +9 -5
- zebra_day/templates/modern/printer_detail.html +161 -34
- zebra_day/templates/modern/printers.html +17 -6
- zebra_day/templates/modern/template_editor.html +7 -4
- zebra_day/web/app.py +84 -7
- zebra_day/web/routers/api.py +155 -5
- zebra_day/web/routers/ui.py +155 -570
- {zebra_day-1.0.2.dist-info → zebra_day-2.0.0.dist-info}/METADATA +74 -13
- {zebra_day-1.0.2.dist-info → zebra_day-2.0.0.dist-info}/RECORD +46 -57
- zebra_day/bin/fetch_zebra_config.py +0 -15
- zebra_day/bin/generate_coord_grid_zpl.py +0 -50
- zebra_day/bin/print_zpl_from_file.py +0 -21
- zebra_day/bin/probe_new_label_dimensions.py +0 -75
- zebra_day/bin/scan_for_networed_zebra_printers.py +0 -23
- zebra_day/bin/scan_for_networed_zebra_printers_arp_scan.sh +0 -1
- zebra_day/bin/scan_for_networed_zebra_printers_curl.sh +0 -30
- zebra_day/bin/zserve.py +0 -1062
- zebra_day/templates/base.html +0 -36
- zebra_day/templates/bpr.html +0 -72
- zebra_day/templates/build_new_config.html +0 -36
- zebra_day/templates/build_print_request.html +0 -32
- zebra_day/templates/chg_ui_style.html +0 -19
- zebra_day/templates/edit_template.html +0 -128
- zebra_day/templates/edit_zpl.html +0 -37
- zebra_day/templates/index.html +0 -82
- zebra_day/templates/legacy/base.html +0 -37
- zebra_day/templates/legacy/bpr.html +0 -72
- zebra_day/templates/legacy/build_new_config.html +0 -36
- zebra_day/templates/legacy/build_print_request.html +0 -32
- zebra_day/templates/legacy/chg_ui_style.html +0 -19
- zebra_day/templates/legacy/edit_template.html +0 -128
- zebra_day/templates/legacy/edit_zpl.html +0 -37
- zebra_day/templates/legacy/index.html +0 -82
- zebra_day/templates/legacy/list_prior_configs.html +0 -24
- zebra_day/templates/legacy/print_result.html +0 -30
- zebra_day/templates/legacy/printer_details.html +0 -25
- zebra_day/templates/legacy/printer_status.html +0 -70
- zebra_day/templates/legacy/save_result.html +0 -17
- zebra_day/templates/legacy/send_print_request.html +0 -34
- zebra_day/templates/legacy/simple_print.html +0 -94
- zebra_day/templates/legacy/view_pstation_json.html +0 -29
- zebra_day/templates/list_prior_configs.html +0 -24
- zebra_day/templates/print_result.html +0 -30
- zebra_day/templates/printer_details.html +0 -25
- zebra_day/templates/printer_status.html +0 -70
- zebra_day/templates/save_result.html +0 -17
- zebra_day/templates/send_print_request.html +0 -34
- zebra_day/templates/simple_print.html +0 -94
- zebra_day/templates/view_pstation_json.html +0 -29
- {zebra_day-1.0.2.dist-info → zebra_day-2.0.0.dist-info}/WHEEL +0 -0
- {zebra_day-1.0.2.dist-info → zebra_day-2.0.0.dist-info}/entry_points.txt +0 -0
- {zebra_day-1.0.2.dist-info → zebra_day-2.0.0.dist-info}/licenses/LICENSE +0 -0
- {zebra_day-1.0.2.dist-info → zebra_day-2.0.0.dist-info}/top_level.txt +0 -0
zebra_day/web/routers/ui.py
CHANGED
|
@@ -2,9 +2,7 @@
|
|
|
2
2
|
UI router for zebra_day web interface.
|
|
3
3
|
|
|
4
4
|
Provides HTML endpoints for the web-based management interface.
|
|
5
|
-
|
|
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
|
"""
|
|
9
7
|
from __future__ import annotations
|
|
10
8
|
|
|
@@ -29,7 +27,7 @@ router = APIRouter()
|
|
|
29
27
|
|
|
30
28
|
|
|
31
29
|
def get_template_context(request: Request, **kwargs) -> dict:
|
|
32
|
-
"""Build common template context for
|
|
30
|
+
"""Build common template context for templates."""
|
|
33
31
|
return {
|
|
34
32
|
"request": request,
|
|
35
33
|
"css_theme": f"static/{request.app.state.css_theme}",
|
|
@@ -73,7 +71,8 @@ def get_templates_list(pkg_path: Path) -> tuple[list, list]:
|
|
|
73
71
|
def get_stats(zp, pkg_path: Path) -> dict:
|
|
74
72
|
"""Calculate dashboard statistics."""
|
|
75
73
|
labs = zp.printers.get("labs", {})
|
|
76
|
-
|
|
74
|
+
# Count printers via nested 'printers' key (v2 schema)
|
|
75
|
+
total_printers = sum(len(lab_data.get("printers", {})) for lab_data in labs.values())
|
|
77
76
|
stable, draft = get_templates_list(pkg_path)
|
|
78
77
|
|
|
79
78
|
# Count backup files
|
|
@@ -141,15 +140,23 @@ async def modern_printers_by_lab(request: Request, lab: str):
|
|
|
141
140
|
if lab not in zp.printers.get("labs", {}):
|
|
142
141
|
raise HTTPException(status_code=404, detail=f"Lab '{lab}' not found")
|
|
143
142
|
|
|
143
|
+
lab_data = zp.printers["labs"][lab]
|
|
144
|
+
lab_printers = lab_data.get("printers", {})
|
|
145
|
+
|
|
144
146
|
printers = []
|
|
145
|
-
for name, info in
|
|
147
|
+
for name, info in lab_printers.items():
|
|
146
148
|
printers.append({
|
|
147
|
-
"
|
|
149
|
+
"id": name,
|
|
150
|
+
"name": info.get("printer_name") or name, # Display name or fallback to ID
|
|
151
|
+
"printer_name": info.get("printer_name"),
|
|
148
152
|
"ip_address": info.get("ip_address", ""),
|
|
153
|
+
"lab_location": info.get("lab_location"),
|
|
154
|
+
"manufacturer": info.get("manufacturer", "zebra"),
|
|
149
155
|
"model": info.get("model", ""),
|
|
150
156
|
"serial": info.get("serial", ""),
|
|
151
157
|
"label_zpl_styles": info.get("label_zpl_styles", []),
|
|
152
158
|
"status": "online" if info.get("ip_address") else "unknown",
|
|
159
|
+
"notes": info.get("notes", ""),
|
|
153
160
|
})
|
|
154
161
|
|
|
155
162
|
ip_root = ".".join(request.app.state.local_ip.split(".")[:-1])
|
|
@@ -160,23 +167,29 @@ async def modern_printers_by_lab(request: Request, lab: str):
|
|
|
160
167
|
labs=list(zp.printers.get("labs", {}).keys()),
|
|
161
168
|
printers=printers,
|
|
162
169
|
lab=lab,
|
|
170
|
+
lab_name=lab_data.get("lab_name", lab),
|
|
171
|
+
available_locations=lab_data.get("available_locations", []),
|
|
163
172
|
ip_root=ip_root,
|
|
164
173
|
)
|
|
165
174
|
return templates.TemplateResponse("modern/printers.html", context)
|
|
166
175
|
|
|
167
176
|
|
|
168
|
-
@router.get("/printers/{lab}/{
|
|
169
|
-
async def modern_printer_detail(request: Request, lab: str,
|
|
177
|
+
@router.get("/printers/{lab}/{printer_id}", response_class=HTMLResponse)
|
|
178
|
+
async def modern_printer_detail(request: Request, lab: str, printer_id: str):
|
|
170
179
|
"""Modern printer detail page."""
|
|
171
180
|
zp = request.app.state.zp
|
|
172
181
|
templates = request.app.state.templates
|
|
173
182
|
|
|
174
183
|
if lab not in zp.printers.get("labs", {}):
|
|
175
184
|
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
185
|
|
|
179
|
-
|
|
186
|
+
lab_data = zp.printers["labs"][lab]
|
|
187
|
+
lab_printers = lab_data.get("printers", {})
|
|
188
|
+
|
|
189
|
+
if printer_id not in lab_printers:
|
|
190
|
+
raise HTTPException(status_code=404, detail=f"Printer '{printer_id}' not found")
|
|
191
|
+
|
|
192
|
+
printer_info = lab_printers[printer_id]
|
|
180
193
|
|
|
181
194
|
# Try to get printer configuration
|
|
182
195
|
printer_config = ""
|
|
@@ -190,8 +203,11 @@ async def modern_printer_detail(request: Request, lab: str, printer_name: str):
|
|
|
190
203
|
context = get_modern_context(
|
|
191
204
|
request,
|
|
192
205
|
active_page="printers",
|
|
193
|
-
|
|
206
|
+
printer_id=printer_id,
|
|
207
|
+
printer_name=printer_info.get("printer_name") or printer_id,
|
|
194
208
|
lab=lab,
|
|
209
|
+
lab_name=lab_data.get("lab_name", lab),
|
|
210
|
+
available_locations=lab_data.get("available_locations", []),
|
|
195
211
|
printer_info=printer_info,
|
|
196
212
|
printer_config=printer_config,
|
|
197
213
|
)
|
|
@@ -278,6 +294,53 @@ async def modern_template_edit(
|
|
|
278
294
|
return templates.TemplateResponse("modern/template_editor.html", context)
|
|
279
295
|
|
|
280
296
|
|
|
297
|
+
@router.get("/templates/preview")
|
|
298
|
+
async def modern_template_preview(
|
|
299
|
+
request: Request,
|
|
300
|
+
filename: str,
|
|
301
|
+
dtype: str = "",
|
|
302
|
+
):
|
|
303
|
+
"""Generate a PNG preview of a ZPL template.
|
|
304
|
+
|
|
305
|
+
Returns the PNG image directly or redirects to the generated file.
|
|
306
|
+
"""
|
|
307
|
+
zp = request.app.state.zp
|
|
308
|
+
pkg_path = request.app.state.pkg_path
|
|
309
|
+
|
|
310
|
+
# Find the template file
|
|
311
|
+
if dtype:
|
|
312
|
+
filepath = pkg_path / "etc" / "label_styles" / dtype / filename
|
|
313
|
+
else:
|
|
314
|
+
# Try with .zpl extension if not provided
|
|
315
|
+
if not filename.endswith(".zpl"):
|
|
316
|
+
filepath = pkg_path / "etc" / "label_styles" / f"{filename}.zpl"
|
|
317
|
+
else:
|
|
318
|
+
filepath = pkg_path / "etc" / "label_styles" / filename
|
|
319
|
+
|
|
320
|
+
if not filepath.exists():
|
|
321
|
+
raise HTTPException(status_code=404, detail=f"Template '{filename}' not found")
|
|
322
|
+
|
|
323
|
+
try:
|
|
324
|
+
# Read template content
|
|
325
|
+
zpl_content = filepath.read_text()
|
|
326
|
+
|
|
327
|
+
# Generate PNG preview
|
|
328
|
+
output_dir = pkg_path / "files"
|
|
329
|
+
output_dir.mkdir(parents=True, exist_ok=True)
|
|
330
|
+
|
|
331
|
+
# Use template name for output file
|
|
332
|
+
template_name = filepath.stem
|
|
333
|
+
output_path = output_dir / f"{template_name}_preview.png"
|
|
334
|
+
|
|
335
|
+
result = zp.generate_label_png(zpl_content, str(output_path), False)
|
|
336
|
+
|
|
337
|
+
# Return redirect to the generated file
|
|
338
|
+
return RedirectResponse(url=f"/files/{template_name}_preview.png", status_code=303)
|
|
339
|
+
|
|
340
|
+
except Exception as e:
|
|
341
|
+
raise HTTPException(status_code=500, detail=f"Preview generation failed: {e}")
|
|
342
|
+
|
|
343
|
+
|
|
281
344
|
@router.get("/config", response_class=HTMLResponse)
|
|
282
345
|
async def modern_config(request: Request):
|
|
283
346
|
"""Modern configuration page."""
|
|
@@ -309,426 +372,76 @@ async def modern_config(request: Request):
|
|
|
309
372
|
|
|
310
373
|
@router.get("/config/view", response_class=HTMLResponse)
|
|
311
374
|
async def modern_config_view(request: Request):
|
|
312
|
-
"""View printer configuration JSON
|
|
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."""
|
|
367
|
-
zp = request.app.state.zp
|
|
368
|
-
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
|
-
|
|
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."""
|
|
375
|
+
"""View printer configuration JSON."""
|
|
482
376
|
zp = request.app.state.zp
|
|
483
377
|
templates = request.app.state.templates
|
|
484
378
|
|
|
485
|
-
|
|
379
|
+
config_json = json.dumps(zp.printers, indent=4)
|
|
486
380
|
|
|
487
381
|
context = get_template_context(
|
|
488
382
|
request,
|
|
489
|
-
title="
|
|
490
|
-
|
|
383
|
+
title="View Configuration",
|
|
384
|
+
config_json=config_json,
|
|
385
|
+
mode="view",
|
|
491
386
|
)
|
|
492
|
-
return templates.TemplateResponse("
|
|
387
|
+
return templates.TemplateResponse("modern/config_editor.html", context)
|
|
493
388
|
|
|
494
389
|
|
|
495
|
-
@router.get("/
|
|
496
|
-
async def
|
|
497
|
-
"""
|
|
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])
|
|
535
|
-
|
|
536
|
-
context = get_template_context(
|
|
537
|
-
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()),
|
|
543
|
-
)
|
|
544
|
-
return templates.TemplateResponse("legacy/printer_status.html", context)
|
|
545
|
-
|
|
546
|
-
|
|
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."""
|
|
390
|
+
@router.get("/config/edit", response_class=HTMLResponse)
|
|
391
|
+
async def modern_config_edit(request: Request, error_msg: Optional[str] = None):
|
|
392
|
+
"""Edit printer configuration JSON."""
|
|
664
393
|
zp = request.app.state.zp
|
|
665
394
|
templates = request.app.state.templates
|
|
666
395
|
|
|
667
|
-
|
|
396
|
+
config_json = json.dumps(zp.printers, indent=4)
|
|
668
397
|
|
|
669
398
|
context = get_template_context(
|
|
670
399
|
request,
|
|
671
|
-
title="
|
|
672
|
-
|
|
400
|
+
title="Edit Configuration",
|
|
401
|
+
config_json=config_json,
|
|
402
|
+
mode="edit",
|
|
673
403
|
error_msg=error_msg,
|
|
674
404
|
)
|
|
675
|
-
return templates.TemplateResponse("
|
|
405
|
+
return templates.TemplateResponse("modern/config_editor.html", context)
|
|
676
406
|
|
|
677
407
|
|
|
678
|
-
@router.post("/
|
|
679
|
-
async def
|
|
680
|
-
"""
|
|
408
|
+
@router.post("/config/save")
|
|
409
|
+
async def modern_config_save(request: Request, json_data: str = Form(...)):
|
|
410
|
+
"""Save edited printer configuration JSON."""
|
|
681
411
|
zp = request.app.state.zp
|
|
412
|
+
pkg_path = request.app.state.pkg_path
|
|
682
413
|
|
|
683
414
|
try:
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
return RedirectResponse(
|
|
687
|
-
url=f"/legacy/view_pstation_json?error_msg=Invalid+JSON:+{str(e)}",
|
|
688
|
-
status_code=303,
|
|
689
|
-
)
|
|
415
|
+
# Validate JSON
|
|
416
|
+
new_config = json.loads(json_data)
|
|
690
417
|
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
418
|
+
# Backup current config
|
|
419
|
+
json_file = pkg_path / "etc" / "printer_config.json"
|
|
420
|
+
if json_file.exists():
|
|
421
|
+
bkup_dir = pkg_path / "etc" / "old_printer_config"
|
|
422
|
+
bkup_dir.mkdir(parents=True, exist_ok=True)
|
|
423
|
+
rec_date = str(datetime.now()).replace(" ", "_")
|
|
424
|
+
bkup_file = bkup_dir / f"printer_config.{rec_date}.json"
|
|
425
|
+
bkup_file.write_text(json_file.read_text())
|
|
694
426
|
|
|
695
|
-
#
|
|
696
|
-
|
|
697
|
-
json.dump(data, f, indent=4)
|
|
427
|
+
# Save new config
|
|
428
|
+
json_file.write_text(json.dumps(new_config, indent=4))
|
|
698
429
|
|
|
699
430
|
# Reload config
|
|
700
431
|
zp.load_printer_json(json_file=zp.printers_filename, relative=False)
|
|
701
432
|
|
|
702
|
-
return RedirectResponse(url="/
|
|
433
|
+
return RedirectResponse(url="/config", status_code=303)
|
|
703
434
|
|
|
704
|
-
except
|
|
435
|
+
except json.JSONDecodeError as e:
|
|
705
436
|
return RedirectResponse(
|
|
706
|
-
url=f"/
|
|
707
|
-
status_code=303
|
|
437
|
+
url=f"/config/edit?error_msg=Invalid JSON: {e}",
|
|
438
|
+
status_code=303
|
|
708
439
|
)
|
|
709
440
|
|
|
710
441
|
|
|
711
|
-
@router.get("/
|
|
712
|
-
async def
|
|
713
|
-
"""
|
|
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)
|
|
727
|
-
|
|
728
|
-
|
|
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."""
|
|
442
|
+
@router.get("/config/backups", response_class=HTMLResponse)
|
|
443
|
+
async def modern_config_backups(request: Request):
|
|
444
|
+
"""List prior config files."""
|
|
732
445
|
templates = request.app.state.templates
|
|
733
446
|
pkg_path = request.app.state.pkg_path
|
|
734
447
|
bkup_dir = pkg_path / "etc" / "old_printer_config"
|
|
@@ -741,15 +454,15 @@ async def legacy_list_prior_printer_config_files(request: Request):
|
|
|
741
454
|
|
|
742
455
|
context = get_template_context(
|
|
743
456
|
request,
|
|
744
|
-
title="
|
|
457
|
+
title="Configuration Backups",
|
|
745
458
|
backup_files=backup_files,
|
|
746
459
|
)
|
|
747
|
-
return templates.TemplateResponse("
|
|
460
|
+
return templates.TemplateResponse("modern/config_backups.html", context)
|
|
748
461
|
|
|
749
462
|
|
|
750
|
-
@router.get("/
|
|
751
|
-
async def
|
|
752
|
-
"""
|
|
463
|
+
@router.get("/config/new", response_class=HTMLResponse)
|
|
464
|
+
async def modern_config_new(request: Request):
|
|
465
|
+
"""Build new config page."""
|
|
753
466
|
zp = request.app.state.zp
|
|
754
467
|
templates = request.app.state.templates
|
|
755
468
|
|
|
@@ -757,107 +470,49 @@ async def legacy_build_new_printers_config_json(request: Request):
|
|
|
757
470
|
|
|
758
471
|
context = get_template_context(
|
|
759
472
|
request,
|
|
760
|
-
title="
|
|
473
|
+
title="New Configuration",
|
|
761
474
|
ip_root=ip_root,
|
|
762
475
|
labs=list(zp.printers.get("labs", {}).keys()),
|
|
763
476
|
)
|
|
764
|
-
return templates.TemplateResponse("
|
|
477
|
+
return templates.TemplateResponse("modern/config_new.html", context)
|
|
765
478
|
|
|
766
479
|
|
|
767
|
-
@router.get("/
|
|
768
|
-
async def
|
|
480
|
+
@router.get("/config/reset")
|
|
481
|
+
async def modern_config_reset(request: Request):
|
|
482
|
+
"""Reset printer config from template."""
|
|
483
|
+
zp = request.app.state.zp
|
|
484
|
+
zp.replace_printer_json_from_template()
|
|
485
|
+
time.sleep(1.2)
|
|
486
|
+
return RedirectResponse(url="/config", status_code=303)
|
|
487
|
+
|
|
488
|
+
|
|
489
|
+
@router.get("/config/clear")
|
|
490
|
+
async def modern_config_clear(request: Request):
|
|
491
|
+
"""Clear the printer configuration JSON."""
|
|
492
|
+
zp = request.app.state.zp
|
|
493
|
+
zp.clear_printers_json()
|
|
494
|
+
time.sleep(1.2)
|
|
495
|
+
return RedirectResponse(url="/config", status_code=303)
|
|
496
|
+
|
|
497
|
+
|
|
498
|
+
@router.get("/config/scan", response_class=HTMLResponse)
|
|
499
|
+
async def modern_config_scan(
|
|
769
500
|
request: Request,
|
|
770
501
|
ip_stub: str = "192.168.1",
|
|
771
502
|
scan_wait: str = "0.25",
|
|
772
503
|
lab: str = "scan-results",
|
|
773
504
|
):
|
|
774
|
-
"""
|
|
505
|
+
"""Scan network for printers."""
|
|
775
506
|
zp = request.app.state.zp
|
|
776
507
|
zp.probe_zebra_printers_add_to_printers_json(
|
|
777
508
|
ip_stub=ip_stub, scan_wait=scan_wait, lab=lab
|
|
778
509
|
)
|
|
779
510
|
time.sleep(2.2)
|
|
780
|
-
return RedirectResponse(url=f"/
|
|
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."""
|
|
786
|
-
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)
|
|
817
|
-
|
|
818
|
-
|
|
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."""
|
|
822
|
-
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)
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
@router.get("/legacy/build_print_request", response_class=HTMLResponse)
|
|
834
|
-
async def legacy_build_print_request(
|
|
835
|
-
request: Request,
|
|
836
|
-
lab: str = "",
|
|
837
|
-
printer: str = "",
|
|
838
|
-
printer_ip: str = "",
|
|
839
|
-
label_zpl_style: str = "",
|
|
840
|
-
filename: str = "",
|
|
841
|
-
):
|
|
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)
|
|
511
|
+
return RedirectResponse(url=f"/printers/{lab}", status_code=303)
|
|
857
512
|
|
|
858
513
|
|
|
859
|
-
@router.get("/
|
|
860
|
-
async def
|
|
514
|
+
@router.get("/_print_label", response_class=HTMLResponse)
|
|
515
|
+
async def modern_print_label(
|
|
861
516
|
request: Request,
|
|
862
517
|
lab: Optional[str] = None,
|
|
863
518
|
printer: str = "",
|
|
@@ -872,7 +527,7 @@ async def legacy_print_label(
|
|
|
872
527
|
alt_f: str = "",
|
|
873
528
|
labSelect: str = "",
|
|
874
529
|
):
|
|
875
|
-
"""
|
|
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
|
|
@@ -912,53 +567,18 @@ async def legacy_print_label(
|
|
|
912
567
|
png_name = str(result).split("/")[-1]
|
|
913
568
|
png_url = f"/files/{png_name}"
|
|
914
569
|
|
|
915
|
-
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("
|
|
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("/
|
|
961
|
-
async def
|
|
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
|
-
"""
|
|
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 =
|
|
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("
|
|
607
|
+
return templates.TemplateResponse("modern/save_result.html", context)
|
|
988
608
|
|
|
989
609
|
|
|
990
|
-
@router.post("/
|
|
991
|
-
async def
|
|
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,7 +616,7 @@ async def legacy_png_renderer(
|
|
|
996
616
|
printer: str = Form(""),
|
|
997
617
|
ftag: str = Form(""),
|
|
998
618
|
):
|
|
999
|
-
"""
|
|
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
|
|
|
@@ -1014,38 +634,3 @@ async def legacy_png_renderer(
|
|
|
1014
634
|
content=f"files/{Path(png_tmp_f).name}",
|
|
1015
635
|
media_type="text/plain",
|
|
1016
636
|
)
|
|
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"}
|