from __future__ import annotations import shlex from enum import Enum from typing import Dict, Optional class MessageType(Enum): TEXT = "text" PHOTO = "photo" VIDEO = "video" ANIMATION = "animation" class Messages: # Команды WELCOME_MESSAGE = ( "👋 Привет! Я редактор постов для каналов.\n\n" "🤖 Сначала добавьте бота через /add_bot\n" "📢 Затем добавьте каналы через /add_channel\n" "📝 Потом можно:\n" "- Создать пост: /newpost\n" "- Управлять шаблонами: /tpl_new, /tpl_list\n" "- Посмотреть список ботов: /bots\n" "- Посмотреть список каналов: /channels\n\n" "❓ Справка: /help" ) HELP_MESSAGE = ( "📖 Справка по командам:\n\n" "Управление ботами и каналами:\n" "/add_bot - Добавить нового бота\n" "/bots - Список ваших ботов\n" "/add_channel - Добавить канал\n" "/channels - Список ваших каналов\n\n" "Управление постами:\n" "/newpost - Создать новый пост\n\n" "Управление шаблонами:\n" "/tpl_new - Создать шаблон\n" "/tpl_list - Список ваших шаблонов" ) START = ("👋 Привет! Я редактор постов. Доступные команды:\n" "/newpost — создать новый пост\n" "/tpl_new — создать шаблон\n" "/tpl_list — список шаблонов") # Ошибки ERROR_SESSION_EXPIRED = "❌ Сессия истекла. Начните заново с /newpost" ERROR_INVALID_FORMAT = "❌ Неверный формат. Попробуйте еще раз" ERROR_NO_CHANNELS = "❌ У вас нет каналов. Добавьте канал через админку" ERROR_TEMPLATE_NOT_FOUND = "❌ Шаблон не найден" ERROR_TEMPLATE_CREATE = "❌ Ошибка при создании шаблона: {error}" ERROR_INVALID_KEYBOARD = "❌ Неверный формат клавиатуры" # Создание поста SELECT_CHANNEL = "📢 Выберите канал для публикации:" SELECT_TYPE = "📝 Выберите тип поста:" SELECT_FORMAT = "🔤 Выберите формат текста:" ENTER_TEXT = "✏️ Введите текст сообщения\nИли используйте #имя_шаблона для применения шаблона" ENTER_MEDIA = "📎 Отправьте {media_type}" ENTER_KEYBOARD = "⌨️ Введите клавиатуру в формате:\nтекст|url\nтекст2|url2\n\nИли отправьте 'skip' для пропуска" # Шаблоны TEMPLATE_LIST = "📜 Список шаблонов (стр. {page}/{total_pages}):" TEMPLATE_CREATE_NAME = "📝 Введите имя для нового шаблона:" TEMPLATE_CREATE_TYPE = "📌 Выберите тип шаблона:" TEMPLATE_CREATE_FORMAT = "🔤 Выберите формат текста:" TEMPLATE_CREATE_CONTENT = "✏️ Введите содержимое шаблона:" TEMPLATE_CREATE_KEYBOARD = "⌨️ Введите клавиатуру или отправьте 'skip':" TEMPLATE_CREATED = "✅ Шаблон успешно создан" TEMPLATE_DELETED = "🗑 Шаблон удален" # Отправка CONFIRM_SEND = "📤 Как отправить пост?" ENTER_SCHEDULE = "📅 Введите дату и время для публикации в формате YYYY-MM-DD HH:MM" POST_SCHEDULED = "✅ Пост запланирован на {datetime}" POST_SENT = "✅ Пост отправлен" class MessageParsers: @staticmethod def parse_template_invocation(s: str) -> tuple[str, Dict[str, str]]: """ Парсит вызов шаблона вида: "#promo title='Hi' url=https://x.y" Возвращает: ("promo", {"title":"Hi", "url":"https://x.y"}) """ s = (s or "").strip() if not s.startswith("#"): raise ValueError("not a template invocation") try: parts = shlex.split(s) name = parts[0][1:] # убираем # args: Dict[str, str] = {} for tok in parts[1:]: if "=" in tok: k, v = tok.split("=", 1) args[k.strip()] = v.strip().strip('"\'') return name, args except ValueError as e: raise ValueError(f"Ошибка парсинга шаблона: {e}") @staticmethod def parse_key_value_lines(text: str) -> Dict[str, str]: """ Парсит переменные в форматах: - построчно: key=value key2="quoted value" - одной строкой: key=value key2="quoted value" """ text = (text or "").strip() if not text: return {} try: if "\n" in text: # Построчный формат out: Dict[str, str] = {} for line in text.splitlines(): line = line.strip() if "=" in line: k, v = line.split("=", 1) out[k.strip()] = v.strip().strip('"\'') return out else: # Однострочный формат out: Dict[str, str] = {} for tok in shlex.split(text): if "=" in tok: k, v = tok.split("=", 1) out[k.strip()] = v.strip() return out except ValueError as e: raise ValueError(f"Ошибка парсинга переменных: {e}") @staticmethod def parse_keyboard(text: str) -> Optional[Dict]: """ Парсит клавиатуру в формате: текст1|url1 текст2|url2 Возвращает: { "rows": [ [{"text": "текст1", "url": "url1"}], [{"text": "текст2", "url": "url2"}] ] } """ text = (text or "").strip() if not text or text.lower() == "skip": return None try: rows = [] for line in text.splitlines(): line = line.strip() if "|" in line: text, url = line.split("|", 1) rows.append([{ "text": text.strip(), "url": url.strip() }]) return {"rows": rows} if rows else None except Exception as e: raise ValueError(f"Ошибка парсинга клавиатуры: {e}") return out