← back to Mdc Onboard
chore: refactor (log handles → with-block), session close
562298a246788aac0d05a51cad919e88a2695b76 · 2026-07-26 20:21:41 -0700 · Steve Abrams
Files touched
A __pycache__/import-drafts.cpython-314.pycM import-drafts.py
Diff
commit 562298a246788aac0d05a51cad919e88a2695b76
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Sun Jul 26 20:21:41 2026 -0700
chore: refactor (log handles → with-block), session close
---
__pycache__/import-drafts.cpython-314.pyc | Bin 0 -> 14808 bytes
import-drafts.py | 79 +++++++++++++++---------------
2 files changed, 39 insertions(+), 40 deletions(-)
diff --git a/__pycache__/import-drafts.cpython-314.pyc b/__pycache__/import-drafts.cpython-314.pyc
new file mode 100644
index 0000000..10df9d3
Binary files /dev/null and b/__pycache__/import-drafts.cpython-314.pyc differ
diff --git a/import-drafts.py b/import-drafts.py
index 2972c29..7ba8f60 100644
--- a/import-drafts.py
+++ b/import-drafts.py
@@ -160,47 +160,46 @@ def main():
rows = fetch_rows()
print(f'candidates (not yet on Shopify): {len(rows)} | mode={"COMMIT" if COMMIT else "DRY-RUN"} | limit={LIMIT if LIMIT < 10**9 else "all"}', flush=True)
created = errs = skipped = 0
- leak_log = open(os.path.join(OUT, 'leak-skipped.jsonl'), 'a')
- created_log = open(os.path.join(OUT, 'created.jsonl'), 'a')
todo = rows[:LIMIT]
- for r in todo:
- title = (r['dw_title'] or '').strip()
- # ---- hard guards (task: never Wallpaper/Unknown; >=1 image; no coinage leak)
- composite = f"{title} {r['pattern_name']} {r['color_name']} {r['material']}"
- reason = None
- if not title: reason = 'empty-title'
- elif TITLE_BAN.search(title): reason = 'title-has-wallpaper-or-unknown'
- elif not (r['image_url'] or '').strip(): reason = 'no-image'
- elif HARD_LEAK.search(composite): reason = 'private-label-coinage-leak'
- if reason:
- skipped += 1
- leak_log.write(json.dumps({'dw_sku': r['dw_sku'], 'reason': reason, 'title': title}) + '\n')
- print(f' SKIP {r["dw_sku"]}: {reason}', flush=True)
- continue
-
- payload = build_payload(r)
- if not COMMIT:
- if created < 3:
- print(json.dumps(payload, indent=2)[:1400])
- created += 1
- continue
- try:
- resp = api('POST', '/products.json', payload)
- pid = resp['product']['id']
- # PostgreSQL-FIRST write-back (before anything else) — resumability contract
- psql(f"UPDATE mdc_catalog SET shopify_product_id='{pid}', on_shopify=true "
- f"WHERE id={r['id']}")
- created_log.write(json.dumps({'dw_sku': r['dw_sku'], 'pid': pid, 'title': title}) + '\n')
- created += 1
- if created % 25 == 0:
- print(f' {created}/{len(todo)} created (err {errs}, skip {skipped})', flush=True)
- time.sleep(0.55) # ~1.8/s, under Shopify REST 2/s
- except Exception as e:
- errs += 1
- detail = e.read()[:200] if isinstance(e, urllib.error.HTTPError) else str(e)
- print(f' ERR {r["dw_sku"]}: {detail}', flush=True)
- time.sleep(2)
- leak_log.close(); created_log.close()
+ with (open(os.path.join(OUT, 'leak-skipped.jsonl'), 'a') as leak_log,
+ open(os.path.join(OUT, 'created.jsonl'), 'a') as created_log):
+ for r in todo:
+ title = (r['dw_title'] or '').strip()
+ # ---- hard guards (task: never Wallpaper/Unknown; >=1 image; no coinage leak)
+ composite = f"{title} {r['pattern_name']} {r['color_name']} {r['material']}"
+ reason = None
+ if not title: reason = 'empty-title'
+ elif TITLE_BAN.search(title): reason = 'title-has-wallpaper-or-unknown'
+ elif not (r['image_url'] or '').strip(): reason = 'no-image'
+ elif HARD_LEAK.search(composite): reason = 'private-label-coinage-leak'
+ if reason:
+ skipped += 1
+ leak_log.write(json.dumps({'dw_sku': r['dw_sku'], 'reason': reason, 'title': title}) + '\n')
+ print(f' SKIP {r["dw_sku"]}: {reason}', flush=True)
+ continue
+
+ payload = build_payload(r)
+ if not COMMIT:
+ if created < 3:
+ print(json.dumps(payload, indent=2)[:1400])
+ created += 1
+ continue
+ try:
+ resp = api('POST', '/products.json', payload)
+ pid = resp['product']['id']
+ # PostgreSQL-FIRST write-back (before anything else) — resumability contract
+ psql(f"UPDATE mdc_catalog SET shopify_product_id='{pid}', on_shopify=true "
+ f"WHERE id={r['id']}")
+ created_log.write(json.dumps({'dw_sku': r['dw_sku'], 'pid': pid, 'title': title}) + '\n')
+ created += 1
+ if created % 25 == 0:
+ print(f' {created}/{len(todo)} created (err {errs}, skip {skipped})', flush=True)
+ time.sleep(0.55) # ~1.8/s, under Shopify REST 2/s
+ except Exception as e:
+ errs += 1
+ detail = e.read()[:200] if isinstance(e, urllib.error.HTTPError) else str(e)
+ print(f' ERR {r["dw_sku"]}: {detail}', flush=True)
+ time.sleep(2)
print(f'DONE mode={"COMMIT" if COMMIT else "DRY-RUN"} created={created} errors={errs} skipped={skipped}', flush=True)
← 82f3e8d Document MDC activation policy + Dublin-Vital hold + release
·
back to Mdc Onboard
·
Dublin: drop 'Vital' name per Steve — rename pattern->Dublin 0ce21d8 →