bot works as echo (adding templates s functional)

tpl_list dont
This commit is contained in:
2025-08-19 05:13:16 +09:00
parent a8d860ed87
commit 18a92ca526
7 changed files with 274 additions and 47 deletions

View File

@@ -1,13 +1,27 @@
"""Обработчики для работы с шаблонами."""
from typing import Optional, Dict, Any
from telegram import Update, Message
import logging
import logging
import re
import logging
from typing import Optional, Dict, Any, cast
from telegram import Update, Message, CallbackQuery
from telegram.ext import ContextTypes, ConversationHandler
from telegram.error import BadRequest
from app.bots.editor.states import BotStates
from app.bots.editor.session import get_session_store
from ..keyboards import template_type_keyboard, get_templates_keyboard
from ..keyboards import (
template_type_keyboard,
get_templates_keyboard,
get_preview_keyboard
)
from ..utils.parsers import parse_key_value_lines
from ..utils.validation import validate_template_name
from app.services.users import get_or_create_user
from app.services.template import list_templates as get_user_templates_list
from app.services.template import create_template
logger = logging.getLogger(__name__)
async def start_template_creation(update: Update, context: ContextTypes.DEFAULT_TYPE) -> BotStates:
"""Начало создания шаблона."""
@@ -123,24 +137,174 @@ async def handle_template_keyboard(update: Update, context: ContextTypes.DEFAULT
await message.reply_text("Произошла непредвиденная ошибка при создании шаблона")
return BotStates.TPL_NEW_KB
def extract_template_vars(content: str) -> list[str]:
"""Извлекает переменные из текста шаблона."""
import re
pattern = r'\{([^}]+)\}'
return list(set(re.findall(pattern, content)))
async def list_templates(update: Update, context: ContextTypes.DEFAULT_TYPE) -> BotStates:
"""Список шаблонов."""
if not update.message:
if not update.message or not update.message.from_user:
return BotStates.CONVERSATION_END
message = update.message
user_id = message.from_user.id
templates = await get_user_templates(user_id)
if not templates:
await message.reply_text("У вас пока нет шаблонов")
try:
message = update.message
tg_user = message.from_user
# Получаем или создаем пользователя
user = await get_or_create_user(tg_user_id=tg_user.id, username=tg_user.username)
# Получаем шаблоны пользователя
templates = await get_user_templates_list(owner_id=user.id)
if not templates:
await message.reply_text("Нет доступных шаблонов")
return BotStates.CONVERSATION_END
# Сохраняем шаблоны в контексте
context.user_data['templates'] = {str(t.id): t for t in templates}
# Создаем клавиатуру с шаблонами
keyboard = get_templates_keyboard(templates)
await message.reply_text(
"Выберите шаблон для использования:",
reply_markup=keyboard
)
return BotStates.SELECT_TEMPLATE
except Exception as e:
logger.error(f"Ошибка загрузки шаблонов: {e}", exc_info=True)
if update.message:
await update.message.reply_text(f"Ошибка загрузки шаблонов: {e}")
return BotStates.CONVERSATION_END
async def handle_template_selection(update: Update, context: ContextTypes.DEFAULT_TYPE) -> BotStates:
"""Обработка выбора шаблона."""
query = update.callback_query
if not query:
return BotStates.CONVERSATION_END
page = context.user_data.get("tpl_page", 0)
keyboard = get_templates_keyboard(templates, page)
await query.answer()
await message.reply_text(
"Выберите шаблон:",
reply_markup=keyboard
)
return BotStates.TPL_SELECT
try:
template_id = query.data.split(":")[1]
template = context.user_data['templates'].get(template_id)
if not template:
await query.message.edit_text("Шаблон не найден")
return BotStates.CONVERSATION_END
# Сохраняем выбранный шаблон
context.user_data['current_template'] = template
# Извлекаем переменные из шаблона
vars_needed = extract_template_vars(template.content)
if not vars_needed:
# Если переменных нет, сразу показываем предпросмотр
rendered_text = template.content
keyboard = get_preview_keyboard()
await query.message.edit_text(
f"Предпросмотр:\n\n{rendered_text}",
reply_markup=keyboard,
parse_mode=template.parse_mode
)
return BotStates.PREVIEW_CONFIRM
# Сохраняем список необходимых переменных
context.user_data['vars_needed'] = vars_needed
context.user_data['template_vars'] = {}
# Запрашиваем первую переменную
await query.message.edit_text(
f"Введите значение для переменной {vars_needed[0]}:"
)
return BotStates.TEMPLATE_VARS
except Exception as e:
logger.error(f"Ошибка при выборе шаблона: {e}", exc_info=True)
await query.message.edit_text(f"Произошла ошибка: {e}")
return BotStates.CONVERSATION_END
async def handle_template_vars(update: Update, context: ContextTypes.DEFAULT_TYPE) -> BotStates:
"""Обработка ввода значений переменных шаблона."""
if not update.message or not update.message.text:
return BotStates.CONVERSATION_END
try:
vars_needed = context.user_data.get('vars_needed', [])
template_vars = context.user_data.get('template_vars', {})
template = context.user_data.get('current_template')
if not vars_needed or not template:
await update.message.reply_text("Ошибка: данные шаблона потеряны")
return BotStates.CONVERSATION_END
# Сохраняем введенное значение
current_var = vars_needed[len(template_vars)]
template_vars[current_var] = update.message.text
context.user_data['template_vars'] = template_vars
# Проверяем, все ли переменные заполнены
if len(template_vars) == len(vars_needed):
# Формируем предпросмотр
rendered_text = template.content
for var, value in template_vars.items():
rendered_text = rendered_text.replace(f"{{{var}}}", value)
keyboard = get_preview_keyboard()
await update.message.reply_text(
f"Предпросмотр:\n\n{rendered_text}",
reply_markup=keyboard,
parse_mode=template.parse_mode
)
return BotStates.PREVIEW_CONFIRM
# Запрашиваем следующую переменную
next_var = vars_needed[len(template_vars)]
await update.message.reply_text(
f"Введите значение для переменной {next_var}:"
)
return BotStates.TEMPLATE_VARS
except Exception as e:
logger.error(f"Ошибка при обработке переменных: {e}", exc_info=True)
await update.message.reply_text(f"Произошла ошибка: {e}")
return BotStates.CONVERSATION_END
async def handle_preview_confirmation(update: Update, context: ContextTypes.DEFAULT_TYPE) -> BotStates:
"""Обработка подтверждения предпросмотра."""
query = update.callback_query
if not query:
return BotStates.CONVERSATION_END
await query.answer()
try:
action = query.data.split(":")[1]
if action == "cancel":
await query.message.edit_text("Отправка отменена")
return BotStates.CONVERSATION_END
if action == "send":
template = context.user_data.get('current_template')
template_vars = context.user_data.get('template_vars', {})
if not template:
await query.message.edit_text("Ошибка: данные шаблона потеряны")
return BotStates.CONVERSATION_END
# TODO: Добавить логику отправки в канал
await query.message.edit_text(
"Пост успешно отправлен\n\n" +
"(Здесь будет реальная отправка в канал)"
)
return BotStates.CONVERSATION_END
except Exception as e:
logger.error(f"Ошибка при подтверждении: {e}", exc_info=True)
await query.message.edit_text(f"Произошла ошибка: {e}")
return BotStates.CONVERSATION_END