almeira-web/import_wordpress.js

206 lines
7.7 KiB
JavaScript

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();