diff --git a/src/services/scheduledPostsRunner.js b/src/services/scheduledPostsRunner.js index 558377b..a422934 100644 --- a/src/services/scheduledPostsRunner.js +++ b/src/services/scheduledPostsRunner.js @@ -202,10 +202,39 @@ async function publishOne(scheduledPost) { } } else if (useCover && channel.auto_publish_with_cover) { if (article.cover_url) { - photoUrl = article.cover_url.startsWith('http') - ? article.cover_url - : `https://zeropost.ru${article.cover_url}`; - console.log(`[scheduled-runner] cover=${article.cover_url.split('/').pop()} article=${article.id}`); + // Проверяем что обложка реальная, а не SVG-заглушка (< 30KB) + const localCoverPath = path.join(UPLOADS_DIR, article.cover_url.replace(/^\/uploads\//, '')); + let coverIsReal = true; + try { + const stat = fs.statSync(localCoverPath); + if (stat.size < 30 * 1024) { + coverIsReal = false; + console.log(`[scheduled-runner] SVG stub (${Math.round(stat.size/1024)}KB), regen article=${article.id}`); + try { + const covers = require('./covers'); + await covers.generateCover({ articleId: article.id, title: article.title, tags: article.tags || [], channelId: channel.id }); + const { rows: refreshed } = await query('SELECT cover_url FROM articles WHERE id=$1', [article.id]); + if (refreshed[0]?.cover_url) article.cover_url = refreshed[0].cover_url; + coverIsReal = true; + console.log(`[scheduled-runner] regen OK article=${article.id}`); + } catch(regenErr) { + console.warn(`[scheduled-runner] regen failed, using Zero: ${regenErr.message.slice(0,80)}`); + } + } + } catch(_) { /* внешний URL или файл не найден — считаем реальным */ } + + if (coverIsReal) { + photoUrl = article.cover_url.startsWith('http') + ? article.cover_url + : `https://zeropost.ru${article.cover_url}`; + console.log(`[scheduled-runner] cover=${article.cover_url.split('/').pop()} article=${article.id}`); + } else { + const picked = zeroChar.pickPose({ title: article.title, excerpt: article.excerpt, category: article.category }); + if (picked.exists) { + photoUrl = `/uploads/zero-${picked.pose}.webp`; + console.log(`[scheduled-runner] SVG fallback → Zero pose=${picked.pose} article=${article.id}`); + } + } } else { // Обложки нет (ещё генерируется) — fallback на Зеро const picked = zeroChar.pickPose({