[object Object]

← back to Designer Wallcoverings

Sangetsu parser: image-filename SKU harvest (covers swatch+numeric), backing/width fixes, hunt cmd; refocus Andrew on 36in grasscloth (Woven Grass/Ambience), corrected George draft

cda0849d8091ab73bd3fd225ff8e6a9fc7ae7d28 · 2026-06-29 16:11:53 -0700 · steve@designerwallcoverings.com

Files touched

Diff

commit cda0849d8091ab73bd3fd225ff8e6a9fc7ae7d28
Author: steve@designerwallcoverings.com <steve@designerwallcoverings.com>
Date:   Mon Jun 29 16:11:53 2026 -0700

    Sangetsu parser: image-filename SKU harvest (covers swatch+numeric), backing/width fixes, hunt cmd; refocus Andrew on 36in grasscloth (Woven Grass/Ambience), corrected George draft
---
 .../disco-candidates-for-andrew.md                 | 43 ++++++++++------------
 .../sangetsu-sitemap-scraper.cjs                   | 31 ++++++++++++----
 2 files changed, 43 insertions(+), 31 deletions(-)

diff --git a/onboarding/sangetsu-lilycolor/disco-candidates-for-andrew.md b/onboarding/sangetsu-lilycolor/disco-candidates-for-andrew.md
index b1003688..5ced8101 100644
--- a/onboarding/sangetsu-lilycolor/disco-candidates-for-andrew.md
+++ b/onboarding/sangetsu-lilycolor/disco-candidates-for-andrew.md
@@ -1,30 +1,27 @@
-# Pattern run-down for Andrew Glick (DUST2026)
+# Pattern run-down for Andrew Glick (DUST2026) — 36" GRASSCLOTH/CANE DESIGN
 
 **Customer:** Andrew Glick — 646-330-9767 — egbrownstone@gmail.com — needs ASAP.
-**The ask (as relayed):** a pattern, *"disco possibly,"* like the Donghia he linked, maybe Sangetsu/Goodrich or Lilycolor ("lilly color"), "all in Japan."
+**Refined requirement (Steve, 2026-06-29):** the **DESIGN only, 36" wide** — a woven grasscloth/cane
+look like the Donghia he linked. (NOT the commercial 52–54" Type II line — width is a hard filter.)
 
-**Reference he gave:** Donghia **"Looks Like Grass – Cane"** (DW SKU **DWDH-188012**) — a natural,
-**matte grasscloth / woven cane** texture, 36" wide, 18" repeat, vinyl-on-paper. (No metallic on the
-Donghia itself.)
+**Reference:** Donghia **"Looks Like Grass – Cane"** (DW SKU **DWDH-188012**) — vinyl grasscloth/cane,
+**36" wide**, 18" repeat.
 
-## Honest finding
-**No pattern literally named "Disco"** turned up in the Sangetsu/Goodrich or Lilycolor catalogs in this
-pass — I did not invent one. "Disco possibly" most likely points at the **woven grasscloth look with a
-metallic/shimmer sparkle** (disco = sparkle) layered over the Donghia cane texture. The Sangetsu Goodrich
-"Symphony" naturals line is squarely that. Best matches to send him, ranked:
-
-| Rank | Pattern | Maker | SKU range | Why it fits | Link |
+## ✅ Corrected shortlist — 36"-wide grasscloth/cane designs
+| Rank | Design | Maker | Width | Material / look | Link |
 |---|---|---|---|---|---|
-| 1 | **Sanshin** | Sangetsu Goodrich (Symphony) | AZ52790–AZ52813 | Grasscloth-mimic, horizontal woven strings **+ metallic shimmer** — closest "cane + disco" read | sangetsu-goodrich.co.th/products/wallpaper-wallcovering/commercial-wallcovering/sanshin/ |
-| 2 | **Virtuoso** | Sangetsu Goodrich (Symphony) | AZ52250–AZ52899 | Layered woven print, **finest metallic touch / "effortless glamour"** — the most overtly "disco" shimmer | sangetsu-goodrich.co.th/products/wallpaper-wallcovering/commercial-wallcovering/virtuoso/ |
-| 3 | **Savannah** | Sangetsu Goodrich (J.Josephson) | Y47660–Y47677 | Chunky grasscloth, **18 matte AND metallic** colorways — has both the cane body and the sparkle | sangetsu-goodrich.co.th/products/wallpaper-wallcovering/commercial-wallcovering/savannah-wallpapers/ |
-| 4 | **Woven Grass** | Sangetsu Goodrich (goodwall SEED) | GSD1038–GSD1041 | Truest **cane/wild-grass-stem** match to the Donghia, matte (if "disco" turns out to be wrong) | sangetsugoodrich.com/en/brand/goodwall/product/woven-grass/ |
-| 5 | **Sass-a-Grass** | Sangetsu Goodrich (J.Josephson) | Y47450–Y47474 | Grasscloth with color pops + grid overlay — if he wants more color movement | sangetsu-goodrich.co.th/products/wallpaper-wallcovering/hospitality-wallcovering/sass-a-grass/ |
+| 1 | **Woven Grass** | Sangetsu Goodrich (goodwall) | **~36" (92.4 cm)** | Vinyl, woven "wild grass stem" / tatami texture — truest cane match to the Donghia | sangetsugoodrich.com/en/brand/goodwall/product/woven-grass/ |
+| 2 | **Ambience** | Sangetsu Goodrich | **36" untrimmed / 33.5" trimmed** | Natural sisal grasscloth, soft tone-on-tone | sangetsu-goodrich.co.th/products/wallpaper-wallcovering/commercial-wallcovering/ambience_wallpaper/ |
+| 3 | **Sisal Song** | Sangetsu Goodrich | width "upon request" — to confirm | Fine woven grasscloth + subtle horizontal metallic, 19 colors | sangetsu-goodrich.co.th/products/wallpaper-wallcovering/commercial-wallcovering/sisal-song/ |
+
+**Also ~36":** Lilycolor naturals are ~92.5 cm (≈36.4") wide — washi/woven-look vinyl; can pull a
+couple as side-by-side comparables if he wants more options.
 
