← back to Dw Collection Banner Audit
deeper_dig.py
82 lines
#!/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)}")