← 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
M collectors/ashton-woods/src/index.ts
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 &/& first so query
+ // strings survive, dedup by path, cap. [images enabled 2026-07-28 per hotlink approval]
+ const decoded = html.replace(/\\u0026/gi, "&").replace(/&/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 →