← back to Grassclothwallpaper
extract-and-save-colors.js
136 lines
const fetch = require('node-fetch');
const Vibrant = require('node-vibrant/node');
const SUPABASE_URL = 'https://fypvpcxyfmmdhtklgbrt.supabase.co';
const SUPABASE_KEY = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImZ5cHZwY3h5Zm1tZGh0a2xnYnJ0Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTg4MTAxMjMsImV4cCI6MjA3NDM4NjEyM30.fzDf6VE7jyrqLIbebAwI1NHXi50pI0b_FgQVO-6QcAk';
// First, let's create a JSON file with all the colors
async function extractAllColors() {
console.log('=== COLOR EXTRACTION PROCESS ===\n');
console.log('Step 1: Fetching all products...');
try {
// Fetch all products
const response = await fetch(
`${SUPABASE_URL}/rest/v1/grasscloth_products?select=*&order=sku`,
{
headers: {
'apikey': SUPABASE_KEY,
'Authorization': `Bearer ${SUPABASE_KEY}`
}
}
);
if (!response.ok) {
throw new Error(`Failed to fetch products: ${response.statusText}`);
}
const products = await response.json();
if (!Array.isArray(products)) {
throw new Error(`Unexpected response from Supabase: ${JSON.stringify(products)}`);
}
const productsWithImages = products.filter(p =>
p.image_url && p.image_url.includes('supabase.co/storage')
);
console.log(`Found ${productsWithImages.length} products with Supabase images\n`);
const colorData = [];
let processed = 0;
console.log('Step 2: Extracting colors from images...\n');
// Process each product
for (const product of productsWithImages) {
try {
process.stdout.write(`Processing ${processed + 1}/${productsWithImages.length}: ${product.sku}... `);
// Use Vibrant properly
const v = new Vibrant(product.image_url);
const palette = await v.getPalette();
let primaryColor = '#D4B896'; // Default beige
let secondaryColor = '#8B7355'; // Default brown
if (palette) {
// Get primary color
if (palette.Vibrant) {
primaryColor = palette.Vibrant.getHex();
} else if (palette.Muted) {
primaryColor = palette.Muted.getHex();
} else if (palette.DarkVibrant) {
primaryColor = palette.DarkVibrant.getHex();
}
// Get secondary color
if (palette.DarkMuted) {
secondaryColor = palette.DarkMuted.getHex();
} else if (palette.DarkVibrant && primaryColor !== palette.DarkVibrant.getHex()) {
secondaryColor = palette.DarkVibrant.getHex();
} else if (palette.LightVibrant) {
secondaryColor = palette.LightVibrant.getHex();
}
}
colorData.push({
id: product.id,
sku: product.sku,
primary_color: primaryColor,
secondary_color: secondaryColor
});
console.log(`✓ (${primaryColor}, ${secondaryColor})`);
processed++;
// Small delay every 10 items to avoid overwhelming
if (processed % 10 === 0) {
await new Promise(resolve => setTimeout(resolve, 500));
}
} catch (error) {
console.log(`✗ Error: ${error.message}`);
// Add with default colors on error
colorData.push({
id: product.id,
sku: product.sku,
primary_color: '#D4B896',
secondary_color: '#8B7355'
});
processed++;
}
}
console.log('\n\nStep 3: Saving color data to JSON file...');
// Save to JSON file
const fs = require('fs').promises;
await fs.writeFile(
'product-colors.json',
JSON.stringify(colorData, null, 2)
);
console.log('✓ Color data saved to product-colors.json');
// Show sample
console.log('\nSample of extracted colors:');
colorData.slice(0, 5).forEach(item => {
console.log(` ${item.sku}: Primary=${item.primary_color}, Secondary=${item.secondary_color}`);
});
console.log('\n=== EXTRACTION COMPLETE ===');
console.log(`Total products processed: ${processed}`);
console.log('\nNext steps:');
console.log('1. Add color columns to Supabase using the SQL in add-color-columns.sql');
console.log('2. Run: node upload-colors-to-supabase.js');
return colorData;
} catch (error) {
console.error('Fatal error:', error);
}
}
// Run extraction
extractAllColors();