← back to Wallco Ai
render-live-rooms.py: PIL rooms for prod-only designs (pull tile from live /designs/img/by-id, composite); fixed 60 la-toile PDPs (57524-57587) that shipped with no room mockups
a0b6407f8991fb5426e4e92f025bcbeab669efb4 · 2026-06-03 13:57:19 -0700 · Steve Abrams
Files touched
A scripts/render-live-rooms.py
Diff
commit a0b6407f8991fb5426e4e92f025bcbeab669efb4
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Wed Jun 3 13:57:19 2026 -0700
render-live-rooms.py: PIL rooms for prod-only designs (pull tile from live /designs/img/by-id, composite); fixed 60 la-toile PDPs (57524-57587) that shipped with no room mockups
---
scripts/render-live-rooms.py | 72 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 72 insertions(+)
diff --git a/scripts/render-live-rooms.py b/scripts/render-live-rooms.py
new file mode 100644
index 0000000..fdd0a07
--- /dev/null
+++ b/scripts/render-live-rooms.py
@@ -0,0 +1,72 @@
+#!/usr/bin/env python3
+# Render free-local PIL room mockups for designs that live ONLY on prod (not in the
+# local DB / designs.json). Pulls each tile from the live /designs/img/by-id/<id>
+# route, then composites it with the SAME internals as pil-room-composite.py
+# (BASE_TEMPLATE + WALL_QUAD perspective warp). Writes data/rooms/design_<id>_living_room.png.
+# Usage: python3 scripts/render-live-rooms.py <id> [<id> ...]
+# python3 scripts/render-live-rooms.py --ids-file /tmp/ids.txt
+import sys, os, importlib.util, urllib.request, tempfile
+from pathlib import Path
+from PIL import Image, ImageEnhance, ImageDraw
+
+ROOT = Path(__file__).resolve().parent.parent
+BASE = "https://wallco.ai"
+
+# Import the hyphenated module to reuse its constants + helpers (no duplication).
+spec = importlib.util.spec_from_file_location("prc", ROOT / "scripts" / "pil-room-composite.py")
+prc = importlib.util.module_from_spec(spec)
+spec.loader.exec_module(prc)
+
+ROOMS_DIR = prc.ROOMS_DIR
+ROOMS_DIR.mkdir(parents=True, exist_ok=True)
+
+def fetch_tile(design_id: int) -> Image.Image:
+ url = f"{BASE}/designs/img/by-id/{design_id}"
+ req = urllib.request.Request(url, headers={"User-Agent": "wallco-room-render"})
+ with urllib.request.urlopen(req, timeout=30) as r:
+ if r.status != 200:
+ raise RuntimeError(f"http {r.status}")
+ data = r.read()
+ tf = tempfile.NamedTemporaryFile(suffix=".png", delete=False)
+ tf.write(data); tf.close()
+ return Image.open(tf.name).convert("RGB")
+
+def composite(design_id: int) -> Path:
+ out_path = ROOMS_DIR / f"design_{design_id}_living_room.png"
+ base = Image.open(prc.BASE_TEMPLATE).convert("RGB")
+ pat = fetch_tile(design_id)
+ wall_w = max(p[0] for p in prc.WALL_QUAD) - min(p[0] for p in prc.WALL_QUAD)
+ wall_h = max(p[1] for p in prc.WALL_QUAD) - min(p[1] for p in prc.WALL_QUAD)
+ tiled = prc.tile_pattern(pat, wall_w, wall_h, repeats_x=4, repeats_y=3)
+ src_pts = [(0, 0), (wall_w, 0), (wall_w, wall_h), (0, wall_h)]
+ coeffs = prc.perspective_coeffs(src_pts, prc.WALL_QUAD)
+ warped = tiled.transform(base.size, Image.PERSPECTIVE, coeffs, Image.BICUBIC)
+ mask = Image.new("L", base.size, 0)
+ ImageDraw.Draw(mask).polygon(prc.WALL_QUAD, fill=255)
+ if prc.WALL_BLEND != 1.0:
+ warped = ImageEnhance.Brightness(warped).enhance(prc.WALL_BLEND)
+ out = base.copy()
+ out.paste(warped, (0, 0), mask)
+ out.save(out_path, "PNG", optimize=True)
+ return out_path
+
+def main():
+ args = sys.argv[1:]
+ ids = []
+ if args and args[0] == "--ids-file":
+ ids = [int(x) for x in Path(args[1]).read_text().split()]
+ else:
+ ids = [int(x) for x in args]
+ ok, fail = 0, 0
+ for i, did in enumerate(ids):
+ try:
+ p = composite(did)
+ ok += 1
+ print(f"[{i+1}/{len(ids)}] #{did} -> {p.name}")
+ except Exception as e:
+ fail += 1
+ print(f"[{i+1}/{len(ids)}] #{did} FAIL {e}")
+ print(f"\nrendered {ok}/{len(ids)} ({fail} failed)")
+
+if __name__ == "__main__":
+ main()
← 1096024 build-mural-master: fix SDXL outpaint — UA + files-API uploa
·
back to Wallco Ai
·
backfill-rooms: idempotent free-local PIL room backfill for 9952d41 →