100 lines
4.1 KiB
Python
100 lines
4.1 KiB
Python
"""The heat map and the weld map of one drawing page, as a JPEG at the sheet's own size (the old renderMapCanvas)."""
|
|||
|
|
|
||
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
from collections.abc import Mapping
|
||
|
|
from pathlib import Path
|
||
|
|
from typing import Any
|
||
|
|
|
||
|
|
from ..domain import assets
|
||
|
|
from . import raster
|
||
|
|
from .style import fmt_d, site_tz
|
||
|
|
|
||
|
|
|
||
|
|
def asset_file(conn: Any, settings: Any, asset_id: Any) -> tuple[dict[str, Any], Path]:
|
||
|
|
"""The assets row and its stored file. Raises when the row or the file is missing."""
|
||
|
|
row = assets.get(conn, asset_id) if asset_id else None
|
||
|
|
if row is None:
|
||
|
|
raise FileNotFoundError("The file is not in the asset store.")
|
||
|
|
return row, assets.open_blob(settings, row)
|
||
|
|
|
||
|
|
|
||
|
|
def page_file(conn: Any, settings: Any, page: Mapping[str, Any]) -> tuple[Path, int]:
|
||
|
|
"""The stored PDF of a packet page and the page number inside it."""
|
||
|
|
_row, path = asset_file(conn, settings, page.get("asset_id"))
|
||
|
|
return path, int(page.get("pn") or 1)
|
||
|
|
|
||
|
|
|
||
|
|
def void_text(page: Mapping[str, Any], tz: str | None = None) -> str:
|
||
|
|
"""VOID - superseded by CO-2 (dwg Rev B) 10/16/2026. Empty for a live page (the old voidText)."""
|
||
|
|
v = page.get("void")
|
||
|
|
if not v:
|
||
|
|
return ""
|
||
|
|
co = f"CO-{v['co_no']}" if v.get("co_no") is not None else "a change order"
|
||
|
|
new = v.get("new")
|
||
|
|
sheet = f" ({new.get('dwg') or 'new sheet'} Rev {new.get('rev') or '?'})" if new else ""
|
||
|
|
day = fmt_d(v.get("at"), tz, empty="")
|
||
|
|
return f"VOID - superseded by {co}{sheet}" + (f" {day}" if day else "")
|
||
|
|
|
||
|
|
|
||
|
|
def heat_placement(packet: Mapping[str, Any], page_n: int) -> Mapping[str, Any] | None:
|
||
|
|
"""The heat table placed on a page, or None."""
|
||
|
|
for h in packet.get("heat_table") or []:
|
||
|
|
if h.get("page") == page_n and h.get("x") is not None:
|
||
|
|
return h
|
||
|
|
return None
|
||
|
|
|
||
|
|
|
||
|
|
def legacy_tags(packet: Mapping[str, Any], page_n: int) -> list[Mapping[str, Any]]:
|
||
|
|
"""The older heat tags of a page. They show only while no table is placed on it."""
|
||
|
|
if heat_placement(packet, page_n) is not None:
|
||
|
|
return []
|
||
|
|
return [t for t in packet.get("heat_tags") or [] if t.get("page") == page_n]
|
||
|
|
|
||
|
|
|
||
|
|
def page_welds(packet: Mapping[str, Any], page_n: int) -> list[Mapping[str, Any]]:
|
||
|
|
return [w for w in packet.get("welds") or [] if w.get("page") == page_n]
|
||
|
|
|
||
|
|
|
||
|
|
def _render(conn: Any, settings: Any, page: Mapping[str, Any]) -> tuple[Any, float, float]:
|
||
|
|
path, pn = page_file(conn, settings, page)
|
||
|
|
return raster.render_page(path, pn)
|
||
|
|
|
||
|
|
|
||
|
|
def heat_map_page(
|
||
|
|
conn: Any, settings: Any, packet: Mapping[str, Any], page: Mapping[str, Any]
|
||
|
|
) -> tuple[bytes, float, float]:
|
||
|
|
"""The sheet with its heat table (or its older heat tags when no table is placed), VOID when the page is void.
|
||
|
|
Returns (jpeg bytes, width pt, height pt)."""
|
||
|
|
img, w, h = _render(conn, settings, page)
|
||
|
|
n = int(page["n"])
|
||
|
|
bom = packet.get("bom") or []
|
||
|
|
placement = heat_placement(packet, n)
|
||
|
|
if placement is not None:
|
||
|
|
raster.draw_heat_table(img, placement, raster.heat_rows(bom))
|
||
|
|
else:
|
||
|
|
raster.draw_heat_tags(img, packet.get("heat_tags") or [], bom, n)
|
||
|
|
if page.get("void"):
|
||
|
|
img = raster.stamp_void(img, void_text(page, site_tz(settings)))
|
||
|
|
return raster.to_jpeg(img), w, h
|
||
|
|
|
||
|
|
|
||
|
|
def weld_map_page(
|
||
|
|
conn: Any, settings: Any, packet: Mapping[str, Any], page: Mapping[str, Any]
|
||
|
|
) -> tuple[bytes, float, float]:
|
||
|
|
"""The sheet with its weld bubbles, VOID when the page is void. Returns (jpeg bytes, width pt, height pt)."""
|
||
|
|
img, w, h = _render(conn, settings, page)
|
||
|
|
raster.draw_weld_marks(img, packet.get("welds") or [], int(page["n"]))
|
||
|
|
if page.get("void"):
|
||
|
|
img = raster.stamp_void(img, void_text(page, site_tz(settings)))
|
||
|
|
return raster.to_jpeg(img), w, h
|
||
|
|
|
||
|
|
|
||
|
|
def clean_page(conn: Any, settings: Any, page: Mapping[str, Any]) -> tuple[bytes, float, float]:
|
||
|
|
"""The sheet with no marks (VOID when void), as a raster. Prints copy the vector page instead; this is for a
|
||
|
|
page whose PDF cannot be copied."""
|
||
|
|
img, w, h = _render(conn, settings, page)
|
||
|
|
if page.get("void"):
|
||
|
|
img = raster.stamp_void(img, void_text(page, site_tz(settings)))
|
||
|
|
return raster.to_jpeg(img), w, h
|