← back to Sidmouth Material Fix
Fix Momentum acoustic material vinyl->100% recycled polyester on 28 SKUs (Corsham/Crosby/Otterton/Yettington spec-confirmed + Cesare)
9b05509a0d58e82aeba9178d41d75a71725c77fa · 2026-07-12 10:59:49 -0700 · Steve
Verified from Momentum spec sheets (Currents/Cluster/Nufelt = 100% recycled polyester).
custom.material corrected on 13 ACTIVE + 15 DRAFT; rollback_targets_polyester.json snapshots prior values.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Files touched
A fix_generic.pyA nufelt.pdfA rollback_targets_polyester.jsonA silence_spec.pdfA targets_polyester.tsv
Diff
commit 9b05509a0d58e82aeba9178d41d75a71725c77fa
Author: Steve <steve@designerwallcoverings.com>
Date: Sun Jul 12 10:59:49 2026 -0700
Fix Momentum acoustic material vinyl->100% recycled polyester on 28 SKUs (Corsham/Crosby/Otterton/Yettington spec-confirmed + Cesare)
Verified from Momentum spec sheets (Currents/Cluster/Nufelt = 100% recycled polyester).
custom.material corrected on 13 ACTIVE + 15 DRAFT; rollback_targets_polyester.json snapshots prior values.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
fix_generic.py | 52 ++++++++++++
nufelt.pdf | Bin 0 -> 10772147 bytes
rollback_targets_polyester.json | 170 ++++++++++++++++++++++++++++++++++++++++
silence_spec.pdf | Bin 0 -> 155130 bytes
targets_polyester.tsv | 28 +++++++
5 files changed, 250 insertions(+)
diff --git a/fix_generic.py b/fix_generic.py
new file mode 100644
index 0000000..bd71b51
--- /dev/null
+++ b/fix_generic.py
@@ -0,0 +1,52 @@
+#!/usr/bin/env python3
+"""Generic custom.material fixer. Usage:
+ python3 fix_generic.py <targets.tsv> "<NEW VALUE>" [--apply]
+targets.tsv rows: pid|sku|status|pattern (only first two cols used)
+Snapshots prior values to rollback_<targets>.json. DRY-RUN unless --apply.
+"""
+import json, sys, time, urllib.request, urllib.error, pathlib
+ROOT = pathlib.Path(__file__).parent
+TOKEN = (ROOT/".token").read_text().strip()
+STORE = (ROOT/".store").read_text().strip()
+API = "2024-10"
+TARGETS_FILE = sys.argv[1]
+NEW_VALUE = sys.argv[2]
+APPLY = "--apply" in sys.argv
+
+def req(method, path, body=None):
+ url = f"https://{STORE}/admin/api/{API}/{path}"
+ data = json.dumps(body).encode() if body else None
+ r = urllib.request.Request(url, data=data, method=method,
+ headers={"X-Shopify-Access-Token": TOKEN, "Content-Type": "application/json"})
+ with urllib.request.urlopen(r) as resp:
+ return json.loads(resp.read() or "{}")
+
+rows = [l.split("|") for l in (ROOT/TARGETS_FILE).read_text().splitlines() if l.strip()]
+snapshot, results = [], []
+print(f"{'APPLY' if APPLY else 'DRY-RUN'} — {len(rows)} products -> Material {NEW_VALUE!r}\n")
+for r in rows:
+ pid, sku = r[0], r[1]
+ try:
+ mfs = req("GET", f"products/{pid}/metafields.json").get("metafields", [])
+ except urllib.error.HTTPError as e:
+ print(f" {sku:22} GET FAIL {e.code}"); results.append("get_fail"); continue
+ mat = next((m for m in mfs if m["namespace"]=="custom" and m["key"]=="material"), None)
+ old = mat["value"] if mat else None
+ snapshot.append({"pid":pid,"sku":sku,"metafield_id":mat["id"] if mat else None,"old_value":old})
+ if not APPLY:
+ print(f" {sku:22} was {old!r}"); results.append("dry"); continue
+ try:
+ if mat:
+ req("PUT", f"metafields/{mat['id']}.json",
+ {"metafield":{"id":mat["id"],"value":NEW_VALUE,"type":mat.get("type","multi_line_text_field")}})
+ else:
+ req("POST", f"products/{pid}/metafields.json",
+ {"metafield":{"namespace":"custom","key":"material","value":NEW_VALUE,"type":"multi_line_text_field"}})
+ print(f" {sku:22} {old!r} -> {NEW_VALUE!r} ✓"); results.append("written")
+ except urllib.error.HTTPError as e:
+ print(f" {sku:22} PUT FAIL {e.code} {e.read()[:120]}"); results.append("put_fail")
+ time.sleep(0.55)
+rb = ROOT/f"rollback_{pathlib.Path(TARGETS_FILE).stem}.json"
+rb.write_text(json.dumps(snapshot, indent=2))
+from collections import Counter
+print(f"\nSnapshot -> {rb.name}. Summary:", dict(Counter(results)))
diff --git a/nufelt.pdf b/nufelt.pdf
new file mode 100644
index 0000000..e968cf4
Binary files /dev/null and b/nufelt.pdf differ
diff --git a/rollback_targets_polyester.json b/rollback_targets_polyester.json
new file mode 100644
index 0000000..67c166e
--- /dev/null
+++ b/rollback_targets_polyester.json
@@ -0,0 +1,170 @@
+[
+ {
+ "pid": "1497935478896",
+ "sku": "ACT-73254-sample",
+ "metafield_id": 34794836525107,
+ "old_value": "100% recycled polyester"
+ },
+ {
+ "pid": "1497935642736",
+ "sku": "ACT-73255",
+ "metafield_id": 34795171971123,
+ "old_value": "100% recycled polyester"
+ },
+ {
+ "pid": "1497935806576",
+ "sku": "ACT-73256",
+ "metafield_id": 34798759018547,
+ "old_value": "100% recycled polyester"
+ },
+ {
+ "pid": "1497935970416",
+ "sku": "ACT-73257-sample",
+ "metafield_id": 34794822860851,
+ "old_value": "100% recycled polyester"
+ },
+ {
+ "pid": "1497936167024",
+ "sku": "ACT-73258-sample",
+ "metafield_id": 34800588881971,
+ "old_value": "100% recycled polyester"
+ },
+ {
+ "pid": "1497936494704",
+ "sku": "ACT-73260",
+ "metafield_id": 34798759477299,
+ "old_value": "100% recycled polyester"
+ },
+ {
+ "pid": "1497936658544",
+ "sku": "ACT-73261",
+ "metafield_id": 34795413798963,
+ "old_value": "100% recycled polyester"
+ },
+ {
+ "pid": "1497936855152",
+ "sku": "ACT-73262-sample",
+ "metafield_id": 34795055349811,
+ "old_value": "100% recycled polyester"
+ },
+ {
+ "pid": "1497937018992",
+ "sku": "ACT-73263-sample",
+ "metafield_id": 34795178688563,
+ "old_value": "100% recycled polyester"
+ },
+ {
+ "pid": "1497935282288",
+ "sku": "XVY-73252",
+ "metafield_id": 34725664325683,
+ "old_value": "100% recycled polyester"
+ },
+ {
+ "pid": "1498965704816",
+ "sku": "XKU-47542-sample",
+ "metafield_id": 34725743231027,
+ "old_value": "100% recycled polyester"
+ },
+ {
+ "pid": "1498966327408",
+ "sku": "XKU-47545-sample",
+ "metafield_id": 34725744377907,
+ "old_value": "100% recycled polyester"
+ },
+ {
+ "pid": "1498966556784",
+ "sku": "XKU-47546-sample",
+ "metafield_id": 34725744771123,
+ "old_value": "100% recycled polyester"
+ },
+ {
+ "pid": "1498967277680",
+ "sku": "XKU-47550-sample",
+ "metafield_id": 34725746311219,
+ "old_value": "100% recycled polyester"
+ },
+ {
+ "pid": "1498967375984",
+ "sku": "XKU-47551-sample",
+ "metafield_id": 34725746704435,
+ "old_value": "100% recycled polyester"
+ },
+ {
+ "pid": "1498950598768",
+ "sku": "XKL-47466",
+ "metafield_id": 34447213199411,
+ "old_value": "100% recycled polyester"
+ },
+ {
+ "pid": "1498950795376",
+ "sku": "XKL-47467",
+ "metafield_id": 34447213592627,
+ "old_value": "100% recycled polyester"
+ },
+ {
+ "pid": "1498951024752",
+ "sku": "XKL-47468",
+ "metafield_id": 34447213690931,
+ "old_value": "100% recycled polyester"
+ },
+ {
+ "pid": "1498951254128",
+ "sku": "XKL-47469",
+ "metafield_id": 34447213985843,
+ "old_value": "100% recycled polyester"
+ },
+ {
+ "pid": "1498951417968",
+ "sku": "XKL-47470",
+ "metafield_id": 34447214280755,
+ "old_value": "100% recycled polyester"
+ },
+ {
+ "pid": "1498951581808",
+ "sku": "XKL-47471",
+ "metafield_id": 34447215263795,
+ "old_value": "100% recycled polyester"
+ },
+ {
+ "pid": "1498951778416",
+ "sku": "XKL-47472",
+ "metafield_id": 34447215755315,
+ "old_value": "100% recycled polyester"
+ },
+ {
+ "pid": "1498951975024",
+ "sku": "XKL-47473",
+ "metafield_id": 34447216148531,
+ "old_value": "100% recycled polyester"
+ },
+ {
+ "pid": "1498952171632",
+ "sku": "XKL-47474",
+ "metafield_id": 34447216312371,
+ "old_value": "100% recycled polyester"
+ },
+ {
+ "pid": "7087970484275",
+ "sku": "XPV-48352",
+ "metafield_id": 34727196295219,
+ "old_value": "100% recycled polyester"
+ },
+ {
+ "pid": "7087987064883",
+ "sku": "XPV-48360",
+ "metafield_id": 34727200358451,
+ "old_value": "100% recycled polyester"
+ },
+ {
+ "pid": "7099463172147",
+ "sku": "XPV-48361",
+ "metafield_id": 34727200948275,
+ "old_value": "100% recycled polyester"
+ },
+ {
+ "pid": "7099513143347",
+ "sku": "XPV-48363",
+ "metafield_id": 34727202095155,
+ "old_value": "100% recycled polyester"
+ }
+]
\ No newline at end of file
diff --git a/silence_spec.pdf b/silence_spec.pdf
new file mode 100644
index 0000000..15b77c2
Binary files /dev/null and b/silence_spec.pdf differ
diff --git a/targets_polyester.tsv b/targets_polyester.tsv
new file mode 100644
index 0000000..8e24850
--- /dev/null
+++ b/targets_polyester.tsv
@@ -0,0 +1,28 @@
+1497935478896|ACT-73254-sample|ACTIVE|Cesare Acoustical Walls
+1497935642736|ACT-73255|DRAFT|Cesare Acoustical Walls
+1497935806576|ACT-73256|DRAFT|Cesare Acoustical Walls
+1497935970416|ACT-73257-sample|ACTIVE|Cesare Acoustical Walls
+1497936167024|ACT-73258-sample|ACTIVE|Cesare Acoustical Walls
+1497936494704|ACT-73260|DRAFT|Cesare Acoustical Walls
+1497936658544|ACT-73261|DRAFT|Cesare Acoustical Walls
+1497936855152|ACT-73262-sample|ACTIVE|Cesare Acoustical Walls
+1497937018992|ACT-73263-sample|ACTIVE|Cesare Acoustical Walls
+1497935282288|XVY-73252|DRAFT|Cesare Acoustical Walls
+1498965704816|XKU-47542-sample|ACTIVE|Corsham Acoustical Wallcovering
+1498966327408|XKU-47545-sample|ACTIVE|Corsham Acoustical Wallcovering
+1498966556784|XKU-47546-sample|ACTIVE|Corsham Acoustical Wallcovering
+1498967277680|XKU-47550-sample|ACTIVE|Corsham Acoustical Wallcovering
+1498967375984|XKU-47551-sample|DRAFT|Corsham Acoustical Wallcovering
+1498950598768|XKL-47466|DRAFT|Crosby Acoustical Wallcovering
+1498950795376|XKL-47467|DRAFT|Crosby Acoustical Wallcovering
+1498951024752|XKL-47468|DRAFT|Crosby Acoustical Wallcovering
+1498951254128|XKL-47469|DRAFT|Crosby Acoustical Wallcovering
+1498951417968|XKL-47470|DRAFT|Crosby Acoustical Wallcovering
+1498951581808|XKL-47471|DRAFT|Crosby Acoustical Wallcovering
+1498951778416|XKL-47472|DRAFT|Crosby Acoustical Wallcovering
+1498951975024|XKL-47473|DRAFT|Crosby Acoustical Wallcovering
+1498952171632|XKL-47474|DRAFT|Crosby Acoustical Wallcovering
+7087970484275|XPV-48352|ACTIVE|Otterton Acoustical Wallcovering
+7087987064883|XPV-48360|ACTIVE|Yettington Acoustical Wallcovering
+7099463172147|XPV-48361|ACTIVE|Yettington Acoustical Wallcovering
+7099513143347|XPV-48363|ACTIVE|Yettington Acoustical Wallcovering
← 4924537 Fix Sidmouth Acoustical (Momentum Silence) material: vinyl -
·
back to Sidmouth Material Fix
·
Set Ellington goat-hair acoustical material 'Goat Hair' on 4 d416de5 →