-Lilycolor naturals (和紙調 washi / 麻 hemp / 織物 woven) exist too but are Japanese-catalog only and none
-read as "disco"; holding those unless he says the maker was specifically Lilycolor.
+## ❌ Superseded (wrong width)
+Sanshin / Virtuoso / Savannah are 52–54" commercial Type II — dropped per the 36" requirement.
+(Original draft with these was replaced; see corrected George draft.)
 
-## Suggested next step (NOT yet done — needs your OK to send)
-Send Andrew the **Sanshin / Virtuoso / Savannah** sample images (top 3) and ask him to point at the one.
-These are all **commercial 52–54" Type II** — confirm he wants commercial width, and we'll need to source
-**net cost** before quoting (no DW cost on file — these vendors aren't onboarded yet).
+## Status
+Corrected reply DRAFTED via George (`info@`) — leads with Woven Grass + Ambience (both 36"),
+Sisal Song as the third pending width confirm. Awaiting Steve review/send.
+Next: confirm Sisal Song width; optionally pull 36" Lilycolor naturals.
diff --git a/onboarding/sangetsu-lilycolor/sangetsu-sitemap-scraper.cjs b/onboarding/sangetsu-lilycolor/sangetsu-sitemap-scraper.cjs
index da45faa1..053bca33 100644
--- a/onboarding/sangetsu-lilycolor/sangetsu-sitemap-scraper.cjs
+++ b/onboarding/sangetsu-lilycolor/sangetsu-sitemap-scraper.cjs
@@ -61,14 +61,14 @@ function parsePage(html, url) {
   const name = stripTags((html.match(/<h1[^>]*class="product_title[^"]*"[^>]*>([\s\S]*?)<\/h1>/i) || [])[1])
     .replace(/\s+Wallpapers?$/i, '').trim() || null;
 
-  // colorway SKUs from <option value="...">SKU
-  const skus = [...new Set([...html.matchAll(/<option[^>]*>\s*([A-Z]{1,4}[0-9]{4,6}(?:-[0-9]+)?)\s*</gi)].map((m) => m[1].toUpperCase()))];
-
-  // SKU -> full-res image (non-thumbnail) from uploads path
+  // SKU -> full-res image (strip -WxH thumbnails). Works for AZ#####, Y#####, numeric 384500, G0167.
   const imgMap = {};
-  for (const m of html.matchAll(/(https:\/\/[^"' ]*\/uploads\/[0-9]{4}\/[0-9]{2}\/([A-Z]{1,4}[0-9]{4,6}))\.jpe?g/gi)) {
+  for (const m of html.matchAll(/(https:\/\/[^"' ]*\/uploads\/[0-9]{4}\/[0-9]{2}\/([A-Za-z]{0,4}[0-9]{3,6}))(?:-\d+x\d+)?\.jpe?g/gi)) {
     imgMap[m[2].toUpperCase()] = m[1] + '.jpg';
   }
+  // colorway SKUs = union of <option> values + image-filename SKUs (covers dropdown AND swatch pages)
+  const fromOptions = [...html.matchAll(/<option[^>]*>\s*([A-Za-z]{0,4}[0-9]{4,6})\s*</gi)].map((m) => m[1].toUpperCase());
+  const skus = [...new Set([...fromOptions, ...Object.keys(imgMap)])].filter((s) => /[0-9]{4,}/.test(s)).sort();
 
   // overview: short-description (percent- or entity-encoded in places) -> best-effort plain text
   let overview = stripTags((html.match(/woocommerce-product-details__short-description[^>]*>([\s\S]*?)<\/div>/i) || [])[1]);
@@ -81,11 +81,14 @@ function parsePage(html, url) {
   // specs: pull common wallcovering spec tokens from static text
   const text = stripTags(html);
   const spec = {
-    width: (text.match(/Width[:\s]*(\d{2}(?:\.\d)?)\s*"/i) || text.match(/\b(\d{2})"\s*Type\s+I/i) || [])[1]
-      ? `${(text.match(/Width[:\s]*(\d{2}(?:\.\d)?)\s*"/i) || text.match(/\b(\d{2})"\s*Type\s+I/i))[1]}"` : null,
+    width: (() => {
+      const m = text.match(/Width[:\s]*(\d{2}(?:\.\d)?)\s*"/i) || text.match(/\b(\d{2}(?:\.\d)?)"\s*(?:untrimmed|Type\s+I|wide)/i);
+      return m ? `${m[1]}"` : null;
+    })(),
     type: (text.match(/Type\s+I{1,3}/i) || [])[0] || null,
     weight: (text.match(/\b\d{1,2}\s*oz\b/i) || [])[0] || null,
-    backing: (text.match(/Backing[:\s]*([A-Za-z][A-Za-z-]+)/i) || [])[1] || null,
+    // stop the backing capture at the next Capitalized label (avoids "OsnaburgWidth")
+    backing: (text.match(/Backing[:\s]*([A-Z][a-z]+(?:[-\s][a-z]+)?)/) || [])[1] || null,
     is_grasscloth: /grasscloth/i.test(text),
     is_metallic: /metallic|shimmer/i.test(text),
   };
@@ -142,5 +145,17 @@ async function discover() {
     console.log(JSON.stringify({ patternsStaged: n, colorwaySkus: skuTotal, out: STAGE_OUT }, null, 2));
     return;
   }
+  if (cmd === 'hunt') {
+    // hunt <urls-file> : parse each URL, print ONE compact JSON line (pattern/width/grasscloth/skus)
+    const file = process.argv[3];
+    const urls = fs.readFileSync(file, 'utf8').trim().split('\n').filter(Boolean);
+    for (const url of urls) {
+      try {
+        const r = parsePage(await get(url), url);
+        console.log(JSON.stringify({ pattern: r.pattern, width: r.spec.width, grasscloth: r.spec.is_grasscloth, metallic: r.spec.is_metallic, skus: r.colorway_count, url }));
+      } catch (e) { console.log(JSON.stringify({ pattern: null, url, err: e.message })); }
+    }
+    return;
+  }
   console.error('unknown command:', cmd); process.exit(1);
 })().catch((e) => { console.error('FAILED:', e.message); process.exit(1); });

← be5f5549 Sangetsu: parsePage proven (plain fetch, no Browserbase) — 1  ·  back to Designer Wallcoverings  ·  Suncloth is Fabric not Wallcovering: stop cadence overriding ccdd68da →