from __future__ import annotations
import re
import shutil
import sys
from pathlib import Path
_IMAGE_RE = re.compile(r"!\[([^\]]*)\]\((/[^)]+)\)")
_ASSET_EXTENSIONS = {
".gif",
".png",
".jpg",
".jpeg",
".svg",
".webp",
".bmp",
".ico",
".mp4",
".webm",
".mov",
".pdf",
}
def _is_asset(path: Path) -> bool:
return path.suffix.lower() in _ASSET_EXTENSIONS
def main() -> None:
project_root = Path(__file__).resolve().parent.parent
blog_dir = project_root / "blog"
landing_dir = project_root / "landing"
if not blog_dir.is_dir():
print(f"Blog directory not found: {blog_dir}", file=sys.stderr)
sys.exit(1)
blog_posts = sorted(blog_dir.glob("*.md"))
if not blog_posts:
print("No markdown files found in blog/")
return
copied: dict[Path, Path] = {} errors: list[str] = []
for post in blog_posts:
content = post.read_text()
for match in _IMAGE_RE.finditer(content):
img_path = match.group(2)
src = project_root / img_path.lstrip("/")
if not _is_asset(src):
continue
try:
src.resolve().relative_to(landing_dir.resolve())
continue
except ValueError:
pass
if not src.exists():
errors.append(f" ✗ {post.name}: asset not found: {img_path}")
continue
dest = landing_dir / img_path.lstrip("/")
dest.parent.mkdir(parents=True, exist_ok=True)
shutil.copy2(src, dest)
copied[src] = dest
if copied:
print(f"Copied {len(copied)} asset(s) into landing/:")
for src, dest in sorted(copied.items()):
rel_src = src.relative_to(project_root)
rel_dest = dest.relative_to(project_root)
print(f" ✓ {rel_src} -> {rel_dest}")
if errors:
print(f"\n{len(errors)} warning(s):")
for err in errors:
print(err)
if not copied and not errors:
print("No assets to copy.")
print(f"\n✅ Done.")
if __name__ == "__main__":
main()