[object Object]

← back to Wallco Ai

Add rollback-photoreal-rooms.py: regenerate living_room mockups via :3075 service, explicit served-dir output, no PG dependency

d335cbc066414941efb8cc58a78f8948a02d6f4b · 2026-05-29 08:35:36 -0700 · Steve

Files touched

Diff

commit d335cbc066414941efb8cc58a78f8948a02d6f4b
Author: Steve <steve@designerwallcoverings.com>
Date:   Fri May 29 08:35:36 2026 -0700

    Add rollback-photoreal-rooms.py: regenerate living_room mockups via :3075 service, explicit served-dir output, no PG dependency
---
 scripts/rollback-photoreal-rooms.py | 59 +++++++++++++++++++++++++++++++++++++
 1 file changed, 59 insertions(+)

diff --git a/scripts/rollback-photoreal-rooms.py b/scripts/rollback-photoreal-rooms.py
new file mode 100644
index 0000000..421cfe2
--- /dev/null
+++ b/scripts/rollback-photoreal-rooms.py
@@ -0,0 +1,59 @@
+#!/usr/bin/env python3
+"""Regenerate photoreal living_room mockups via the :3075 room service.
+Writes EXPLICITLY to the served dir (data/rooms), resolves source from
+designs.json filename -> data/generated/<filename>. No PG dependency.
+Usage: rollback-photoreal-rooms.py --ids 4569[,4570,...]  |  --file /tmp/ids.txt
+"""
+import base64, json, os, sys, time, argparse, urllib.request, urllib.error
+ROOT=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))  # the served project dir
+IMG_DIR=os.path.join(ROOT,'data','generated')
+ROOMS_DIR=os.path.join(ROOT,'data','rooms')
+ROOM_API='http://127.0.0.1:3075/api/generate-room'
+D={x['id']:x for x in json.load(open(os.path.join(ROOT,'data','designs.json')))}
+
+def render(design_id, src_path):
+    b64=base64.b64encode(open(src_path,'rb').read()).decode()
+    body=json.dumps({'patternBase64':b64,'roomType':'living_room','angle':'straight_on',
+                     'cameraDistance':5,'patternWidth':27,'patternHeight':27}).encode()
+    req=urllib.request.Request(ROOM_API,data=body,headers={'Content-Type':'application/json'})
+    with urllib.request.urlopen(req,timeout=180) as r:
+        resp=json.loads(r.read())
+    img=resp.get('image') or resp.get('imageBase64') or ''
+    if not img:
+        return None, f'no-image keys={list(resp.keys())} success={resp.get("success")}'
+    if img.startswith('data:'): img=img.split(',',1)[1]
+    out=os.path.join(ROOMS_DIR,f'design_{design_id}_living_room.png')
+    tmp=out+'.tmp'
+    if img.startswith('http'):
+        with urllib.request.urlopen(img,timeout=60) as r2: open(tmp,'wb').write(r2.read())
+    else:
+        open(tmp,'wb').write(base64.b64decode(img))
+    sz=os.path.getsize(tmp)
+    if sz<50000:  # sanity: photoreal should be >>50KB
+        os.remove(tmp); return None, f'too-small {sz}b'
+    os.replace(tmp,out)
+    return sz, 'ok'
+
+def main():
+    ap=argparse.ArgumentParser()
+    ap.add_argument('--ids'); ap.add_argument('--file')
+    a=ap.parse_args()
+    ids=[]
+    if a.ids: ids=[int(x) for x in a.ids.split(',') if x.strip()]
+    if a.file: ids+=[int(l) for l in open(a.file) if l.strip().isdigit()]
+    ok=err=0
+    for i,did in enumerate(ids,1):
+        x=D.get(did)
+        if not x: print(f'[{i}/{len(ids)}] #{did} SKIP not-in-designs.json'); err+=1; continue
+        src=os.path.join(IMG_DIR,x.get('filename') or '')
+        if not os.path.exists(src): print(f'[{i}/{len(ids)}] #{did} SKIP no-src {x.get("filename")}'); err+=1; continue
+        t0=time.time()
+        try:
+            sz,msg=render(did,src)
+        except Exception as e:
+            sz=None; msg=str(e)[:120]
+        if sz: print(f'[{i}/{len(ids)}] #{did} OK {sz//1024}KB {time.time()-t0:.1f}s'); ok+=1
+        else: print(f'[{i}/{len(ids)}] #{did} FAIL {msg}'); err+=1
+    print(f'[done] ok={ok} err={err}')
+
+if __name__=='__main__': main()

← 431fbf5 haiku 4.5 weekend defect-scan test scripts + monday summary  ·  back to Wallco Ai  ·  haiku weekend test: yolo-queue runner (max-plan path) + SQL 875105c →