Files
hoelee-blog/scripts/og-gen/generate_prompts_catalog.py
T
hoelee a41448bb4a feat(og-gen): check in the v2 art pipeline and its batch renderer
The consultant-approved "one art, four targets" work existed only in the
working tree. Commit it so the 72-post rollout is reproducible from the repo
instead of from one session's scratch files.

- template-v2.html / v2.1 / v2.2: the iteration the consultant reviewed, plus
  the accepted frosted-bento layout (736x536 card, blueprint grid, full-width
  evidence bar, self-fitting headline script that reports "FIT <n>px").
- render_sample_suite{,_v2,_v3}.mjs + fit-title-probe.mjs: how the two sample
  posts were rendered for rounds 2-4 (kept for provenance).
- generate_prompts_catalog.py + prompts_catalog.json: the 72 per-post prompts
  and their visual metaphors, extracted from the posts themselves.
- render_from_art.mjs (new): the batch renderer. One zero-text base frame per
  post -> banner 1600x900 webp (+jpg fallback), social card 1200x630 (EN and
  zh-<slug>), thumbs 800x420 and 400x210. Cards are filled from frontmatter +
  art-meta.json; a missing evidence line or a headline that never settles is a
  hard failure, never a silently-degraded card.
- art-meta.json: the per-slug input contract. Two slugs wired; 70 still need
  base art (GPU) and a hand-written evidence line.
- README: documents the pipeline, the measured format choice (558 KB PNG ->
  84 KB mozjpeg q85) and the PostList thumb-helper trap when ogImage moves to
  .jpg.

Proof the renderer reproduces the accepted output: re-rendering the two sample
posts yields banner + 800px thumb files BYTE-IDENTICAL to the consultant's
delivery (sha256 16e6a7b0, f3b29f38, c4e28291, 8095ec6c), and all four cards
report FIT, 2-3 title lines, 2 description lines, 0 overflow in x and y.
2026-10-18 16:32:58 +08:00

199 lines
11 KiB
Python

