← back to Dw Domain Fleet

scripts/gen-retry-candidates.js

44 lines

#!/usr/bin/env node
// Emit large-preferred, niche-relevant candidate hero urls for the sites whose
// first assignment downloaded too small. Excludes every already-claimed url
// (344 generic + 59 standalone assignments). Output: {domain:[urls...]}.
const fs = require('fs');
const path = require('path');
const catalog = require('../shared/catalog');
const { sortProducts } = require('../shared/sort');
const ROOT = path.join(__dirname, '..');

const KW = {
  '1890swallpaper.com': ['traditional', 'classic', 'damask', 'floral'],
  'contractwallpaper.com': ['contract', 'commercial', 'performance', 'vinyl'],
  'embroideredwallpaper.com': ['embroider', 'stitch', 'textile', 'floral'],
  'greenwallcoverings.com': ['green', 'botanical', 'natural', 'grasscloth'],
  'metallicwallpaper.com': ['metallic', 'metal', 'gold', 'silver'],
  'silkwallpaper.com': ['silk', 'shimmer', 'texture'],
  'wallpapersback.com': ['floral', 'classic', 'damask', 'geometric'],
};

const isClean = u => u && /^https:\/\//i.test(u) && !/(_swatch|_thumb|-thumb|icon|sprite|placeholder|\.svg)/.test(u.toLowerCase());

const claimed = new Set();
for (const f of ['hero-allocation.json', 'standalone-hero-allocation.json']) {
  try {
    const j = JSON.parse(fs.readFileSync(path.join(ROOT, 'data', f), 'utf8'));
    if (Array.isArray(Object.values(j)[0])) Object.values(j).forEach(a => a.forEach(u => claimed.add(u)));
    else Object.values(j).forEach(o => claimed.add(o.url));
  } catch {}
}

const out = {};
for (const [dom, kw] of Object.entries(KW)) {
  let pool = catalog.nicheSlice({ pos: kw, neg: [], types: [], limit: 8000 }).filter(p => isClean(p.image_url));
  if (pool.length < 20) pool = catalog.nicheSlice({ pos: [], neg: [], types: ['Wallcovering'], limit: 100000 }).filter(p => isClean(p.image_url));
  // lifestyle /files/ shots first (usually large), then newest
  pool = sortProducts(pool, 'newest').sort((a, b) => (/\/files\//.test(b.image_url) ? 1 : 0) - (/\/files\//.test(a.image_url) ? 1 : 0));
  const urls = [];
  for (const p of pool) { if (!claimed.has(p.image_url)) urls.push(p.image_url); if (urls.length >= 120) break; }
  out[dom] = urls;
}
fs.writeFileSync(path.join(ROOT, 'data', 'retry-candidates.json'), JSON.stringify(out));
console.log('candidates per domain:', Object.entries(out).map(([d, u]) => d.replace('.com', '') + ':' + u.length).join(' '));