[object Object]

← back to Homesonspec

auto-save: 2026-07-28T20:33:03 (1 files) — collectors/ashton-woods/src/index.ts

590c9393a25039a758459baf506401566e3a30f2 · 2026-07-28 20:33:09 -0700 · Steve Abrams

Files touched

Diff

commit 590c9393a25039a758459baf506401566e3a30f2
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Tue Jul 28 20:33:09 2026 -0700

    auto-save: 2026-07-28T20:33:03 (1 files) — collectors/ashton-woods/src/index.ts
---
 collectors/ashton-woods/src/index.ts | 23 ++++++++++++++++++++---
 1 file changed, 20 insertions(+), 3 deletions(-)

diff --git a/collectors/ashton-woods/src/index.ts b/collectors/ashton-woods/src/index.ts
index 3d9dc0f9..97090cbb 100644
--- a/collectors/ashton-woods/src/index.ts
+++ b/collectors/ashton-woods/src/index.ts
@@ -30,8 +30,9 @@ import {
  *     Product.offers: price (number), priceCurrency, availability
  *       (schema.org/InStock -> for-sale).
  *
- * Plain HTTP; one page == one inventory_home. Facts-only (image intentionally
- * omitted — mediaRights=NONE). Metro scope via ASHTONWOODS_METRO (comma-list,
+ * Plain HTTP; one page == one inventory_home. Captures per-home Widen CDN photos
+ * from JSON-LD + gallery (images enabled 2026-07-28 per Steve's hotlink approval).
+ * Metro scope via ASHTONWOODS_METRO (comma-list,
  * e.g. "austin,dallas"; default = all metros); per-metro page cap via
  * ASHTONWOODS_PAGE_LIMIT. HAS per-home geo (homes appear on the map).
  */
@@ -202,6 +203,22 @@ export const ashtonWoodsAdapter: SourceAdapter = {
       if (!h.price || !h.available) return { records: [], errors: [] }; // sold / unpriced -> not current inventory
 
       const cname = h.community ?? "Unknown";
+
+      // per-home Widen CDN photos: JSON-LD `image` is the primary elevation; the page
+      // also carries gallery shots on awh.widen.net. Decode &/&amp; first so query
+      // strings survive, dedup by path, cap. [images enabled 2026-07-28 per hotlink approval]
+      const decoded = html.replace(/\\u0026/gi, "&").replace(/&amp;/g, "&");
+      const ldImg = decoded.match(/"image"\s*:\s*"(https:\/\/awh\.widen\.net[^"]+)"/)?.[1];
+      const widenAll = [...decoded.matchAll(/https:\/\/awh\.widen\.net\/content\/[^\s"'<>\\)]+/gi)].map((m) => m[0]);
+      const seenImg = new Set<string>();
+      const images: string[] = [];
+      for (const u of [ldImg, ...widenAll].filter((x): x is string => !!x)) {
+        const key = u.split("?")[0]!;
+        if (seenImg.has(key)) continue;
+        seenImg.add(key);
+        images.push(u);
+      }
+
       const records: ExtractedRecord[] = [];
 
       // community record (carries per-home geo so the community also maps)
@@ -254,7 +271,7 @@ export const ashtonWoodsAdapter: SourceAdapter = {
           builderInventoryId: fv(h.url || h.street, h.url || h.street, page.url),
           planName: fv<string>(null, null, page.url),
           availabilityStatus: fv("InStock", "InStock", page.url, "schema.org availability InStock"),
-          images: fv<string[]>([], null, page.url), // facts-only — mediaRights=NONE
+          images: fv<string[]>(images.slice(0, 8), null, page.url, images.length ? "builder listing photo" : null),
         },
       });
 

← 8e6635cb tri-pointe: capture per-home Cloudinary photos (h.image.raw)  ·  back to Homesonspec  ·  collectors: add Perry, Brookfield, Holt adapters (+3 builder 33db5031 →