"""Emitting the pages mews.page serves. Every page the service produces is itself a Mews page, so this module writes the same prologue, head and body shape as md2mews.py. The emitter is repeated here rather than imported because md2mews.py is a standalone script that pulls in a Markdown parser; tests/test_pages.py fails if the two drift apart. """ from datetime import UTC, datetime import fcntl from html import escape import os from pathlib import Path import sqlite3 from mews import VERSION from mews.lint import validate_bytes DOCTYPE = ( '' ) VARIANTS = ("mews-warm", "mews-cool", "mews-green", "mews-mono") STYLESHEET = "mews-0.1.css" SITE_VARIANT = "mews-cool" # SPEC.md 4.3 caps a page at 256 KB and asks for 64 KB. The directory refuses to # publish a page over the first and warns past the second. SIZE_MUST = 256 * 1024 SIZE_SHOULD = 64 * 1024 def _text(value: str) -> str: """Escape text content, leaving apostrophes alone so prose reads as prose.""" return escape(value, quote=False) def _attr(value: str) -> str: """Escape a value going into an attribute.""" return escape(value, quote=True) def page( title: str, body: list[str], language: str = "en", direction: str | None = None, variant: str | None = None, description: str | None = None, ) -> str: """Wrap body lines in a complete Mews page. Mirrors md2mews.page().""" attrs = f'xml:lang="{language}" lang="{language}"' if direction: attrs += f' dir="{direction}"' head = [ f"
{_text(line)}
" for line in paragraphs] body.append("{_text(opening)}
"] if findings_report.url: body.append( f'Checked ' f"{_text(findings_report.url)}.
" ) if findings_report.failures: body.append("{_text(note)}
") body.append("The rules are all in the spec. Checking ' "on your own machine is quicker while you are still fixing things:
" ) body.append(f"{_text(command)}")
body.append(
' Check another page ' '· The directory
' ) return site_page(title, body) def directory(rows: list[sqlite3.Row]) -> str: """Build the directory page: every site whose page passes the checks.""" body = ["{count} listed. Every one of these pages passed the checks " 'against Mews Profile 0.1, and gets looked ' "at again every week.
" ) body.append("Nothing here yet. Yours could be the first one in!
") body.append("Add your site ' '· Mews
' ) body.append( f" Updated {datetime.now(UTC).strftime('%Y-%m-%d %H:%M')} " "UTC" ) return site_page( "Mews directory", body, description="Sites whose pages follow Mews Profile 0.1.", ) def write_directory(target: str, rows: list[sqlite3.Row]) -> list[str]: """Write the directory page, replacing it only if it conforms. The page is validated before it is published, because the one page that has to be a good example is this one. Returns any warnings about it. """ destination = Path(target) destination.parent.mkdir(parents=True, exist_ok=True) text = directory(rows).encode() if len(text) > SIZE_MUST: raise ValueError( "The directory page would be over 256 KB, which section 4.3 " "forbids. Split it before listing more sites." ) lock = destination.with_name(destination.name + ".lock") with open(lock, "w") as handle: fcntl.flock(handle, fcntl.LOCK_EX) result = validate_bytes(text) if not result.conforms: raise ValueError( "The directory page doesn't conform: " + "; ".join(str(f) for f in result.failures) ) temporary = destination.with_name("." + destination.name + ".tmp") temporary.write_bytes(text) os.replace(temporary, destination) warnings = [str(f) for f in result.warnings] if len(text) > SIZE_SHOULD: warnings.append( f"The directory page is {len(text) // 1024} KB, over the 64 KB " "section 4.3 asks for." ) return warnings