drop code128

This commit is contained in:
Piotr Oleszczyk 2025-10-02 17:01:21 +02:00
parent 377b7f1d2f
commit 37280f0345

46
app.py
View file

@ -3,14 +3,12 @@ import asyncio
from functools import lru_cache from functools import lru_cache
from typing import Optional from typing import Optional
from barcode import Code128
from barcode.writer import ImageWriter
from brother_ql.backends.helpers import send from brother_ql.backends.helpers import send
from brother_ql.conversion import convert from brother_ql.conversion import convert
from brother_ql.raster import BrotherQLRaster from brother_ql.raster import BrotherQLRaster
from fastapi import FastAPI, HTTPException from fastapi import FastAPI, HTTPException
from PIL import Image, ImageDraw, ImageFont from PIL import Image, ImageDraw, ImageFont
from pydantic import BaseModel, Field from pydantic import BaseModel, ConfigDict, Field
from pylibdmtx.pylibdmtx import encode from pylibdmtx.pylibdmtx import encode
TARGET_H = 106 TARGET_H = 106
@ -29,39 +27,13 @@ class PrintRequest(BaseModel):
product: str = Field(..., description="Product name") product: str = Field(..., description="Product name")
due_date: Optional[str] = Field(None, description="Due date from stock entry") due_date: Optional[str] = Field(None, description="Due date from stock entry")
class Config: model_config = ConfigDict(extra="ignore")
# ignore any other fields Grocy might send
extra = "ignore"
def mm_for_px(px, dpi=DPI): def mm_for_px(px, dpi=DPI):
return 25.4 * px / dpi return 25.4 * px / dpi
@lru_cache(maxsize=256)
def make_code128_exact(
grocycode: str,
xdim_px: int = 2, # narrower bars reduce overall width; ~0.25mm at 300dpi
dpi: int = DPI,
) -> Image.Image:
code = Code128(grocycode, writer=ImageWriter())
pil = code.render(
writer_options={
"write_text": False,
"dpi": dpi,
"module_height": mm_for_px(TARGET_H, dpi), # exact 106 px tall
"module_width": mm_for_px(xdim_px, dpi), # integer px/narrow bar
"quiet_zone": max(2.5, 10 * mm_for_px(xdim_px, dpi)), # generous quiet zone
}
).convert(
"L"
) # keep grayscale
# Height should already be 106 px; if writer adds 1px border, crop vertically.
if pil.height != TARGET_H:
pil = pil.resize((pil.width, TARGET_H), Image.NEAREST)
return pil
@lru_cache(maxsize=256) @lru_cache(maxsize=256)
def make_datamatrix_scaled(grocycode: str) -> Image.Image: def make_datamatrix_scaled(grocycode: str) -> Image.Image:
dm = encode(grocycode.encode("utf-8")) dm = encode(grocycode.encode("utf-8"))
@ -148,7 +120,7 @@ def _ellipsize(
def make_text_panel( def make_text_panel(
product: str, due_date: Optional[str], max_width: int = 360, padding: int = 4 product: str, due_date: Optional[str], max_width: int = 480, padding: int = 4
) -> Image.Image: ) -> Image.Image:
"""Render product (wrapped to 2 lines) + due_date in a fixed-height strip. """Render product (wrapped to 2 lines) + due_date in a fixed-height strip.
@ -294,19 +266,15 @@ def make_text_panel(
return out return out
@app.post("/print", summary="Print Code128 + DataMatrix side-by-side") @app.post("/print", summary="Print DataMatrix + text side-by-side")
async def print_from_grocy(req: PrintRequest): async def print_from_grocy(req: PrintRequest):
try: try:
loop = asyncio.get_running_loop() loop = asyncio.get_running_loop()
code_img, dm_img = await asyncio.gather( dm_img = await loop.run_in_executor(None, make_datamatrix_scaled, req.grocycode)
# use default x-dimension and DPI; only pass the payload
loop.run_in_executor(None, make_code128_exact, req.grocycode),
loop.run_in_executor(None, make_datamatrix_scaled, req.grocycode),
)
# Render a compact text panel; width-capped to keep label length reasonable # Render a compact text panel; width-capped to keep label length reasonable
text_panel = make_text_panel(req.product, req.due_date, max_width=360) text_panel = make_text_panel(req.product, req.due_date, max_width=360)
# compose expects a list of images # compose expects a list of images
label_img = compose_row([code_img, dm_img, text_panel], spacing=12) label_img = compose_row([dm_img, text_panel], spacing=12)
send_to_printer(label_img, req.printer_ip, req.model, req.label) send_to_printer(label_img, req.printer_ip, req.model, req.label)
except Exception: except Exception:
# optionally: log e with traceback and return a generic message # optionally: log e with traceback and return a generic message
@ -315,5 +283,5 @@ async def print_from_grocy(req: PrintRequest):
"status": "printed", "status": "printed",
"model": req.model, "model": req.model,
"label": req.label, "label": req.label,
"layout": "code128 | datamatrix | text", "layout": "datamatrix | text",
} }