[object Object]

← 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 →