feat: image rubrics with AI selection for cover variety
- channel_style.image_rubrics (JSONB): 6 рубрик для ZeroPost-блога (tech-photo, 3d-device, code-screen, data-flow, ai-neural, cinematic-tech) - selectRubric(): haiku выбирает рубрику по заголовку+тегам статьи - generateCover(): загружает rubrics из БД, вызывает selectRubric перед генерацией - buildCoverPrompt(): принимает rubric — рубрика задаёт весь визуальный язык - Убраны лишние ограничения (no circuit boards, no glowing nodes, no brains) из базового промпта — теперь только: no text, no logos, no real faces
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
require('dotenv').config({ path: '/var/www/zeropost-engine/.env' });
|
||||
process.chdir('/var/www/zeropost-engine');
|
||||
|
||||
const covers = require('./src/services/covers');
|
||||
const config = require('./src/config');
|
||||
const { query } = require('./src/config/db');
|
||||
|
||||
const DELAY_MS = 8000;
|
||||
const sleep = ms => new Promise(r => setTimeout(r, ms));
|
||||
|
||||
(async () => {
|
||||
await config.reloadAi();
|
||||
const { rows } = await query('SELECT id, title, tags FROM articles WHERE cover_url IS NOT NULL ORDER BY id');
|
||||
console.log(`Total articles: ${rows.length}`);
|
||||
|
||||
let ok = 0, fail = 0;
|
||||
for (const a of rows) {
|
||||
try {
|
||||
console.log(`\n[${ok+fail+1}/${rows.length}] article=${a.id}: ${a.title.slice(0,60)}`);
|
||||
const url = await covers.generateCover({ articleId: a.id, title: a.title, tags: a.tags||[], channelId: 1 });
|
||||
console.log(` ✓ ${url}`);
|
||||
ok++;
|
||||
} catch(e) {
|
||||
console.log(` ✗ FAIL: ${e.message.slice(0,100)}`);
|
||||
fail++;
|
||||
}
|
||||
if (ok + fail < rows.length) await sleep(DELAY_MS);
|
||||
}
|
||||
|
||||
console.log(`\nDone: ${ok} OK, ${fail} failed`);
|
||||
process.exit(0);
|
||||
})().catch(e => { console.error(e); process.exit(1); });
|
||||
Reference in New Issue
Block a user