Source code for httk.web.engine.discovery

from pathlib import Path

from httk.web.model.config import SiteConfig
from httk.web.model.page import ResolvedRoute

[docs] DEFAULT_CONTENT_EXTENSIONS: tuple[str, ...] = (".md", ".rst", ".html", ".httkweb")
[docs] def normalize_route(route: str) -> str: normalized = route.lstrip("/").strip() if normalized in {"", "."}: return "index" return normalized
def _is_within(path: Path, root: Path) -> bool: try: path.resolve().relative_to(root.resolve()) return True except ValueError: return False
[docs] def resolve_route(config: SiteConfig, route: str) -> ResolvedRoute: normalized = normalize_route(route) static_candidate = (config.static_dir / normalized).resolve() if static_candidate.exists() and static_candidate.is_file() and _is_within(static_candidate, config.static_dir): return ResolvedRoute(kind="static", route=normalized, source_path=static_candidate) content = _resolve_content_route(content_dir=config.content_dir, route=normalized) if content is not None: return ResolvedRoute(kind="content", route=normalized, source_path=content) return ResolvedRoute(kind="missing", route=normalized)
def _resolve_content_route(content_dir: Path, route: str) -> Path | None: route_path = Path(route) if route_path.suffix: candidate = (content_dir / route_path).resolve() if candidate.exists() and candidate.is_file() and _is_within(candidate, content_dir): return candidate for ext in DEFAULT_CONTENT_EXTENSIONS: candidate = (content_dir / route_path).with_suffix(ext).resolve() if candidate.exists() and candidate.is_file() and _is_within(candidate, content_dir): return candidate return None