agenda/agenda/ical.py

53 lines
1.4 KiB
Python

"""Shared helpers for generating iCalendar feeds."""
from __future__ import annotations
from datetime import date, datetime, timezone
from typing import Iterable
def escape_text(value: str) -> str:
"""Escape text for safer ICS output."""
return (
value.replace("\\", "\\\\")
.replace(";", "\\;")
.replace(",", "\\,")
.replace("\n", "\\n")
)
def _fold_line(value: str) -> Iterable[str]:
"""Yield RFC5545 folded lines."""
if len(value) <= 75:
yield value
return
remaining = value
first = True
while remaining:
segment = remaining[:75]
remaining = remaining[75:]
if not first:
segment = " " + segment
yield segment
first = False
def append_property(lines: list[str], name: str, value: str) -> None:
"""Append a folded property line to the ICS output."""
for line in _fold_line(f"{name}:{value}"):
lines.append(line)
def format_datetime_utc(dt_value: datetime) -> str:
"""Return datetime formatted in UTC for ICS."""
if dt_value.tzinfo is None:
dt_value = dt_value.replace(tzinfo=timezone.utc)
else:
dt_value = dt_value.astimezone(timezone.utc)
return dt_value.strftime("%Y%m%dT%H%M%SZ")
def format_date(date_value: date) -> str:
"""Return date formatted for all-day ICS events."""
return date_value.strftime("%Y%m%d")