"""Shared utility helpers.""" from __future__ import annotations from copy import deepcopy from datetime import datetime, timezone from html import escape import json from pathlib import Path from typing import Any ROOT = Path(__file__).resolve().parent.parent STORAGE_DIR = ROOT / "storage" STATIC_DIR = ROOT / "static" def html(value: Any) -> str: """Handle html.""" return escape(str(value if value is not None else ""), quote=True) def deep_copy(value: Any) -> Any: """Handle deep copy.""" return deepcopy(value) def utc_now() -> datetime: """Handle utc now.""" return datetime.now(timezone.utc) def current_year() -> int: """Return year.""" return utc_now().year def iso_now() -> str: """Handle iso now.""" return utc_now().isoformat(timespec="seconds") def parse_dt(value: str) -> datetime: """Parse dt.""" return datetime.fromisoformat(value.replace("Z", "+00:00")) def read_json(path: Path, default: Any) -> Any: """Read json.""" if not path.exists(): return deep_copy(default) try: return json.loads(path.read_text(encoding="utf-8")) except (OSError, json.JSONDecodeError): return deep_copy(default) def write_json(path: Path, payload: Any) -> None: """Write json.""" path.parent.mkdir(parents=True, exist_ok=True) path.write_text(json.dumps(payload, indent=2, sort_keys=True), encoding="utf-8") def bool_from_form(value: str | None) -> bool: """Handle bool from form.""" return value in {"on", "true", "1", "yes", "y"} def clean_text(value: Any, max_length: int = 500, allow_newlines: bool = False) -> str: """Clean text.""" text = str(value if value is not None else "") cleaned = [] for char in text: if char in "\r\n\t": if allow_newlines: cleaned.append("\n" if char in "\r\n" else "\t") else: cleaned.append(" ") elif ord(char) >= 32: cleaned.append(char) return "".join(cleaned).strip()[:max_length] def clean_choice(value: Any, allowed: set[str], default: str) -> str: """Clean choice.""" candidate = clean_text(value, 80) return candidate if candidate in allowed else default def list_html(items: list[str]) -> str: """Return html.""" return "" def tag_html(items: list[str], css_class: str = "") -> str: """Handle tag html.""" return ( '
' + "".join(f'{html(item)}' for item in items) + "
" ) def clamp_int(value: Any, default: int, minimum: int, maximum: int) -> int: """Handle clamp int.""" try: parsed = int(value) except (TypeError, ValueError): return default return max(minimum, min(maximum, parsed)) def first_present(mapping: dict[str, Any], key: str, default: Any = "") -> Any: """Handle first present.""" value = mapping.get(key, default) return value if value not in (None, "") else default