from __future__ import annotations import bleach from app.modules.content import repository from app.modules.content.models import ContentPage ALLOWED_TAGS = ["p", "h1", "h2", "h3", "h4", "ul", "ol", "li", "a", "strong", "em", "br", "img"] def sanitize_html(raw_html: str) -> str: return bleach.clean( raw_html, tags=ALLOWED_TAGS, attributes={"a": ["href"], "img": ["src", "alt"]}, protocols=["http", "https", "mailto"], strip=True, ) def page_to_dict(page: ContentPage) -> dict: return { "id": page.id, "slug": page.slug, "title": page.title, "body": page.body, "status": page.status, "author_id": page.author_id, "published_at": page.published_at.isoformat() if page.published_at else None, "updated_at": page.updated_at.isoformat() if page.updated_at else None, } def list_published_pages() -> list[ContentPage]: return repository.list_published_pages() def list_all_pages() -> list[ContentPage]: return repository.list_all_pages() def get_page_by_slug(slug: str, include_draft: bool = False) -> ContentPage | None: return repository.get_page_by_slug(slug, include_draft=include_draft) def create_page(slug: str, title: str, body: str, status: str, author_id: str) -> ContentPage: return repository.create_page( slug=slug, title=title, body=sanitize_html(body), status=status, author_id=author_id, ) def update_page(page_id: str, title: str | None, body: str | None, status: str | None) -> ContentPage: return repository.update_page( page_id, title, sanitize_html(body) if body else None, status, ) def delete_page(page_id: str) -> None: repository.delete_page(page_id) def page_exists(page_id: str) -> bool: return repository.get_page_by_id(page_id) is not None