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.
This commit is contained in:
1 parent
c09aeccc9c
commit
a41448bb4a
12 files changed
+2932
-1
No files matched your search
@@ -0,0 +1,198 @@
|
||||
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}")
|
||||
Reference in new issue
Block a user