141 lines
5.2 KiB
JavaScript
141 lines
5.2 KiB
JavaScript
const fs = require('fs');
|
|
const path = require('path');
|
|
const { execSync } = require('child_process');
|
|
const { Client, Databases, ID } = require('node-appwrite');
|
|
require('dotenv').config({ path: '.env.local' });
|
|
const mammoth = require('mammoth');
|
|
|
|
const client = new Client()
|
|
.setEndpoint(process.env.NEXT_PUBLIC_APPWRITE_ENDPOINT)
|
|
.setProject(process.env.NEXT_PUBLIC_APPWRITE_PROJECT_ID)
|
|
.setKey(process.env.APPWRITE_API_KEY);
|
|
|
|
const databases = new Databases(client);
|
|
const dbId = process.env.APPWRITE_DATABASE_ID;
|
|
const collectionId = 'posts';
|
|
const defaultTipoPublicacionId = '69c2b91400362d5d52b6'; // NOTICIA
|
|
|
|
const DIR_PENDIENTES = '/home/carlos/Documentos/Pendientes';
|
|
|
|
function generateSlug(titulo) {
|
|
return titulo.toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g, '').replace(/[^a-z0-9\s-]/g, '').trim().replace(/\s+/g, '-').replace(/-+/g, '-').substring(0, 100);
|
|
}
|
|
|
|
function truncateString(str, length) {
|
|
if (!str) return '';
|
|
return str.length > length ? str.substring(0, length - 3) + '...' : str;
|
|
}
|
|
|
|
function extractDate(filename) {
|
|
const regex = /(\d{1,2})\s+DE\s+([A-Z]+)\s+DEL?\s+(\d{4})/i;
|
|
const match = filename.match(regex);
|
|
if (match) {
|
|
const months = { 'enero': 0, 'febrero': 1, 'marzo': 2, 'abril': 3, 'mayo': 4, 'junio': 5, 'julio': 6, 'agosto': 7, 'septiembre': 8, 'octubre': 9, 'noviembre': 10, 'diciembre': 11 };
|
|
const monthStr = match[2].toLowerCase();
|
|
if (months[monthStr] !== undefined) {
|
|
return new Date(parseInt(match[3], 10), months[monthStr], parseInt(match[1], 10), 12, 0, 0).toISOString();
|
|
}
|
|
}
|
|
return new Date().toISOString();
|
|
}
|
|
|
|
function extractDriveUrl(text) {
|
|
const match = text.match(/https:\/\/drive\.google\.com\/[^\s\n]+/);
|
|
return match ? match[0] : null;
|
|
}
|
|
|
|
async function insertPost(title, contentBlocks, driveUrl, filename) {
|
|
if (!title || contentBlocks.length === 0) return;
|
|
|
|
let pureContent = contentBlocks.filter(b => !b.includes('http')).map(p => `<p>${p}</p>`).join('');
|
|
|
|
const docData = {
|
|
titulo: truncateString(title, 70),
|
|
slug: generateSlug(title) + '-' + Math.random().toString(36).substring(2, 7),
|
|
contenido: pureContent,
|
|
resumen_redes: truncateString(contentBlocks[0], 155),
|
|
seo_titulo: truncateString(title, 60),
|
|
seo_descripcion: truncateString(contentBlocks[0], 155),
|
|
estado: 'borrador',
|
|
tipo_publicacion_id: defaultTipoPublicacionId,
|
|
fecha_publicacion: extractDate(filename),
|
|
...(driveUrl && { url_destino: driveUrl })
|
|
};
|
|
|
|
try {
|
|
await databases.createDocument(dbId, collectionId, ID.unique(), docData);
|
|
console.log(`✅ Creado: ${docData.titulo}`);
|
|
} catch (e) {
|
|
console.error(`❌ Error en ${title}:`, e.message);
|
|
}
|
|
}
|
|
|
|
async function processFile(filePath, filename) {
|
|
const ext = path.extname(filename).toLowerCase();
|
|
|
|
if (ext === '.docx') {
|
|
const result = await mammoth.extractRawText({ path: filePath });
|
|
const lines = result.value.split('\n').map(l => l.trim()).filter(l => l.length > 0);
|
|
if (lines.length > 0) {
|
|
const title = lines[0];
|
|
const contentBlocks = lines.slice(1);
|
|
const driveUrl = extractDriveUrl(result.value);
|
|
await insertPost(title, contentBlocks, driveUrl, filename);
|
|
}
|
|
} else if (ext === '.pdf') {
|
|
const text = execSync(`pdftotext "${filePath}" -`).toString();
|
|
const pages = text.split('\x0C').map(p => p.trim()).filter(p => p.length > 0);
|
|
|
|
for (const page of pages) {
|
|
const lines = page.split('\n').map(l => l.trim()).filter(l => l.length > 0);
|
|
if (lines.length < 3) continue;
|
|
|
|
let startIndex = 0;
|
|
if (lines[0].toLowerCase().includes('boletín')) {
|
|
startIndex = 1; // skip header
|
|
}
|
|
|
|
const title = lines[startIndex];
|
|
const contentBlocks = [];
|
|
let currentBlock = [];
|
|
for (let i = startIndex + 1; i < lines.length; i++) {
|
|
currentBlock.push(lines[i]);
|
|
if (lines[i].endsWith('.') || lines[i].includes('http')) {
|
|
contentBlocks.push(currentBlock.join(' '));
|
|
currentBlock = [];
|
|
}
|
|
}
|
|
if (currentBlock.length > 0) contentBlocks.push(currentBlock.join(' '));
|
|
|
|
const driveUrl = extractDriveUrl(page);
|
|
await insertPost(title, contentBlocks, driveUrl, filename);
|
|
}
|
|
}
|
|
}
|
|
|
|
async function main() {
|
|
let files = fs.readdirSync(DIR_PENDIENTES).filter(f => f.endsWith('.pdf') || f.endsWith('.docx'));
|
|
|
|
files.sort((a, b) => {
|
|
const numA = parseInt(a.match(/\d+/)) || 0;
|
|
const numB = parseInt(b.match(/\d+/)) || 0;
|
|
return numA - numB;
|
|
});
|
|
|
|
// Only March and April: Boletines 22 to 37
|
|
files = files.filter(f => {
|
|
const num = parseInt(f.match(/\d+/)) || 0;
|
|
return num >= 22 && num <= 37;
|
|
});
|
|
|
|
console.log(`Procesando ${files.length} archivos de Marzo y Abril...`);
|
|
|
|
for (const file of files) {
|
|
console.log(`\n📄 Iniciando: ${file}`);
|
|
await processFile(path.join(DIR_PENDIENTES, file), file);
|
|
}
|
|
console.log('\n¡Proceso finalizado!');
|
|
}
|
|
|
|
main();
|