fix: cover image variety — concrete metaphors + articleId cycling
getVisualMetaphor(): - articleId % array.length как чистый индекс цикличности - Метафоры конкретные/материальные (ключи, телескопы, часы, книги) вместо абстрактных neural nodes которые все выглядят одинаково - AI категория: 14 метафор (повтор через 14 статей = ~5 дней) - 11 тематических категорий + 15 универсальных
This commit is contained in:
+113
-59
@@ -167,7 +167,7 @@ function buildCoverPrompt({ title, tags = [], articleId = 0, channelStyle = null
|
||||
paletteDesc = PALETTES[channelStyle.image_palette] || null;
|
||||
}
|
||||
|
||||
const visualMetaphor = getVisualMetaphor(title, tags);
|
||||
const visualMetaphor = getVisualMetaphor(title, tags, articleId);
|
||||
|
||||
return `Create a wide 16:9 editorial cover illustration.
|
||||
|
||||
@@ -183,112 +183,166 @@ ${channelStyle?.image_prompt_instructions ? `\nCHANNEL STYLE: ${channelStyle.ima
|
||||
RULE: absolutely no text, no letters, no words, no logos, no real human faces.`;
|
||||
}
|
||||
|
||||
function getVisualMetaphor(title, tags = []) {
|
||||
/**
|
||||
* Возвращает уникальную визуальную метафору для обложки.
|
||||
* articleId гарантирует уникальность даже при одинаковой теме.
|
||||
* Метафоры — конкретные, материальные, не абстрактные.
|
||||
*/
|
||||
function getVisualMetaphor(title, tags = [], articleId = 0) {
|
||||
const t = (title + ' ' + tags.join(' ')).toLowerCase();
|
||||
|
||||
// Чистый index по articleId — каждая новая статья = следующая метафора в цикле
|
||||
// Гарантирует повторение только через N статей (N = кол-во метафор в категории)
|
||||
function pick(arr) { return arr[articleId % arr.length]; }
|
||||
|
||||
// Тематические паттерны → конкретные визуальные метафоры
|
||||
const patterns = [
|
||||
{ kw: ['взлом', 'хакер', 'атак', 'уязвим', 'безопасн', 'hack', 'secur', 'cyber', 'exploit', 'inject', 'фишинг'],
|
||||
{ kw: ['взлом', 'хакер', 'атак', 'уязвим', 'безопасн', 'hack', 'secur', 'cyber', 'exploit', 'inject', 'фишинг', 'ransomware'],
|
||||
metaphors: [
|
||||
'A digital lock being opened by invisible force, streams of binary code dissolving into particles',
|
||||
'Abstract shield shattering into geometric fragments, neon cracks spreading through dark digital surface',
|
||||
'A labyrinth of glowing circuits with a single thread breaking through a barrier',
|
||||
'Mirror reflecting a distorted version of itself, duality and deception made abstract',
|
||||
'A vintage combination lock under ultraviolet light, tumblers glowing, one tumbler broken open — dark industrial background',
|
||||
'A glass door with a hairline crack spreading across its surface, red light leaking through the fracture',
|
||||
'An old steel safe with its door hanging open, interior papers spilling out, emergency light casting harsh shadows',
|
||||
'A chain with one shattered link, chrome and steel, dramatic spotlight on the break point',
|
||||
'An antique key duplicating itself in a hall of mirrors, each copy slightly distorted',
|
||||
'A fingerprint dissolving into scattered pixels under a magnifying glass, neon forensic lab aesthetic',
|
||||
'A locked filing cabinet surrounded by floating question marks and warning symbols, cinematic lighting',
|
||||
]
|
||||
},
|
||||
{ kw: ['ии', ' ai ', 'нейро', 'llm', 'gpt', 'claude', 'модел', 'neural', 'machine learn', 'deep learn', 'искусственн'],
|
||||
{ kw: ['ии', ' ai ', 'нейро', 'llm', 'gpt', 'claude', 'модел', 'neural', 'machine learn', 'deep learn', 'искусственн', 'chatgpt'],
|
||||
metaphors: [
|
||||
'Abstract neural network nodes pulsing with light, interconnected pathways branching into infinity',
|
||||
'A geometric brain lattice dissolving at the edges into streams of luminous particles',
|
||||
'Floating data cubes assembling themselves into emergent patterns, representing machine cognition',
|
||||
'Concentric rings of light expanding outward from a central pulsing node',
|
||||
'A vintage typewriter whose keys are being pressed by invisible force, paper emerging with text forming itself',
|
||||
'An hourglass where sand flows upward, each grain transforming into a tiny glowing letter',
|
||||
'A book opening by itself in a dark library, pages turning rapidly, text rearranging mid-air',
|
||||
'An old brass telescope pointed at a sky full of equations instead of stars',
|
||||
'A clay sculpture being shaped by invisible hands, smooth surfaces revealing complex geometry underneath',
|
||||
'A single candle flame in darkness, its shadow casting a complex branching pattern on the wall behind',
|
||||
'A compass spinning wildly then settling on a new direction, surrounded by scattered maps and charts',
|
||||
'A chess queen piece casting a shadow of an entire army, dramatic chiaroscuro lighting',
|
||||
'An optical prism splitting white light into spectrum, mounted on dark velvet, macro photography',
|
||||
'A moth drawn to a glowing lamp, dozens of moths circling, long exposure photography blur',
|
||||
'A seed germinating in time-lapse, roots and shoots emerging simultaneously, dark soil background',
|
||||
'A master key on a ring of different keys, held up to light, warm metal tones',
|
||||
'A musician tuning an instrument by ear, close-up on hands on strings, warm studio light',
|
||||
'A cartographer sketching an unmapped territory, hand drawing a coastline into blank space',
|
||||
]
|
||||
},
|
||||
{ kw: ['автомат', 'бот', 'automat', 'workflow', 'pipeline', 'скрипт', 'robot', 'n8n', 'make ', 'zapier'],
|
||||
{ kw: ['автомат', 'бот', 'automat', 'workflow', 'pipeline', 'скрипт', 'robot', 'n8n', 'make ', 'zapier', 'automation'],
|
||||
metaphors: [
|
||||
'Elegant gears of light meshing perfectly, each tooth sparking as they turn in unison',
|
||||
'Abstract conveyor belt transforming raw geometric shapes into refined crystalline forms',
|
||||
'Overlapping circular flow arrows suggesting perpetual automation, each loop more refined',
|
||||
'Vintage clockwork mechanism — interlocking brass gears in motion, warm amber light, macro detail',
|
||||
'A factory assembly line condensed to a tabletop, tiny objects moving through stages, long exposure light trails',
|
||||
'A domino chain in the moment of falling, each domino a different color, motion blur',
|
||||
'A switchboard operator desk with hundreds of cables connecting ports, warm retro office lighting',
|
||||
'Pipes of different materials connecting and merging into one clean output pipe, industrial workshop',
|
||||
'A rube goldberg sequence frozen in time, multiple contraptions mid-action',
|
||||
'Time-lapse of a city intersection at night, light trails forming perfect flow patterns',
|
||||
]
|
||||
},
|
||||
{ kw: ['данн', 'аналит', 'data', 'analyt', 'метрик', 'статист', 'chart', 'график'],
|
||||
{ kw: ['данн', 'аналит', 'data', 'analyt', 'метрик', 'статист', 'chart', 'график', 'seo'],
|
||||
metaphors: [
|
||||
'Rivers of light converging from edges to a bright focal point, order emerging from streams',
|
||||
'Translucent scatter plot in 3D space, clusters of meaning floating in abstract dimension',
|
||||
'Cascading data streams transforming from chaotic noise into clean organized patterns',
|
||||
'A vintage stock ticker machine printing endless paper tape, trading floor atmosphere',
|
||||
'A weather station with multiple instruments all pointing to extremes, storm approaching',
|
||||
'Cartographer desk with overlapping transparent maps, pins and measurements, candlelight',
|
||||
'A microscope slide with a complex pattern of cells, lab setting, precise clinical lighting',
|
||||
'Library card catalog system with infinite drawers, one drawer pulled open revealing complex index',
|
||||
'A piano with sheet music where the notes form bar chart patterns, concert hall lighting',
|
||||
'A surveyor theodolite in a field, precision instruments against a dramatic sky',
|
||||
]
|
||||
},
|
||||
{ kw: ['дипфейк', 'голос', 'deepfake', 'voice', 'fraud', 'fake', 'мошенн'],
|
||||
metaphors: [
|
||||
'A face dissolving at the edges into a mosaic of pixels, the real becoming uncertain',
|
||||
'Abstract mask layered over another mask, shadow figures suggesting layered identity',
|
||||
'Two mirrors facing each other creating infinite regress, reality and reflection indistinguishable',
|
||||
'A wax museum figure melting slightly at the edges, museum spotlights, uncanny valley',
|
||||
'Two theatrical masks — comedy and tragedy — but identical, hanging in spotlight',
|
||||
'A reflection in water that is slightly different from what stands above it, twilight mood',
|
||||
'Vintage photobooth with curtain closed, multiple shadow silhouettes visible through fabric',
|
||||
'A hand puppet casting a human-shaped shadow on a wall, single dramatic light source',
|
||||
'A mirror cracked down the middle, each half showing a different scene',
|
||||
]
|
||||
},
|
||||
{ kw: ['код', 'разработ', 'програм', 'code', 'develop', 'software', 'api', 'github', 'cursor', 'copilot'],
|
||||
metaphors: [
|
||||
'Layers of abstract code symbols transforming into crystalline architectural structures',
|
||||
'A branching tree of glowing paths, each fork representing choices in logic flow',
|
||||
'Floating geometric modules snapping together like elegant puzzle pieces in zero gravity',
|
||||
'A craftsman workbench covered in tools, each precisely placed, wood shavings on floor, workshop window light',
|
||||
'An architect drafting table with blueprints unrolled, compass and ruler in use, desk lamp',
|
||||
'A vintage telephone exchange switchboard, operator perspective, warm bulb lights',
|
||||
'Knitting needles mid-row on a complex pattern, wool threads crossing precisely, natural light',
|
||||
'A mason building a wall one brick at a time, each brick a different texture, golden hour',
|
||||
'An open laptop in a dark room, only the screen light illuminating the workspace, code reflection on glasses',
|
||||
]
|
||||
},
|
||||
{ kw: ['seo', 'маркетинг', 'контент', 'реклам', 'marketing', 'content', 'growth', 'продвиж'],
|
||||
{ kw: ['маркетинг', 'контент', 'реклам', 'marketing', 'content', 'growth', 'продвиж', 'аудитор'],
|
||||
metaphors: [
|
||||
'Abstract particles rising in an upward spiral, accelerating as they approach the light',
|
||||
'Geometric shapes spontaneously organizing from scattered chaos into perfect aligned grid',
|
||||
'A single beam cutting through layered fog, illuminating a clear path forward',
|
||||
'A megaphone lying on a table, vintage brass, city map spread underneath it',
|
||||
'A fishing rod cast into a sea of business cards, one card caught on the hook',
|
||||
'A vendor market stall being set up, colorful awning, products arranged attractively, morning light',
|
||||
'Seeds being planted in geometric rows, birds-eye view, garden tools aside, spring light',
|
||||
'A lighthouse beam sweeping over a foggy harbor, ships turning toward the light',
|
||||
'A street performer drawing a large crowd, performer perspective from stage, golden sunset',
|
||||
]
|
||||
},
|
||||
{ kw: ['email', 'рассылк', 'письм', 'newsletter', 'inbox'],
|
||||
metaphors: [
|
||||
'Paper planes of light streaming outward from a central pulsing source in all directions',
|
||||
'Abstract envelopes unfolding into origami shapes that take flight as geometric birds',
|
||||
'Digital waves radiating concentrically outward, each ring more refined and intentional',
|
||||
'A vintage mailbox overflowing with envelopes, country road, afternoon light',
|
||||
'A writing desk with fountain pen mid-sentence on paper, wax seal nearby, window light',
|
||||
'Hundreds of paper airplanes suspended in air radiating from a single point, white room',
|
||||
'A postal sorting office with letters on conveyor, warm institutional lighting',
|
||||
'A message in a bottle washing ashore, ocean at golden hour, single perfect wave',
|
||||
]
|
||||
},
|
||||
{ kw: ['vector', 'embed', 'pinecone', 'база знаний', 'rag ', 'retriev', 'weaviate', 'pgvector'],
|
||||
{ kw: ['prompt', 'промпт', 'инжиниринг', 'instruct', 'few-shot', 'chain', 'копирайт'],
|
||||
metaphors: [
|
||||
'Multi-dimensional space: glowing constellation points clustering by invisible forces of meaning',
|
||||
'Abstract geometric lattice stretching to infinity, nodes connected by silk-thin lines',
|
||||
'A library of light — glowing geometric books organized in vast abstract infinite space',
|
||||
'A sculptor chiseling marble, chips flying, emerging form just visible, dramatic studio lighting',
|
||||
'A translator desk with multiple open dictionaries and handwritten notes between them',
|
||||
'A cook adjusting seasoning over a pot, herbs and spices scattered artfully on counter',
|
||||
'A jeweler using loupe to set a tiny gem, precision tools, warm workshop light',
|
||||
'A conductor baton frozen mid-gesture, orchestra music sheets visible below',
|
||||
]
|
||||
},
|
||||
{ kw: ['prompt', 'промпт', 'инжиниринг', 'instruct', 'few-shot', 'chain'],
|
||||
{ kw: ['vector', 'embed', 'база знаний', 'rag ', 'pinecone', 'weaviate', 'langchain', 'llamaindex'],
|
||||
metaphors: [
|
||||
'Abstract command flowing as light through a series of transforming geometric gates',
|
||||
'A sculptor chisel made of light, shaping formless material into precise form',
|
||||
'Words becoming shapes becoming outcomes — a visual sequence of transformation',
|
||||
'A vast library card catalog extending to infinite depth, one card pulled mid-search',
|
||||
'A specimen collection in glass cases, each specimen precisely labeled, natural history museum',
|
||||
'A wine cellar with bottles organized in a complex system, sommelier consulting notes',
|
||||
'A large cork pinboard covered in photos and strings connecting them, detective war room',
|
||||
'A seed bank vault with thousands of labeled drawers, clinical cold light',
|
||||
]
|
||||
},
|
||||
{ kw: ['продуктив', 'задач', 'workflow', 'менеджмент', 'таск', 'task', 'agile', 'sprint'],
|
||||
metaphors: [
|
||||
'A physical inbox/outbox tray system stacked high on wooden desk, morning office light',
|
||||
'A large whiteboard covered in sticky notes being organized by unseen hands',
|
||||
'A craftsman apron with every tool in its pocket, each in perfect order',
|
||||
'Calendar pages turning on a desk, one date circled in red, pen nearby',
|
||||
]
|
||||
},
|
||||
];
|
||||
|
||||
for (const { kw, metaphors } of patterns) {
|
||||
if (kw.some(k => t.includes(k))) {
|
||||
// Детерминированный но разнообразный выбор по хешу заголовка
|
||||
let seed = 0;
|
||||
for (let i = 0; i < title.length; i++) seed = (seed * 31 + title.charCodeAt(i)) >>> 0;
|
||||
return metaphors[seed % metaphors.length];
|
||||
return pick(metaphors);
|
||||
}
|
||||
}
|
||||
|
||||
// Универсальные метафоры — конкретные и разнообразные
|
||||
const generic = [
|
||||
'Abstract architectural forms assembling from scattered fragments into a coherent whole',
|
||||
'Geometric light rays converging from multiple directions into a single illuminated focal point',
|
||||
'Flowing liquid-like shapes morphing and transforming, suggesting evolution and emergence',
|
||||
'A horizon where two contrasting worlds meet — ordered and organic — in perfect visual tension',
|
||||
'Cascading layers of translucent geometric planes revealing depth and hidden complexity',
|
||||
'Crystalline growth pattern emerging organically from a single seed point into elaborate structure',
|
||||
'Diagonal force lines cutting through deep negative space with directional energy and purpose',
|
||||
'Nested geometric forms expanding outward from center like a visual echo in still water',
|
||||
'Abstract topography of peaks and valleys formed by data, landscape of pure information',
|
||||
'A vortex of geometric elements spiraling inward toward a luminous center of clarity',
|
||||
'A single lighthouse on a rocky coast at dusk, warm light in the tower, storm approaching from sea',
|
||||
'A vintage globe being spun by unseen hands, old map colors, library atmosphere',
|
||||
'A hand planting a seed in rich dark soil, morning mist in background, close-up',
|
||||
'An empty stage with a single spotlight on a plain wooden chair, theatre atmosphere',
|
||||
'A vintage compass on a worn leather journal, mountain wilderness in background',
|
||||
'A mason jar filled with fireflies, summer night, porch railing, blurred trees behind',
|
||||
'An old film projector casting beam of light, dust particles visible, cinema darkness',
|
||||
'A door slightly ajar, warm light escaping, curious perspective from hallway',
|
||||
'A ladder leaning against a wall reaching above the clouds, surreal realistic style',
|
||||
'A single match being struck in complete darkness, dramatic flare, close-up',
|
||||
'A crossroads sign pointing in four different directions, fog, gravel road, dawn',
|
||||
'A paper boat on still water, single ripple expanding outward, minimalist',
|
||||
'An old radio being tuned, backlit frequency dial, warm evening light',
|
||||
'A telescope pointed skyward from a rooftop, city lights below, stars above',
|
||||
'A bridge in fog, one end visible, other end disappearing into mist, pedestrian perspective',
|
||||
];
|
||||
|
||||
let seed = 0;
|
||||
for (let i = 0; i < title.length; i++) seed = (seed * 31 + title.charCodeAt(i)) >>> 0;
|
||||
return generic[seed % generic.length];
|
||||
return pick(generic);
|
||||
}
|
||||
|
||||
|
||||
async function generateCoverViaRouterAI({ prompt }) {
|
||||
const base = config.ai.routeraiBaseUrl;
|
||||
const key = config.ai.routeraiApiKey;
|
||||
|
||||
Reference in New Issue
Block a user