← back to Dw Photo Capture
create_22_new.py
57 lines
#!/usr/bin/env python3
"""Bulk-create the net-new GRS sheet items as DRAFT Shopify products with full info
(no image yet — they go live once photographed). DRY default; CONFIRM=1 writes."""
import os,sys,json,re,time,urllib.request
SHOP="designer-laboratory-sandbox.myshopify.com";API="2024-10";DRY=os.environ.get("CONFIRM","0")!="1"
TOKEN=""
for l in open(os.path.expanduser("~/Projects/secrets-manager/.env")):
if l.startswith("SHOPIFY_ADMIN_TOKEN="): TOKEN=l.strip().split("=",1)[1];break
H={"X-Shopify-Access-Token":TOKEN,"Content-Type":"application/json"}
def api(m,p,pl=None):
d=json.dumps(pl).encode() if pl is not None else None
r=urllib.request.Request(f"https://{SHOP}/admin/api/{API}"+p,data=d,headers=H,method=m)
with urllib.request.urlopen(r,timeout=60) as x: b=x.read().decode();return x.status,(json.loads(b) if b.strip() else {})
SHEET={x["grs"].upper():x for x in json.load(open(os.path.expanduser("~/Projects/dw-photo-capture/data/sheet_grs.json")))}
# the net-new list straight from the app
import urllib.request as u, base64
req=u.Request("http://127.0.0.1:9890/api/new",headers={"Authorization":"Basic "+base64.b64encode(b"admin:DW2024!").decode()})
NEW=json.loads(u.urlopen(req,timeout=20).read())["items"]
def title(s):
name=(s.get("name") or "").strip(); color=(s.get("color") or "").strip()
nl,cl=name.lower(),color.lower()
col=(" "+color) if (color and nl!=cl and cl not in nl and nl not in cl) else ""
if name: return f"{name}{col} Grasscloth Wallcovering | Fentucci"
if s.get("material"): return f"Fentucci {s['material']} Grasscloth Wallcovering"+((" — "+color) if color else "")
return "Fentucci Grasscloth Wallcovering"+((" — "+color) if color else "")
def body(s):
lead=s.get("name") or (("Fentucci "+s["material"]+" grasscloth") if s.get("material") else "This Fentucci grasscloth")
de=(s.get("desc") or "").strip()
if de and de.lower().startswith("is "): return f"{lead} {de}"
return de or f"{lead} is a natural woven grasscloth wallcovering with handcrafted natural-fiber texture."
def mf(ns,k,v): return {"namespace":ns,"key":k,"value":str(v),"type":"single_line_text_field"} if v else None
print(f"{len(NEW)} net-new to create as DRAFT (full info, no image)")
created=0
for it in NEW:
s=SHEET.get(it["dw_sku"].upper())
if not s: print(f" skip {it['dw_sku']} (no sheet row)"); continue
grs=s["grs"]; price=s.get("price"); col=(s.get("color") or "").strip()
tags=["Grasscloth","Natural Wallcovering","Fentucci","TWIL Naturals","display_variant","Needs-Image"]+([f"color:{col}"] if col else [])+([] if price else ["Needs-Cost"])
roll={"option1":"Roll","sku":grs,"inventory_management":"shopify","inventory_quantity":2026}
if price: roll["price"]=str(price)
payload={"product":{"title":title(s),"body_html":body(s),"vendor":"Fentucci","product_type":"Wallcovering",
"status":"draft","published_scope":"global","tags":", ".join(tags),"options":[{"name":"Size"}],
"variants":[roll,{"option1":"Sample","sku":grs+"-Sample","price":"4.25","inventory_management":"shopify","inventory_quantity":2026}],
"metafields":[x for x in [mf("global","width",s.get("width") or "36 Inches"),mf("global","length",s.get("length") or "8 Yards"),
mf("global","unit_of_measure","Priced Per Single Roll"),mf("global","Content","Natural Grasscloth"),
mf("global","Brand","Fentucci"),mf("global","Collection","TWIL Naturals"),mf("global","Color-Way",col),mf("custom","color",col),
mf("custom","manufacturer_sku",s.get("mfr")),mf("dwc","manufacturer_sku",s.get("mfr")),
mf("custom","pattern_name",s.get("name")),mf("dwc","pattern_name",s.get("name"))] if x]}}
if DRY: print(f" [dry] {grs:12} {('$'+str(price)) if price else 'no-price':9} {title(s)[:46]}"); continue
try:
st,r=api("POST","/products.json",payload); created+=1
print(f" created {grs} -> {r.get('product',{}).get('id')} (draft)"); time.sleep(0.5)
except Exception as e:
bd=getattr(e,'read',lambda:b'')() if hasattr(e,'read') else b''; print(f" ERR {grs}: {e} {bd[:140]}")
if DRY: print(f"\n[DRY] would create {len(NEW)} drafts. CONFIRM=1 to create.")
else: print(f"\nDONE — created {created} draft products (Needs-Image; photograph to go live).")