feat: Archiv-Backfill, responsive Bilder und Site-Meta
Ergänzt Backfill- und Hilfsskripte, erzeugt nach der Pixazo-Generierung komprimierte srcset-Varianten, validiert leere Bilder und fügt Favicon, Web Manifest sowie Open-Graph-/Twitter-Tags in die Templates ein. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Create responsive image variants and patch existing HTML img tags."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
from generate import log, write_text_atomic
|
||||
from images import create_responsive_variants, iter_source_images
|
||||
|
||||
HERO_IMG_RE = re.compile(
|
||||
r'<img src="/img/(\d{4}-\d{2}-\d{2})\.jpg" alt="([^"]*)" width="560" height="420">'
|
||||
)
|
||||
THUMB_IMG_RE = re.compile(
|
||||
r'<img src="/img/(\d{4}-\d{2}-\d{2})\.jpg" alt="([^"]*)" width="360" height="203" loading="lazy">'
|
||||
)
|
||||
|
||||
|
||||
def patch_html_images(path: Path, descriptors: dict[str, dict[str, str]]) -> bool:
|
||||
html = path.read_text(encoding="utf-8")
|
||||
original = html
|
||||
|
||||
def replace_hero(match: re.Match[str]) -> str:
|
||||
date_iso, alt = match.group(1), match.group(2)
|
||||
image = descriptors.get(date_iso)
|
||||
if not image:
|
||||
return match.group(0)
|
||||
return (
|
||||
f'<img src="{image["src"]}" srcset="{image["srcset"]}" sizes="{image["sizes"]}" '
|
||||
f'alt="{alt}" width="560" height="420">'
|
||||
)
|
||||
|
||||
def replace_thumb(match: re.Match[str]) -> str:
|
||||
date_iso, alt = match.group(1), match.group(2)
|
||||
image = descriptors.get(date_iso)
|
||||
if not image:
|
||||
return match.group(0)
|
||||
return (
|
||||
f'<img src="{image["thumb_src"]}" srcset="{image["thumb_srcset"]}" '
|
||||
f'sizes="{image["thumb_sizes"]}" alt="{alt}" width="360" height="203" loading="lazy">'
|
||||
)
|
||||
|
||||
html = HERO_IMG_RE.sub(replace_hero, html)
|
||||
html = THUMB_IMG_RE.sub(replace_thumb, html)
|
||||
if html != original:
|
||||
write_text_atomic(path, html)
|
||||
log(f"patched images in {path}")
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(description="Create responsive hero image variants")
|
||||
parser.add_argument("--site-dir", default=None)
|
||||
args = parser.parse_args()
|
||||
|
||||
repo_root = Path(__file__).resolve().parent.parent
|
||||
site_dir = Path(args.site_dir or os.environ.get("SITE_DIR", repo_root / "public"))
|
||||
img_dir = site_dir / "img"
|
||||
|
||||
descriptors: dict[str, dict[str, str]] = {}
|
||||
for source in iter_source_images(img_dir):
|
||||
date_iso = source.stem
|
||||
descriptor = create_responsive_variants(img_dir, date_iso)
|
||||
if descriptor:
|
||||
descriptors[date_iso] = descriptor
|
||||
log(f"created variants for {date_iso}")
|
||||
|
||||
patched = 0
|
||||
targets = [site_dir / "index.html", site_dir / "archiv" / "index.html"]
|
||||
targets.extend(sorted((site_dir / "archiv").glob("2026-*.html")))
|
||||
for path in targets:
|
||||
if path.exists():
|
||||
patched += patch_html_images(path, descriptors)
|
||||
|
||||
log(f"done, {len(descriptors)} image set(s), patched {patched} html file(s)")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in New Issue
Block a user