import os, glob, yaml, json
posts = sorted(glob.glob('src/content/posts/*.md'))
ACCENTS = {
'devops': 'cyan and vibrant emerald green (#4ade80)',
'engineering': 'royal cobalt blue (#295cff) with crisp ice-white',
'ai': 'neon-cyan and electric violet-magenta',
'web3': 'translucent emerald (#10b981) and prism-split cyan',
'tutorials': 'electric cyan and soft ultraviolet spectrum',
'case-studies': 'emerald green (#4ade80) status nodes and gold telemetry',
'notes': 'warm amber-orange warning glow (#fbbf24)'
}
SPECIFIC_METAPHORS = {
'running-production-infrastructure-solo': (
'Three massive interconnected obsidian server monoliths, surrounded by dense floating micro-glass container matrices representing 162 modular services, routed by glowing fiber optic pipelines into a single master control console',
'162 containers · 3 hosts · 78 stacks'
),
'loop-engineering-without-a-coding-agent': (
'Eleven concentric circular obsidian gear loops rotating in mechanical harmony, eight solid pure crystal clockwork rings alongside three subtle neural pulse rings, operating autonomously without human intervention',
'11 cron jobs · 8 zero-AI loops'
),
'one-prometheus-for-unraid-synology-and-a-vps': (
'A single radiant central telemetry beacon sending precision laser monitoring vectors to three distinct hexagonal platform nodes, illuminating transparent storage volumes with holographic metrics',
'3 hosts · 1 prometheus · 0 false panels'
),
'self-healing-digital-goods-entitlements': (
'A multi-stage floating acrylic workflow pathway with five interlocking diamond gates, automatically self-repairing broken link fragments with glowing golden solder',
'5 workflows · NocoDB + n8n + AList'
),
'docker-reported-exit-0-the-oom-killer-disagreed': (
'A translucent glass server cube displaying a deceptive green heartbeat light, while a razor-sharp crimson kernel laser beam slices through its bottom core, scattering fractured memory crystals',
'exit 0 · dmesg: 6x cgroup OOM kills'
),
'my-backup-was-using-someone-elses-api-quota': (
'A massive high-throughput data conduit bottlenecked at a narrow glowing amber hourglass valve, only releasing single sparse droplets into a dark repository vault below',
'1 TB restic seed · shared rclone quota'
),
'calibrating-intel-quick-sync-hevc-quality': (
'A 3D topographic luminous video waveform mountain dropping abruptly off a 90-degree vertical cliff edge marked at 28, flanked by two perfectly identical overlapping optical calibration prisms',
'ICQ 18-22 vs 28 cliff · QSV measured'
),
'i-let-an-agent-manage-my-shopee-vouchers': (
'An intricate rotating glass agent decision loop, where an unexpected stray orange pulse vector veers off the blueprint track, materializing an unauthorized glowing geometric voucher card in mid-air',
'mode=propose gate · RM140 voucher unapproved'
),
'why-your-cdp-clicks-silently-fail': (
'A high-precision robotic cursor pointer clicking onto a translucent glass UI button that has already shifted away due to an invisible kinetic wave, triggering zero DOM resonance',
'scroll-behavior:smooth · rect expired'
),
'space-reclamation-wasnt-stuck-it-was-waiting': (
'A massive btrfs filesystem disk cylinder slowly draining fragmented blue blocks into an obsidian reclamation pit, guided by a precision holographic timer dial count down',
'121 GiB returned · scheduled 09:29'
),
'five-step-ai-roadmap-what-i-actually-run': (
'A five-tier architectural staircase in dark graphite, with the middle tiers brightly illuminated with active hardware racks while speculative top tiers remain skeletal wireframes',
'whisper + mem0 in production · step 4 skipped'
)
}
def derive_metaphor(title, desc, cat, tags):
title_l = title.lower()
desc_l = desc.lower()
if any(k in title_l for k in ['backup', 'restic', 'rclone']):
return (
'A secure armored cryptographic data vault connected by glowing braided conduit cables, archiving shimmering memory slabs into deep subterranean storage partitions',
'automated backup verification · zero-loss'
)
if any(k in title_l for k in ['container', 'docker', 'compose']):
return (
'Modular glowing cubic container blocks neatly docked into an industrial server chassis, synchronized by high-speed optic interconnects',
'containerized topology · isolated runtime'
)
if any(k in title_l for k in ['disk', 'smartctl', 'btrfs', 'nas', 'storage', 'raid']):
return (
'A precision laser diagnostic sensor scanning a floating high-density magnetic storage platter, revealing microscopic sector heatmaps',
'storage diagnostics · SMART telemetry'
)
if any(k in title_l for k in ['agent', 'llm', 'ai', 'gpt', 'token']):
return (
'Concentric acrylic rings of an autonomous neural decision core, pulsing with directed cyan synaptic data packets along vector paths',
'autonomous loop · constrained execution'
)
if any(k in title_l for k in ['dns', 'mail', 'postfix', 'mailcow', 'email']):
return (
'An intricate routing matrix of optical network fiber switches, filtering and directing packet envelopes through cryptographic security barriers',
'mail protocol routing · DKIM / SPF handshake'
)
if any(k in title_l for k in ['video', 'transcode', 'ffmpeg', 'hevc', 'audio', 'song']):
return (
'A cascading optical prism slicing raw video wavebands into ultra-compact high-efficiency spectral ribbons on a dark reflective surface',
'HEVC hardware pipeline · lossless fidelity'
)
if any(k in title_l for k in ['traefik', 'proxy', 'ssl', 'tls', 'nginx', 'cloudflare']):
return (
'An impenetrable dark-glass gateway perimeter routing colored ingress traffic streams through dynamic cryptographic reverse-proxy channels',
'reverse proxy routing · dynamic ingress'
)
if any(k in title_l for k in ['codeigniter', 'php', 'database', 'mysql', 'commit', 'churn', 'lines']):
return (
'Interlocking precision architectural pillars and modular computational foundations, supporting a clean crystalline software framework',
'verification gates · deterministic code'
)
# Generic high-tech fallbacks by category
if cat == 'devops':
return (
'Sleek industrial rackmount hardware with glowing diagnostic bus cables, routing high-throughput telemetry streams across redundant server clusters',
'production DevOps · verified metrics'
)
elif cat == 'ai':
return (
'An elegant geometric lattice core radiating structured synaptic energy pulses across an organized neural topological network',
'AI automation · deterministic controls'
)
elif cat == 'web3':
return (
'An isometric floating crystalline polyhedral block with precision laser-etched mathematical vectors and internal emerald prism reflections',
'on-chain verification · cryptographic math'
)
elif cat == 'tutorials':
return (
'A clean modular educational workbench of floating holographic schematic layers and precision calibration instruments',
'step-by-step telemetry · reproducible setup'
)
elif cat == 'case-studies':
return (
'An expansive architectural blueprint of enterprise private cloud nodes interconnected by luminous data pathways and telemetry readouts',
'enterprise delivery · real-world production'
)
else: # notes
return (
'A minimalist diagnostic probe examining a micro-structural hardware flaw illuminated by a subtle amber pinpoint warning light',
'root-cause analysis · production evidence'
)
catalog = []
for p in posts:
slug = os.path.basename(p)[:-3]
with open(p, 'r', encoding='utf-8') as f:
content = f.read()
parts = content.split('---')
if len(parts) < 3: continue
try: data = yaml.safe_load(parts[1])
except: continue
if data.get('draft'): continue
title = data.get('title', slug)
desc = data.get('description', '')
cat = data.get('category', 'engineering')
tags = data.get('tags', [])[:3]
accent = ACCENTS.get(cat, 'royal cobalt blue (#295cff)')
if slug in SPECIFIC_METAPHORS:
unique_elem, evidence = SPECIFIC_METAPHORS[slug]
else:
unique_elem, evidence = derive_metaphor(title, desc, cat, tags)
prompt = (
f"{unique_elem}, styled as a modern dark cyber-bento 3D concept and technical blueprint schematic. "
f"Sleek matte obsidian hardware, frosted acrylic glass surfaces, subtle ultra-thin blueprint coordinate crosshairs "
f"and vector topology lines in the background. Strictly off-center composition: the 3D focal subject is positioned "
f"exclusively in the right 38% of the canvas, leaving vast, clean, uncluttered dark negative space across the entire "
f"left 62% for UI overlay. Deep midnight slate background (#0b0f19 to #111827), volumetric rim lighting in royal blue (#4d82ff) "
f"with {accent} highlights, raytraced ambient occlusion, macro depth of field, 8k resolution, "
f"no text, no typography, no letters, no numbers, no HUD labels, no watermark."
)
catalog.append({
'slug': slug,
'title': title,
'category': cat,
'tags': tags,
'accent': accent,
'unique_elements': unique_elem,
'evidence_summary': evidence,
'prompt': prompt
})
os.makedirs('scripts/og-gen', exist_ok=True)
with open('scripts/og-gen/prompts_catalog.json', 'w', encoding='utf-8') as f:
json.dump(catalog, f, indent=2, ensure_ascii=False)
print(f"Generated complete prompts catalog for {len(catalog)} posts in scripts/og-gen/prompts_catalog.json")
out_md = "C:/Users/hoelee/Desktop/blog-og-image-redesign-brief/03-72-Posts-Visual-Prompts-Catalog.md"
with open(out_md, 'w', encoding='utf-8') as f:
f.write("# 72 篇技术文章专属视觉意象与 Prompt 全景目录 (Prompts Catalog)\n\n")
f.write("> 由 Hermes Agent 根据外部设计顾问定调公式自动提取生成:固定品牌底座 (60%) + 单篇专属独特隐喻 (40%)\n\n")
f.write("| # | 分类 | 文章 Slug 与标题 | 单篇专属物理隐喻与动作状态 | 硬核证据条摘要 |\n")
f.write("|---|---|---|---|---|\n")
for i, it in enumerate(catalog, 1):
f.write(f"| {i} | `{it['category']}` | **{it['title']}**<br>`{it['slug']}` | {it['unique_elements']} | `${it['evidence_summary']}` |\n")
print(f"Readable summary written to {out_md}")