Files
postbot/app/bots/editor/messages.py

175 lines
7.2 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.

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