"""Проверка и разбор форм админки (чистые функции — без HTTP и БД).""" from __future__ import annotations from typing import Any from zoneinfo import ZoneInfo, ZoneInfoNotFoundError WEEKDAY_NAMES: dict[int, str] = { 1: "Пн", 2: "Вт", 3: "Ср", 4: "Чт", 5: "Пт", 6: "Сб", 7: "Вс", } MAX_DESCRIPTION_LENGTH = 200 def format_weekdays(days: list[int] | tuple[int, ...] | None) -> str: """Человеческое описание дней ISO: ``1,3,5`` -> ``Пн, Ср, Пт``.""" if not days: return "каждый день" return ", ".join(WEEKDAY_NAMES[day] for day in sorted(set(days)) if day in WEEKDAY_NAMES) def parse_schedule_fields( *, template_key: str, hour: str, minute: str, weekdays: list[str], timezone: str, description: str, enabled: bool, ) -> tuple[dict[str, Any] | None, list[str]]: """Собрать данные расписания из полей формы. Возвращает ``(data, errors)``: при ошибках ``data is None`` и заполнен ``errors``. """ errors: list[str] = [] try: hour_value = int(hour) except (TypeError, ValueError): hour_value = -1 errors.append("Час должен быть числом") try: minute_value = int(minute) except (TypeError, ValueError): minute_value = -1 errors.append("Минуты должны быть числом") if not 0 <= hour_value <= 23 and "Час должен быть числом" not in errors: errors.append("Час должен быть от 0 до 23") if not 0 <= minute_value <= 59 and "Минуты должны быть числом" not in errors: errors.append("Минуты должны быть от 0 до 59") days: list[int] = [] for raw in weekdays: try: day = int(raw) except (TypeError, ValueError): errors.append(f"Некорректный день недели: {raw}") continue if 1 <= day <= 7: days.append(day) else: errors.append("День недели должен быть от 1 (Пн) до 7 (Вс)") tz_name = (timezone or "").strip() or "Europe/Moscow" try: ZoneInfo(tz_name) except (ZoneInfoNotFoundError, ValueError): errors.append(f"Неизвестная таймзона: {tz_name}") if not template_key.strip(): errors.append("Выберите шаблон сообщения") if len(description) > MAX_DESCRIPTION_LENGTH: errors.append(f"Описание длиннее {MAX_DESCRIPTION_LENGTH} символов") if errors: return None, errors return ( { "template_key": template_key, "hour": hour_value, "minute": minute_value, "weekdays": sorted(set(days)), "timezone": tz_name, "enabled": enabled, "description": description.strip(), }, [], )