const fs = require('fs'); const path = require('path'); const { Client, Databases, Storage, ID, Query } = require('node-appwrite'); const { InputFile } = require('node-appwrite/file'); const axios = require('axios'); // Configuración desde .env.local (Cargado manualmente para este script) if (fs.existsSync('.env.local')) { const envConfig = fs.readFileSync('.env.local').toString(); envConfig.split('\n').forEach(line => { const match = line.match(/^([^=]+)=(.*)$/); if (match) process.env[match[1]] = match[2]; }); } const WP_URL = 'https://almeiraproducciones.com/wp-json/wp/v2'; const ENDPOINT = process.env.NEXT_PUBLIC_APPWRITE_ENDPOINT; const PROJECT_ID = process.env.NEXT_PUBLIC_APPWRITE_PROJECT_ID; const API_KEY = process.env.APPWRITE_API_KEY; const client = new Client(); client.setEndpoint(ENDPOINT).setProject(PROJECT_ID).setKey(API_KEY); const databases = new Databases(client); const storage = new Storage(client); const DB_ID = 'almeira'; const BUCKET_ID = 'media_bucket'; async function importCategories() { console.log("--- Importando Categorías ---"); let page = 1; let totalCategories = 0; while(true) { try { const resp = await axios.get(`${WP_URL}/categories?per_page=100&page=${page}`); const wpCategories = resp.data; if (wpCategories.length === 0) break; for (const cat of wpCategories) { // Verificar si existe const existing = await databases.listDocuments(DB_ID, 'categories', [ Query.equal('slug', cat.slug) ]); if (existing.total === 0) { await databases.createDocument(DB_ID, 'categories', ID.unique(), { nombre: cat.name, slug: cat.slug }); console.log(`+ Categoría creada: ${cat.name}`); } else { console.log(`~ Categoría ya existe: ${cat.name}`); } } page++; totalCategories += wpCategories.length; } catch (e) { break; } } console.log(`Total categorías procesadas: ${totalCategories}`); } async function importMediaBatch(limit = 10) { console.log(`--- Importando Lote de Medios (Límite: ${limit}) ---`); let page = 1; let count = 0; while(count < limit) { try { const resp = await axios.get(`${WP_URL}/media?per_page=100&page=${page}`); const wpMedia = resp.data; if (wpMedia.length === 0) break; for (const media of wpMedia) { if (count >= limit) break; // Verificar si ya existe el medio en la colección const existing = await databases.listDocuments(DB_ID, 'media', [ Query.equal('file_id', `wp_${media.id}`) ]); if (existing.total === 0) { try { // Descargar imagen const imgResp = await axios.get(media.source_url, { responseType: 'arraybuffer' }); const tempPath = path.join('/tmp', `wp_${media.id}_${path.basename(media.source_url)}`); fs.writeFileSync(tempPath, imgResp.data); // Subir a Storage const file = await storage.createFile(BUCKET_ID, `wp_${media.id}`, InputFile.fromPath(tempPath, path.basename(tempPath))); // Crear registro en colección 'media' await databases.createDocument(DB_ID, 'media', ID.unique(), { file_id: file.$id, bucket_id: BUCKET_ID, titulo: media.title.rendered || 'Sin título', alt_text: media.alt_text || '', tipo: 'imagen' }); console.log(`+ Medio subido: ${media.id}`); fs.unlinkSync(tempPath); } catch (uploadErr) { console.error(`! Error subiendo medio ${media.id}:`, uploadErr.message); } } count++; } page++; } catch (e) { console.error(e.message); break; } } } async function importPosts(limit = 5) { console.log(`--- Importando Lote de Posts (Límite: ${limit}) ---`); let page = 1; let count = 0; // Obtener ID del tipo de publicación 'noticia' const types = await databases.listDocuments(DB_ID, 'publication_types', [ Query.equal('codigo', 'NOTICIA') ]); const tipoNoticiaId = types.total > 0 ? types.documents[0].$id : null; if (!tipoNoticiaId) { console.error("No se encontró el tipo de publicación 'NOTICIA'."); return; } while(count < limit) { try { const resp = await axios.get(`${WP_URL}/posts?per_page=20&page=${page}`); const wpPosts = resp.data; if (wpPosts.length === 0) break; for (const post of wpPosts) { if (count >= limit) break; const existing = await databases.listDocuments(DB_ID, 'posts', [ Query.equal('slug', post.slug) ]); if (existing.total === 0) { try { const data = { titulo: post.title.rendered, slug: post.slug, tipo: 'noticia', contenido: post.content.rendered, resumen_redes: post.excerpt.rendered.replace(/<[^>]*>?/gm, '').substring(0, 500), fecha_publicacion: new Date(post.date).toISOString(), estado: post.status === 'publish' ? 'publicado' : 'borrador', tipo_publicacion_id: tipoNoticiaId, seo_titulo: post.title.rendered.substring(0, 60), seo_descripcion: post.excerpt.rendered.replace(/<[^>]*>?/gm, '').substring(0, 160) }; // Imagen destacada? if (post.featured_media > 0) { const mediaDoc = await databases.listDocuments(DB_ID, 'media', [ Query.equal('file_id', `wp_${post.featured_media}`) ]); if (mediaDoc.total > 0) { data.imagen_destacada_id = mediaDoc.documents[0].$id; } } await databases.createDocument(DB_ID, 'posts', ID.unique(), data); console.log(`+ Post importado: ${post.title.rendered}`); } catch (postErr) { console.error(`! Error importando post ${post.id}:`, postErr.message); } } else { console.log(`~ Post ya existe: ${post.slug}`); } count++; } page++; } catch (e) { console.error(e.message); break; } } } async function run() { try { await importCategories(); // Importamos toda la biblioteca de medios disponible await importMediaBatch(6000); // Importamos todas las publicaciones disponibles await importPosts(6000); console.log("--- MIGRACIÓN COMPLETADA ---"); } catch (e) { console.error("ERROR CRÍTICO:", e); } } run();