#!/usr/bin/env node /** * Script para obtener imágenes de Wikimedia Commons para monumentos * Usa la API de Wikimedia Commons (gratuita, sin API key) */ const { Client } = require('pg'); const https = require('https'); // Configuración const config = { db: { host: 'localhost', port: 5432, user: 'karibeo', password: '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', database: 'karibeo_db', }, }; // Buscar imágenes en Wikimedia Commons async function searchWikimediaImages(query, limit = 3) { return new Promise((resolve, reject) => { // Primero buscar en Wikipedia para obtener la página del lugar const searchUrl = `https://commons.wikimedia.org/w/api.php?action=query&list=search&srsearch=${encodeURIComponent(query)}&srnamespace=6&srlimit=${limit}&format=json`; https.get(searchUrl, { headers: { 'User-Agent': 'KaribeoAI/1.0 (contact@karibeo.ai)' } }, (res) => { let data = ''; res.on('data', chunk => data += chunk); res.on('end', () => { try { const json = JSON.parse(data); if (json.query && json.query.search && json.query.search.length > 0) { // Obtener URLs de las imágenes const titles = json.query.search.map(s => s.title).join('|'); getImageUrls(titles).then(resolve).catch(reject); } else { resolve([]); } } catch (e) { reject(e); } }); }).on('error', reject); }); } // Obtener URLs directas de las imágenes async function getImageUrls(titles) { return new Promise((resolve, reject) => { const url = `https://commons.wikimedia.org/w/api.php?action=query&titles=${encodeURIComponent(titles)}&prop=imageinfo&iiprop=url|size&format=json`; https.get(url, { headers: { 'User-Agent': 'KaribeoAI/1.0 (contact@karibeo.ai)' } }, (res) => { let data = ''; res.on('data', chunk => data += chunk); res.on('end', () => { try { const json = JSON.parse(data); const urls = []; if (json.query && json.query.pages) { for (const pageId in json.query.pages) { const page = json.query.pages[pageId]; if (page.imageinfo && page.imageinfo[0]) { const info = page.imageinfo[0]; // Solo incluir imágenes de tamaño razonable (> 100KB y < 10MB) if (info.size > 100000 && info.size < 10000000) { urls.push(info.url); } } } } resolve(urls); } catch (e) { reject(e); } }); }).on('error', reject); }); } // Buscar con términos alternativos async function searchWithAlternatives(name, country) { const countryName = country === 'DO' ? 'Dominican Republic' : 'Puerto Rico'; const countryNameEs = country === 'DO' ? 'República Dominicana' : 'Puerto Rico'; // Lista de búsquedas a intentar const searches = [ `${name} ${countryNameEs}`, `${name} ${countryName}`, name, `${name} Caribbean`, ]; for (const query of searches) { console.log(` Buscando: "${query}"`); const images = await searchWikimediaImages(query, 5); if (images.length > 0) { return images.slice(0, 3); // Máximo 3 imágenes } await delay(500); // Rate limit } return []; } function delay(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } async function main() { console.log('🖼️ Buscador de Imágenes - Wikimedia Commons'); console.log('============================================\n'); // Conectar a la DB const client = new Client(config.db); await client.connect(); console.log('✅ Conectado a la base de datos\n'); // Obtener monumentos sin imágenes válidas const query = ` SELECT id, name, country, slug, images FROM tourism.places_of_interest WHERE active = true AND (images IS NULL OR images::text = '[]' OR images::text LIKE '%example.com%') ORDER BY name `; const result = await client.query(query); const places = result.rows; console.log(`📍 Encontrados ${places.length} lugares sin imágenes válidas\n`); let found = 0; let notFound = 0; for (let i = 0; i < places.length; i++) { const place = places[i]; console.log(`[${i + 1}/${places.length}] ${place.name} (${place.country})`); try { const images = await searchWithAlternatives(place.name, place.country); if (images.length > 0) { // Guardar en la DB await client.query( `UPDATE tourism.places_of_interest SET images = $1 WHERE id = $2`, [JSON.stringify(images), place.id] ); console.log(` ✅ ${images.length} imágenes encontradas`); found++; } else { console.log(` ⚠️ No se encontraron imágenes`); notFound++; } } catch (error) { console.log(` ❌ Error: ${error.message}`); notFound++; } // Rate limit para la API de Wikimedia await delay(1000); } await client.end(); console.log('\n============================================'); console.log('📊 RESUMEN'); console.log(` ✅ Con imágenes: ${found}`); console.log(` ⚠️ Sin imágenes: ${notFound}`); console.log('============================================\n'); } main().catch(err => { console.error('Error fatal:', err); process.exit(1); });