[object Object]

← back to Wallco Ai

etsy export: add print_ready_in / print_ready_ft computed fields per listing (close-up 150 DPI / room 75 DPI / mural 50 DPI) + safe-print-size language in description + CSV columns

8794315d33d4d8ac6ef7f65ddbe9f13a5eb1a06c · 2026-05-28 06:48:37 -0700 · Steve Abrams

Files touched

Diff

commit 8794315d33d4d8ac6ef7f65ddbe9f13a5eb1a06c
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Thu May 28 06:48:37 2026 -0700

    etsy export: add print_ready_in / print_ready_ft computed fields per listing (close-up 150 DPI / room 75 DPI / mural 50 DPI) + safe-print-size language in description + CSV columns
---
 data/etsy-queue.jsonl          |  1 +
 scripts/export-etsy-digital.js | 44 +++++++++++++++++++++++++++++++++++++-----
 2 files changed, 40 insertions(+), 5 deletions(-)

diff --git a/data/etsy-queue.jsonl b/data/etsy-queue.jsonl
new file mode 100644
index 0000000..5bfc353
--- /dev/null
+++ b/data/etsy-queue.jsonl
@@ -0,0 +1 @@
+{"ts":"2026-05-28T13:44:47.982Z","id":39418,"dig_number":"DIG_AI_039418","title":"","local_path":"/Users/stevestudio2/Projects/wallco-ai/data/generated/bgswap__39400_1779638659406_932516194.png","source":"design-page-button"}
diff --git a/scripts/export-etsy-digital.js b/scripts/export-etsy-digital.js
index 8f1aee3..111c783 100644
--- a/scripts/export-etsy-digital.js
+++ b/scripts/export-etsy-digital.js
@@ -89,10 +89,23 @@ function deriveTitle(d) {
   // Etsy 140-char limit on titles.
   return `${cn} ${subj} Wallpaper · Seamless Tile · Digital Download · Printable Wallpaper Design`.slice(0, 140);
 }
-function deriveDescription(d, title) {
+// Compute the largest print size that stays SHARP given the output pixel size.
+// 150 DPI is the wallcovering trade's standard for print-master quality at
+// nose-to-the-wall distance. At normal room-viewing distance (4-6 ft) you can
+// drop to ~75 DPI without anyone noticing. At mural distance (8+ ft) 50 DPI
+// is fine. Source 1024² LANCZOS-upscaled to 3600 = 150 DPI × 24" close-up.
+function printSizes(px) {
+  return {
+    close_up_in:   Math.round(px / 150),    // arm's-length quality
+    room_dist_in:  Math.round(px /  75),    // typical residential viewing
+    mural_in:      Math.round(px /  50),    // 8+ ft viewing
+  };
+}
+function deriveDescription(d, title, pxOut) {
   const cn = colorName(d.dominant_hex);
+  const ps = printSizes(pxOut);
   const dpiNote = opt.upscale
-    ? `Includes high-resolution ${opt.upscalePx}×${opt.upscalePx} px PNG (24"×24" tile @ 150 DPI) plus the original 1024×1024 source.`
+    ? `Includes ${pxOut}×${pxOut} px high-resolution PNG (24"×24" tile @ 150 DPI close-up sharpness) plus the original 1024×1024 source.`
     : `Includes 1024×1024 PNG source tile.`;
   return [
     title,
@@ -104,7 +117,13 @@ function deriveDescription(d, title) {
     `📐 What you get:`,
     `• ${dpiNote}`,
     `• Seamless square tile — repeats cleanly across walls of any size`,
-    `• ${cn}-on-ivory palette (or as shown in preview)`,
+    `• ${cn} palette (as shown in preview)`,
+    '',
+    `📏 Print-safe sizes (based on the file resolution):`,
+    `• Up to ${ps.close_up_in}″ wide for tight-detail close-up print (150 DPI) — single accent panel, framed art`,
+    `• Up to ${ps.room_dist_in}″ (${(ps.room_dist_in/12).toFixed(1)}′) wide for normal room viewing (75 DPI) — accent wall`,
+    `• Up to ${ps.mural_in}″ (${(ps.mural_in/12).toFixed(1)}′) wide for mural-scale viewing (50 DPI) — full-wall installs`,
+    `Note: because the file is a seamless tile, it can be repeated to cover ANY wall — the sizes above are the safe print size of one ${ps.close_up_in}″ tile before quality starts to soften.`,
     '',
     `🖼  Use it for:`,
     `• Print-on-demand wallpaper (Spoonflower, Walls.io, custom mills)`,
@@ -202,8 +221,10 @@ function main() {
       buildAssets(d.local_path, folder);
 
       const title = deriveTitle(d);
-      const description = deriveDescription(d, title);
+      const pxOut = opt.upscale ? opt.upscalePx : 1024;
+      const description = deriveDescription(d, title, pxOut);
       const tags = deriveTags(d, title);
+      const ps = printSizes(pxOut);
       const listing = {
         sku: `DW-DL-${d.id}`,
         id: d.id,
@@ -219,6 +240,16 @@ function main() {
           cover: `${d.id}/cover_4x4.png`,
           ...(opt.upscale && { print: `${d.id}/print_${opt.upscalePx}.png` }),
         },
+        // Print-ready dimensions (1 tile, before seamless repeat extends it):
+        //   close-up = 150 DPI (arm's-length sharpness)
+        //   room     = 75 DPI  (normal residential viewing)
+        //   mural    = 50 DPI  (8 ft+ viewing distance)
+        print_ready_in: ps,
+        print_ready_ft: {
+          close_up: +(ps.close_up_in / 12).toFixed(1),
+          room:     +(ps.room_dist_in / 12).toFixed(1),
+          mural:    +(ps.mural_in     / 12).toFixed(1),
+        },
         listing_type: 'digital_download',
         is_personalizable: false,
       };
@@ -236,10 +267,13 @@ function main() {
 
   // Aggregate manifests
   fs.writeFileSync(path.join(OUT_DIR, 'listings.json'), JSON.stringify(manifest, null, 2));
-  const CSV_HEAD = ['sku', 'id', 'title', 'price', 'currency', 'category', 'primary_color', 'tags', 'source_file', 'cover_file', 'print_file'];
+  const CSV_HEAD = ['sku', 'id', 'title', 'price', 'currency', 'category', 'primary_color', 'tags',
+                    'print_close_up_in', 'print_room_in', 'print_mural_ft',
+                    'source_file', 'cover_file', 'print_file'];
   const csvRow = l => [
     l.sku, l.id, JSON.stringify(l.title), l.price.toFixed(2), l.currency, l.category || '',
     l.primary_color || '', JSON.stringify(l.tags.join(',')),
+    l.print_ready_in.close_up_in, l.print_ready_in.room_dist_in, l.print_ready_ft.mural,
     l.files.source || '', l.files.cover || '', l.files.print || '',
   ].join(',');
   fs.writeFileSync(path.join(OUT_DIR, 'listings.csv'),

← c07a04e tone-on-tone hex picker: sort by hue + collapse near-duplica  ·  back to Wallco Ai  ·  seam-debug: replace PIL band-blur with Replicate SDXL-inpain 8c77b4c →