← back to Kravet Sheet Sync 2026 04 20

attach_images.py

95 lines

#!/usr/bin/env python3
"""
Build Kravet image URLs from sheet filenames and attach to the 2 test products.
URL pattern: https://www.kravet.com/media/catalog/product + {sheet.image_file_hires}
"""
import json, subprocess, urllib.request, urllib.error

TOKEN = os.environ.get('SHOPIFY_ADMIN_TOKEN','')
URL   = 'https://designer-laboratory-sandbox.myshopify.com/admin/api/2024-10/graphql.json'
KRAVET_BASE = 'https://www.kravet.com/media/catalog/product'

TARGETS = [
    {"pid": "gid://shopify/Product/7821427441715",
     "dw_sku": "DWKK-141031", "mfr_sku": "109/11053.CS.0"},
    {"pid": "gid://shopify/Product/7821427474483",
     "dw_sku": "DWKK-141042", "mfr_sku": "94/4021.CS.0"},
]


def pg_rows(q):
    r = subprocess.run(["ssh","root@45.61.58.125",
        f'PGPASSWORD=DW2024! psql -h 127.0.0.1 -U dw_admin -d dw_unified -At -F "|" -c "{q}"'],
        capture_output=True, text=True, check=True)
    return [line.split("|") for line in r.stdout.strip().split("\n") if line]


def gql(q, v=None):
    body = json.dumps({"query": q, "variables": v or {}}).encode()
    req = urllib.request.Request(URL, data=body, method="POST",
           headers={"Content-Type":"application/json","X-Shopify-Access-Token":TOKEN})
    d = json.loads(urllib.request.urlopen(req, timeout=30).read())
    if "errors" in d: raise RuntimeError(d["errors"])
    return d["data"]


def probe(url: str) -> int:
    try:
        req = urllib.request.Request(url, headers={"User-Agent":"Mozilla/5.0"}, method="HEAD")
        return urllib.request.urlopen(req, timeout=10).status
    except urllib.error.HTTPError as e:
        return e.code
    except Exception:
        return 0


CREATE_MEDIA = """
mutation productCreateMedia($productId: ID!, $media: [CreateMediaInput!]!) {
  productCreateMedia(productId: $productId, media: $media) {
    media { ... on MediaImage { id status image { url } } }
    mediaUserErrors { field message }
  }
}
"""


for t in TARGETS:
    # Fetch sheet image filenames
    esc = t["mfr_sku"].replace("'", "''")
    rows = pg_rows(f"SELECT image_file_hires, image_file_lores FROM kravet_sheet_fields "
                   f"WHERE mfr_sku_raw = '{esc}'")
    if not rows:
        print(f"{t['dw_sku']}: no sheet row for {t['mfr_sku']}"); continue
    hires, lores = rows[0]

    hires_url = KRAVET_BASE + hires if hires else ""
    lores_url = KRAVET_BASE + lores if lores else ""

    print(f"\n=== {t['dw_sku']} ({t['mfr_sku']}) ===")
    for label, u in [("HIRES", hires_url), ("LORES", lores_url)]:
        if u:
            print(f"  {label} {probe(u)} {u}")

    # Attach HIRES as primary (Shopify fetches async)
    if not hires_url: continue
    data = gql(CREATE_MEDIA, {
        "productId": t["pid"],
        "media": [{
            "originalSource": hires_url,
            "mediaContentType": "IMAGE",
            "alt": f"{t['mfr_sku']} — Kravet manufacturer image",
        }],
    })
    errs = data["productCreateMedia"]["mediaUserErrors"]
    if errs:
        print(f"  ERROR: {errs}")
    else:
        m = data["productCreateMedia"]["media"][0]
        print(f"  attached: {m['id']} status={m['status']}")

    # Persist to kravet_catalog.image_url
    esc_sku = t["dw_sku"].replace("'", "''")
    pg_rows(f"UPDATE kravet_catalog SET image_url = '{hires_url}' "
            f"WHERE dw_sku = '{esc_sku}'")
    print(f"  pg: kravet_catalog.image_url set")