← back to Dw Collection Banner Audit
auto-save: 2026-07-30T10:16:54 (1 files) — deeper_dig.py
b0b46f52fe6c5d8fb0966e2379c067245bc21cba · 2026-07-30 10:17:00 -0700 · Steve Abrams
Files touched
Diff
commit b0b46f52fe6c5d8fb0966e2379c067245bc21cba
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Thu Jul 30 10:17:00 2026 -0700
auto-save: 2026-07-30T10:16:54 (1 files) — deeper_dig.py
---
deeper_dig.py | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 81 insertions(+)
diff --git a/deeper_dig.py b/deeper_dig.py
new file mode 100644
index 0000000..d4cc937
--- /dev/null
+++ b/deeper_dig.py
@@ -0,0 +1,81 @@
+#!/usr/bin/env python3
+"""
+Deeper image dig + room-render for the 9 collections that failed 'no product image'.
+Paginates products.json across pages with heavy pacing (403-safe), collects ALL
+images, picks the largest non-logo photo, generates a 16:9 room-render.
+Generated PNGs land in room_renders/ (then land_renders.py uploads by handle).
+"""
+import json, os, base64, time, urllib.request
+
+HERE = os.path.dirname(os.path.abspath(__file__))
+GKEY = os.environ["GEMINI_API_KEY"]
+STORE = "designer-laboratory-sandbox.myshopify.com"
+UA = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)"
+OUT = os.path.join(HERE, "room_renders"); os.makedirs(OUT, exist_ok=True)
+MODEL = "gemini-2.5-flash-image"
+ROOMS = ["an elegant modern living room", "a refined dining room", "a luxe bedroom feature wall"]
+
+FAILS = ["benu-recycled","collezione-italia","hermes","hinson","nlxl",
+ "paul-montgomery-all-products","paul-montgomery-murals","phillip-jeffries",
+ "phillipe-romano-faux-leathers-upholstery-more"]
+
+def deep_image(handle):
+ allimgs = []
+ for page in range(1, 4): # up to 3 pages, heavily paced
+ url = f"https://{STORE}/collections/{handle}/products.json?limit=50&page={page}"
+ prods = None
+ for attempt in range(5):
+ try:
+ prods = json.load(urllib.request.urlopen(urllib.request.Request(url, headers={"User-Agent": UA}), timeout=25)).get("products", [])
+ break
+ except urllib.error.HTTPError as e:
+ if e.code in (403, 429): time.sleep(3.0*(attempt+1)); continue
+ prods = []; break
+ except Exception:
+ time.sleep(2.0)
+ if not prods: break
+ for p in prods:
+ for im in p.get("images", []):
+ s = im.get("src",""); w = im.get("width") or 0; h = im.get("height") or 0
+ if "logo" in s.lower(): continue
+ allimgs.append((w*h, w, h, s))
+ time.sleep(2.5)
+ if len(prods) < 50: break
+ if not allimgs: return None
+ allimgs.sort(reverse=True)
+ return allimgs[0][3] # largest by area
+
+def gen(handle, src, idx):
+ b = urllib.request.urlopen(urllib.request.Request(src, headers={"User-Agent": UA}), timeout=30).read()
+ b64 = base64.b64encode(b).decode()
+ mime = "image/png" if src.lower().split("?")[0].endswith(".png") else "image/jpeg"
+ room = ROOMS[idx % len(ROOMS)]
+ prompt = (f"Photorealistic interior photograph: the wallcovering pattern shown in the reference image "
+ f"installed on the main wall of {room}. Elegant luxury interior, natural lighting, tasteful "
+ f"furniture, magazine-quality, wide landscape banner composition. The pattern must match the "
+ f"reference exactly. No text, no watermark.")
+ body = json.dumps({"contents": [{"parts": [{"text": prompt}, {"inline_data": {"mime_type": mime, "data": b64}}]}],
+ "generationConfig": {"imageConfig": {"aspectRatio": "16:9"}}}).encode()
+ url = f"https://generativelanguage.googleapis.com/v1beta/models/{MODEL}:generateContent?key={GKEY}"
+ res = json.load(urllib.request.urlopen(urllib.request.Request(url, data=body, headers={"Content-Type": "application/json"}), timeout=120))
+ for part in res["candidates"][0]["content"]["parts"]:
+ d = part.get("inline_data") or part.get("inlineData")
+ if d:
+ out = os.path.join(OUT, f"{handle}.png"); open(out, "wb").write(base64.b64decode(d["data"])); return out
+ return None
+
+results = []
+for i, h in enumerate(FAILS):
+ src = deep_image(h)
+ if not src:
+ print(f" STILL-NO-IMAGE {h}"); results.append({"handle": h, "ok": False}); continue
+ try:
+ out = gen(h, src, i)
+ print(f" OK {h} -> render (from {src.rsplit('/',1)[-1][:36]})")
+ results.append({"handle": h, "ok": bool(out), "src": src})
+ except Exception as e:
+ print(f" GEN-FAIL {h}: {str(e)[:90]}"); results.append({"handle": h, "ok": False})
+ time.sleep(1.5)
+json.dump(results, open(os.path.join(HERE, "deeper_dig.json"), "w"), indent=1)
+ok = [r["handle"] for r in results if r["ok"]]
+print(f"\ndeeper-dig rendered {len(ok)}/9: {' '.join(ok)}")
← 0917475 landed 29 room-render banners live (custom+smart), 29/29 ok,
·
back to Dw Collection Banner Audit
·
deeper-dig: rendered + landed phillip-jeffries banner; 8 log 72329b9 →