← back to Secrets Manager
deploy-faqs-bymaterial.py
143 lines
#!/usr/bin/env python3
"""
deploy-faqs-bymaterial.py — set a grounded custom.faq metafield on EVERY category
collection that has a real description, by matching the collection to a material FAQ
(grasscloth/faux-leather/velvet/cork/silk/suede/metallic/linen/vinyl/mural). The live
theme renders it as a collapsed "Learn about…" panel + FAQPage schema.
Private-label safe. Idempotent (skips a collection that already has custom.faq unless --force).
Run: ! python3 ~/Projects/secrets-manager/deploy-faqs-bymaterial.py # dry-run
! python3 ~/Projects/secrets-manager/deploy-faqs-bymaterial.py --apply
"""
import re, json, sys, urllib.request
APPLY = '--apply' in sys.argv; FORCE = '--force' in sys.argv
env = open('/Users/macstudio3/Projects/secrets-manager/.env').read()
tok = re.search(r'^SHOPIFY_CONTENT_TOKEN=(.+)$', env, re.M).group(1).strip().strip('"').strip("'")
S = "designer-laboratory-sandbox.myshopify.com"; A = "2024-10"
def api(p, method="GET", body=None):
data = json.dumps(body).encode() if body else None
r = urllib.request.Request(f"https://{S}/admin/api/{A}/{p}", data=data, method=method,
headers={"X-Shopify-Access-Token": tok, "Content-Type": "application/json"})
return json.load(urllib.request.urlopen(r, timeout=30))
Q = lambda q, a: {"q": q, "a": a}
M = {
"grasscloth": [
Q("What is grasscloth wallcovering?", "Grasscloth is a natural-fiber wallcovering handwoven from grasses, jute, hemp, sisal and similar sustainable fibers, adding depth and tactile richness paint cannot replicate."),
Q("What rooms suit grasscloth?", "It shines as a feature or accent wall in dining rooms, bedrooms, studies and entries. In high-moisture or high-scrub areas, use it as a feature wall or choose a coated natural."),
Q("Does grasscloth have color and seam variation?", "Yes — woven from real plant fibers, subtle shading and visible seams between panels are inherent and part of its handcrafted appeal. Order all yardage from one dye lot."),
Q("Can I order grasscloth samples first?", "Yes. Designer Wallcoverings offers complimentary samples for the trade so you can check the weave and colorway in your own light before ordering."),
],
"faux-leather": [
Q("What is faux leather wallcovering?", "A vinyl wallcovering engineered to mimic genuine leather — cruelty-free, more sustainable, and far more durable than the real hide."),
Q("Is it good for high-traffic or commercial spaces?", "Yes. Its enhanced durability suits high-traffic and commercial interiors while keeping a luxurious leather appearance."),
Q("How do you clean faux leather wallcovering?", "The vinyl surface wipes clean with a damp cloth, part of why it performs so well in busy residential and commercial spaces."),
Q("Can I order samples before buying?", "Yes. Designer Wallcoverings offers complimentary trade samples so you can compare grain and color in your space."),
],
"velvet": [
Q("What is flocked velvet wallcovering?", "Flock was created to imitate cut-velvet hangings — fibers applied to an adhesive ground form a raised, velvet-like texture, today using synthetic pile such as polyester or rayon."),
Q("What look does it create?", "A tactile, dimensional, luxurious surface ideal for formal rooms and dramatic feature walls where you want depth and richness."),
Q("How do you care for flocked wallcovering?", "Treat the pile gently — dust lightly and avoid abrasion so the raised velvet texture stays crisp."),
Q("Can I order samples?", "Yes. Designer Wallcoverings offers complimentary trade samples so you can feel the pile and see the colorway first."),
],
"cork": [
Q("What is cork wallcovering?", "Cork wallcovering is made from the bark of the cork oak tree, offering a warm, earthy texture with natural variation that makes every panel distinctive."),
Q("Is cork wallcovering sustainable?", "Yes — cork is harvested from the tree's bark without cutting it down, making it a renewable, eco-friendly surface."),
Q("What rooms suit cork?", "Cork works beautifully as a feature wall in studies, offices, bedrooms and living spaces, and its structure also helps soften sound."),
Q("Can I order cork samples first?", "Yes. Designer Wallcoverings offers complimentary trade samples so you can see the natural texture and tone in your own light."),
],
"silk": [
Q("What is faux silk wallcovering?", "Faux silk captures the soft luster and refined drape of real silk in a more durable, easier-care material — the elegance without the fragility."),
Q("What look does it create?", "A gentle sheen and quiet luxury suited to bedrooms, dining rooms and formal living spaces where you want a soft, light-catching backdrop."),
Q("Is faux silk more durable than real silk?", "Yes — it resists the wear and delicacy of genuine silk while keeping the same lustrous appearance."),
Q("Can I order samples before buying?", "Yes. Designer Wallcoverings offers complimentary trade samples so you can check the sheen and color against your furnishings."),
],
"suede": [
Q("What is suede wallcovering?", "A premium microfiber suede wallcovering with the soft, tactile look of real suede in a durable, cleanable material engineered for walls."),
Q("Where is it used?", "It creates a luxurious, upholstered-look feature wall in residential and commercial interiors — a rich surface that reads far more expensive than paint."),
Q("How do you care for it?", "As a microfiber it is more durable and cleanable than natural suede, holding its soft nap in everyday interiors."),
Q("Can I order samples first?", "Yes. Designer Wallcoverings offers complimentary trade samples so you can feel the texture and check the colorway."),
],
"metallic": [
Q("What is metallic wallcovering?", "A wallcovering with a reflective metallic finish that catches and changes with the light, often on a durable vinyl ground."),
Q("What rooms suit metallic wallcovering?", "It makes a striking feature wall in powder rooms, dining rooms, entries and commercial spaces where the reflective sheen adds depth and drama."),
Q("Is it durable and cleanable?", "On a vinyl ground it is scrubbable and hard-wearing, suited to both residential feature walls and high-traffic commercial interiors."),
Q("Can I order samples?", "Yes. Designer Wallcoverings offers complimentary trade samples so you can see how the finish reads in your lighting."),
],
"linen": [
Q("What is linen wallcovering?", "A textile wallcovering woven from linen fibers, bringing a soft, natural weave and understated elegance with a tailored, organic texture."),
Q("What rooms suit linen wallcovering?", "It suits bedrooms, studies, dining rooms and living spaces where you want warmth and refinement without a bold pattern."),
Q("Does linen have natural variation?", "Yes — as a natural woven textile, subtle slubs and shading are part of its character; order all yardage from one run."),
Q("Can I order samples first?", "Yes. Designer Wallcoverings offers complimentary trade samples so you can feel the weave and check the tone in your space."),
],
"vinyl": [
Q("What is vinyl wallcovering?", "A durable, wipeable wallcovering engineered for performance — the go-to for high-traffic residential and commercial interiors."),
Q("Is vinyl good for commercial spaces?", "Yes — Type II vinyl is scrubbable and hard-wearing, standing up to high-traffic corridors, hospitality and healthcare environments."),
Q("How do you clean vinyl wallcovering?", "It wipes clean with a damp cloth, which is why it performs so well where durability and maintenance matter."),
Q("Can I order samples before buying?", "Yes. Designer Wallcoverings offers complimentary trade samples so you can confirm the texture and color in your space."),
],
"mural": [
Q("What is a wallcovering mural?", "A large-scale, panelized design printed to cover a wall as a single continuous scene or pattern — made to order to your wall's dimensions."),
Q("Are murals made to order?", "Yes — murals are produced to your wall size, so accurate measurements are important before ordering."),
Q("Where do murals work best?", "As a statement feature wall in entries, dining rooms, bedrooms and commercial lobbies where you want an immersive, room-defining scene."),
Q("Can I order a sample first?", "Yes. Designer Wallcoverings offers complimentary trade samples so you can check color and print quality before committing to a full mural."),
],
}
# match order: specific -> general
MATCH = [
("faux-leather", r'faux.?leather|leather'),
("velvet", r'flock|velvet'),
("suede", r'suede'),
("cork", r'\bcork'),
("silk", r'silk'),
("metallic", r'metallic|mylar|foil'),
("linen", r'linen'),
("mural", r'mural'),
("grasscloth", r'grasscloth|sisal|jute|hemp|raffia|\bnatural'),
("vinyl", r'vinyl'),
]
cols = []
for kind in ("custom_collections", "smart_collections"):
since = 0
while True:
d = api(f"{kind}.json?limit=250&since_id={since}&fields=id,handle,title,body_html")[kind]
if not d: break
for c in d:
body = re.sub(r'<[^>]+>', '', c.get('body_html') or '').strip()
cols.append({"id": c['id'], "h": c['handle'], "t": c['title'], "blen": len(body)})
since = d[-1]['id']
plan = []
for c in cols:
if c['blen'] < 50: continue # skip bare grids (no description to pair with)
hay = (c['h'] + ' ' + c['t']).lower()
mat = next((m for m, rx in MATCH if re.search(rx, hay)), None)
if mat: plan.append((c, mat))
print(f"{len(plan)} category collections matched a material (of {len(cols)} total):")
from collections import Counter
print(" by material:", dict(Counter(m for _, m in plan)))
changed = skipped = 0
for c, mat in plan:
if not APPLY:
continue
existing = api(f"collections/{c['id']}/metafields.json?namespace=custom&key=faq")['metafields']
if existing and not FORCE:
skipped += 1; continue
body = {"metafield": {"namespace": "custom", "key": "faq", "type": "json",
"value": json.dumps(M[mat], ensure_ascii=False)}}
res = api(f"collections/{c['id']}/metafields.json", "POST", body)
if 'metafield' in res: changed += 1
else: print(f" FAIL {c['h']}: {json.dumps(res)[:120]}")
if not APPLY:
print("\nDRY-RUN — sample of what would be set:")
for c, mat in plan[:20]:
print(f" {mat:12} <- {c['h']}")
print(f"\n(+{max(0,len(plan)-20)} more) re-run with --apply")
else:
print(f"\nAPPLIED — set={changed} skipped(existing)={skipped} of {len(plan)} matched")
print("Verify: https://designerwallcoverings.com/collections/grasscloth-wallpaper-collection")