"""Jinja template filters for the frontend app.""" from datetime import datetime, timezone def from_iso_format(s: str) -> datetime: """Convert ISO 8601 string to datetime object.""" return datetime.fromisoformat(s) def human_time(dt: datetime) -> str: """Format a datetime object into a human-readable relative time.""" now = datetime.now(timezone.utc) if dt.tzinfo is None: dt = dt.replace(tzinfo=timezone.utc) diff = now - dt seconds = diff.total_seconds() if seconds < 60: return "just now" elif seconds < 3600: minutes = int(seconds / 60) return f"{minutes} minute{'s' if minutes > 1 else ''} ago" elif seconds < 86400: hours = int(seconds / 3600) return f"{hours} hour{'s' if hours > 1 else ''} ago" elif seconds < 2592000: days = int(seconds / 86400) return f"{days} day{'s' if days > 1 else ''} ago" elif seconds < 31536000: months = int(seconds / 2592000) return f"{months} month{'s' if months > 1 else ''} ago" else: years = int(seconds / 31536000) return f"{years} year{'s' if years > 1 else ''} ago" def register_filters(app): """Register all template filters on the Flask app.""" app.template_filter("fromisoformat")(from_iso_format) app.template_filter("humantime")(human_time)