Files
duty-teller/duty_teller/i18n/messages.py
Nikolay Tatarinov 77a94fa91b
All checks were successful
CI / lint-and-test (push) Successful in 23s
feat: add team calendar ICS endpoint and related functionality
- Implemented a new API endpoint to generate an ICS calendar for team duty shifts, accessible via a valid token.
- Enhanced the `calendar_link` command to return both personal and team calendar URLs.
- Added a new function to build the team ICS file, ensuring each event includes the duty holder's name in the description.
- Updated tests to cover the new team calendar functionality, including validation for token formats and response content.
- Revised internationalization messages to reflect the new team calendar links.
2026-02-21 23:41:00 +03:00

131 lines
9.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Translation dictionaries: MESSAGES[lang][key]. Keys: dotted, e.g. start.greeting."""
MESSAGES: dict[str, dict[str, str]] = {
"en": {
"start.greeting": "Hi! I'm the duty calendar bot. Use /help for the command list.",
"set_phone.private_only": "The /set_phone command is only available in private chat.",
"set_phone.saved": "Phone saved: {phone}",
"set_phone.cleared": "Phone cleared.",
"set_phone.error": "Error saving.",
"help.title": "Available commands:",
"help.start": "/start — Start",
"help.help": "/help — Show this help",
"help.set_phone": "/set_phone — Set or clear phone for duty display",
"help.calendar_link": "/calendar_link — Get personal calendar subscription link (private chat)",
"help.pin_duty": "/pin_duty — In a group: pin the duty message (bot needs admin with Pin messages)",
"calendar_link.private_only": "The /calendar_link command is only available in private chat.",
"calendar_link.access_denied": "Access denied.",
"calendar_link.success": (
"Personal (your duties only):\n{url_personal}\n\n"
"Team (all duties):\n{url_team}"
),
"calendar_link.help_hint": (
"Subscribe to these URLs in Google Calendar, Apple Calendar, or Outlook."
),
"calendar_link.error": "Could not generate link. Please try again later.",
"help.import_schedule": "/import_duty_schedule — Import duty schedule (JSON)",
"help.set_role": "/set_role — Set user role (user | admin)",
"set_role.usage": "Usage: /set_role @username user|admin or reply to a message and send /set_role user|admin",
"set_role.user_not_found": "User not found.",
"set_role.done": "Role set: {name}{role}",
"set_role.error": "Could not set role.",
"errors.generic": "An error occurred. Please try again later.",
"pin_duty.group_only": "The /pin_duty command works only in groups.",
"pin_duty.no_message": "There is no duty message in this chat yet. Add the bot to the group — it will create one automatically.",
"pin_duty.pinned": "Duty message pinned.",
"pin_duty.failed": (
"Could not pin. Make sure the bot is an administrator with "
"«Pin messages» permission."
),
"pin_duty.could_not_pin_make_admin": (
"Duty message was sent but could not be pinned. Make the bot an "
"administrator with «Pin messages» permission, then send /pin_duty in the "
"chat — the current message will be pinned."
),
"duty.no_duty": "No duty at the moment.",
"duty.label": "Duty:",
"import.admin_only": "Access for administrators only.",
"import.handover_format": (
"Enter handover time as HH:MM and timezone, e.g. 09:00 Europe/Moscow or "
"06:00 UTC."
),
"import.parse_time_error": "Could not parse time. Enter e.g.: 09:00 Europe/Moscow",
"import.send_json": "Send the duty-schedule file (JSON).",
"import.need_json": "File must have .json extension.",
"import.parse_error": "File parse error: {error}",
"import.import_error": "Import error: {error}",
"import.done": (
"Import done: {users} users, {duties} duties{unavailable}{vacation} "
"({total} events total)."
),
"import.done_unavailable": ", {count} unavailable",
"import.done_vacation": ", {count} vacation",
"api.open_from_telegram": "Open the calendar from Telegram",
"api.auth_bad_signature": (
"Invalid signature. Ensure BOT_TOKEN on the server matches the bot from "
"which the calendar was opened (same bot as in the menu)."
),
"api.auth_invalid": "Invalid auth data",
"api.access_denied": "Access denied",
"dates.bad_format": "Parameters from and to must be in YYYY-MM-DD format",
"dates.from_after_to": "from date must not be after to",
},
"ru": {
"start.greeting": "Привет! Я бот календаря дежурств. Используй /help для списка команд.",
"set_phone.private_only": "Команда /set_phone доступна только в личке.",
"set_phone.saved": "Телефон сохранён: {phone}",
"set_phone.cleared": "Телефон очищен.",
"set_phone.error": "Ошибка сохранения.",
"help.title": "Доступные команды:",
"help.start": "/start — Начать",
"help.help": "/help — Показать эту справку",
"help.set_phone": "/set_phone — Указать или очистить телефон для отображения в дежурстве",
"help.calendar_link": "/calendar_link — Получить ссылку на персональную подписку календаря (только в личке)",
"help.pin_duty": "/pin_duty — В группе: закрепить сообщение о дежурстве (нужны права админа у бота)",
"calendar_link.private_only": "Команда /calendar_link доступна только в личке.",
"calendar_link.access_denied": "Доступ запрещён.",
"calendar_link.success": (
"Персональный (только ваши дежурства):\n{url_personal}\n\n"
"Общий (все дежурства):\n{url_team}"
),
"calendar_link.help_hint": (
"Подпишитесь на эти ссылки в Google Календаре, Календаре Apple или Outlook."
),
"calendar_link.error": "Не удалось сформировать ссылку. Попробуйте позже.",
"help.import_schedule": "/import_duty_schedule — Импорт расписания дежурств (JSON)",
"help.set_role": "/set_role — Выдать роль пользователю (user | admin)",
"set_role.usage": "Использование: /set_role @username user|admin или ответьте на сообщение и отправьте /set_role user|admin",
"set_role.user_not_found": "Пользователь не найден.",
"set_role.done": "Роль установлена: {name}{role}",
"set_role.error": "Не удалось установить роль.",
"errors.generic": "Произошла ошибка. Попробуйте позже.",
"pin_duty.group_only": "Команда /pin_duty работает только в группах.",
"pin_duty.no_message": "В этом чате ещё нет сообщения о дежурстве. Добавьте бота в группу — оно создастся автоматически.",
"pin_duty.pinned": "Сообщение о дежурстве закреплено.",
"pin_duty.failed": "Не удалось закрепить. Убедитесь, что бот — администратор с правом «Закреплять сообщения».",
"pin_duty.could_not_pin_make_admin": "Сообщение о дежурстве отправлено, но закрепить его не удалось. "
"Сделайте бота администратором с правом «Закреплять сообщения» (Pin messages), "
"затем отправьте в чат команду /pin_duty — текущее сообщение будет закреплено.",
"duty.no_duty": "Сейчас дежурства нет.",
"duty.label": "Дежурство:",
"import.admin_only": "Доступ только для администраторов.",
"import.handover_format": "Укажите время пересменки в формате ЧЧ:ММ и часовой пояс, "
"например 09:00 Europe/Moscow или 06:00 UTC.",
"import.parse_time_error": "Не удалось разобрать время. Укажите, например: 09:00 Europe/Moscow",
"import.send_json": "Отправьте файл в формате duty-schedule (JSON).",
"import.need_json": "Нужен файл с расширением .json",
"import.parse_error": "Ошибка разбора файла: {error}",
"import.import_error": "Ошибка импорта: {error}",
"import.done": "Импорт выполнен: {users} пользователей, {duties} дежурств{unavailable}{vacation} (всего {total} событий).",
"import.done_unavailable": ", {count} недоступностей",
"import.done_vacation": ", {count} отпусков",
"api.open_from_telegram": "Откройте календарь из Telegram",
"api.auth_bad_signature": "Неверная подпись. Убедитесь, что BOT_TOKEN на сервере совпадает с токеном бота, "
"из которого открыт календарь (тот же бот, что в меню).",
"api.auth_invalid": "Неверные данные авторизации",
"api.access_denied": "Доступ запрещён",
"dates.bad_format": "Параметры from и to должны быть в формате YYYY-MM-DD",
"dates.from_after_to": "Дата from не должна быть позже to",
},
}