147 lines
4.5 KiB
JavaScript
147 lines
4.5 KiB
JavaScript
import '@dotenvx/dotenvx/config';
|
|
import { readFileSync, readdirSync, existsSync } from 'fs';
|
|
import { join, dirname } from 'path';
|
|
import { fileURLToPath } from 'url';
|
|
|
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
const ROOT = join(__dirname, '..');
|
|
const NEWS_DIR = join(ROOT, 'src', 'content', 'news');
|
|
const LANGUAGES = ['es', 'en', 'fr', 'pt', 'rw', 'he', 'uk', 'ru', 'kr'];
|
|
|
|
function extractField(fm, field) {
|
|
const re = new RegExp(`^${field}:\\s*(.*)$`, 'm');
|
|
const m = fm.match(re);
|
|
if (!m) return '';
|
|
let val = m[1].trim();
|
|
if ((val.startsWith("'") && val.endsWith("'")) ||
|
|
(val.startsWith('"') && val.endsWith('"'))) {
|
|
val = val.slice(1, -1);
|
|
}
|
|
return val;
|
|
}
|
|
|
|
function parseMeta(filePath) {
|
|
const raw = readFileSync(filePath, 'utf-8');
|
|
const m = raw.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
if (!m) return {};
|
|
const fm = m[1];
|
|
return {
|
|
locale: extractField(fm, 'locale'),
|
|
title: extractField(fm, 'title'),
|
|
date: extractField(fm, 'date'),
|
|
draft: extractField(fm, 'draft'),
|
|
};
|
|
}
|
|
|
|
function normFilename(fileName) {
|
|
return fileName.replace(/\.md$/, '').replace(/-0(\d)$/, '-$1');
|
|
}
|
|
|
|
function main() {
|
|
const groups = {};
|
|
|
|
for (const lang of LANGUAGES) {
|
|
const dir = join(NEWS_DIR, lang);
|
|
if (!existsSync(dir)) continue;
|
|
|
|
for (const file of readdirSync(dir).filter(f => f.endsWith('.md'))) {
|
|
const meta = parseMeta(join(dir, file));
|
|
if (meta.draft === 'true') continue;
|
|
|
|
const key = normFilename(file);
|
|
if (!groups[key]) groups[key] = {};
|
|
groups[key][lang] = {
|
|
file,
|
|
title: meta.title || '',
|
|
date: meta.date || '',
|
|
};
|
|
}
|
|
}
|
|
|
|
const allKeys = Object.keys(groups).sort();
|
|
const esKeys = allKeys.filter(k => groups[k].es);
|
|
|
|
const summary = Object.fromEntries(LANGUAGES.map(l => {
|
|
const matches = esKeys.filter(k => groups[k][l]).length;
|
|
return [l, {
|
|
total: allKeys.filter(k => groups[k][l]).length,
|
|
translated: matches,
|
|
missing: esKeys.length - matches,
|
|
percent: esKeys.length > 0 ? Math.round((matches / esKeys.length) * 100) : 0,
|
|
}];
|
|
}));
|
|
|
|
const articles = esKeys.map(k => {
|
|
const es = groups[k].es;
|
|
return {
|
|
groupId: k,
|
|
date: es?.date || '',
|
|
spanishTitle: es?.title || '',
|
|
spanishFile: es?.file || '',
|
|
files: Object.fromEntries(LANGUAGES.map(l => [l, groups[k][l]?.file || null])),
|
|
};
|
|
});
|
|
|
|
const orphaned = allKeys.filter(k => !groups[k].es).map(k => ({
|
|
groupId: k,
|
|
languages: Object.keys(groups[k]),
|
|
files: Object.fromEntries(Object.keys(groups[k]).map(l => [l, groups[k][l].file])),
|
|
}));
|
|
|
|
const payload = {
|
|
timestamp: new Date().toISOString(),
|
|
source: 'cdrdpyj-postbuild',
|
|
site: 'centrodelreinodepazyjusticia.com',
|
|
summary,
|
|
articles,
|
|
orphaned,
|
|
totals: {
|
|
spanishArticles: esKeys.length,
|
|
totalGroups: allKeys.length,
|
|
orphanedArticles: orphaned.length,
|
|
languages: Object.fromEntries(LANGUAGES.map(l => {
|
|
const c = allKeys.filter(k => groups[k][l]).length;
|
|
return [l, c];
|
|
})),
|
|
},
|
|
};
|
|
|
|
const url = process.env.N8N_WEBHOOK_URL;
|
|
if (!url) {
|
|
console.log('[send-to-n8n] N8N_WEBHOOK_URL not set — showing sample payload');
|
|
console.log('Summary:', JSON.stringify(payload.summary, null, 2));
|
|
console.log('Sample articles (first 5):');
|
|
payload.articles.slice(0, 5).forEach(a => {
|
|
console.log(` ${a.groupId} | ${a.date} | ${a.spanishTitle.slice(0, 60)}...`);
|
|
const langs = Object.entries(a.files).filter(([_, v]) => v).map(([k]) => k).join(', ');
|
|
console.log(` → Present in: ${langs || 'ES only'}`);
|
|
});
|
|
if (payload.orphaned.length) {
|
|
console.log('Orphaned articles:');
|
|
payload.orphaned.forEach(o => console.log(` ${o.groupId} | languages: ${o.languages.join(', ')}`));
|
|
}
|
|
console.log(`[send-to-n8n] Total: ${articles.length} ES articles, ${orphaned.length} orphans`);
|
|
return;
|
|
}
|
|
|
|
const apiKey = process.env.N8N_API_KEY;
|
|
const apiKeyHeader = process.env.N8N_API_KEY_HEADER || 'X-API-Key';
|
|
const headers = { 'Content-Type': 'application/json' };
|
|
if (apiKey) headers[apiKeyHeader] = apiKey;
|
|
|
|
fetch(url, {
|
|
method: 'POST',
|
|
headers,
|
|
body: JSON.stringify(payload),
|
|
})
|
|
.then(r => {
|
|
if (!r.ok) throw new Error(`HTTP ${r.status} ${r.statusText}`);
|
|
console.log(`[send-to-n8n] OK — ${articles.length} ES articles, ${orphaned.length} orphans`);
|
|
})
|
|
.catch(e => {
|
|
console.error(`[send-to-n8n] Warning: n8n unreachable (${e.message}) — build continues`);
|
|
});
|
|
}
|
|
|
|
main();
|