import telebot import telezab from app import app from backend_locks import bot from bot_database import is_whitelisted, format_regions_list, get_sorted_regions, log_user_event, \ get_user_subscribed_regions from app.models import Regions, Subscriptions from app.extensions.db import db from utilities.telegram_utilities import show_main_menu, show_settings_menu from handlers import handle_my_subscriptions_button, handle_active_regions_button, handle_notification_mode_button def handle_main_menu(message, chat_id, text): """Обработка команд в главном меню.""" if text == 'Регистрация': telezab.state.set_state(chat_id, "REGISTRATION") telezab.handle_register(message) elif text == 'Настройки': telezab.state.set_state(chat_id, "SETTINGS_MENU") telezab.show_settings_menu(chat_id) elif text == 'Помощь': telezab.handle_help(message) elif text == 'Активные события': telezab.handle_active_triggers(message) else: bot.send_message(chat_id, "Команда не распознана.") show_main_menu(chat_id) def handle_settings_menu(message, chat_id, text): """Обработка команд в меню настроек.""" if text.lower() == 'подписаться': telezab.state.set_state(chat_id, "SUBSCRIBE") handle_subscribe_button(message) elif text.lower() == 'отписаться': telezab.state.set_state(chat_id, "UNSUBSCRIBE") handle_unsubscribe_button(message) elif text.lower() == 'мои подписки': handle_my_subscriptions_button(message) elif text.lower() == 'активные регионы': handle_active_regions_button(message) elif text.lower() == "режим уведомлений": handle_notification_mode_button(message) elif text.lower() == 'назад': telezab.state.set_state(chat_id, "MAIN_MENU") show_main_menu(chat_id) else: bot.send_message(chat_id, "Команда не распознана.") show_settings_menu(chat_id) def handle_subscribe_button(message): chat_id = message.chat.id if not is_whitelisted(chat_id): bot.send_message(chat_id, "Вы не авторизованы для использования этого бота.") return username = message.from_user.username if username: username = f"@{username}" else: username = "N/A" regions_list = format_regions_list(get_sorted_regions()) markup = telebot.types.InlineKeyboardMarkup() markup.add(telebot.types.InlineKeyboardButton(text="Отмена", callback_data=f"cancel_action")) bot.send_message(chat_id, f"Отправьте номера регионов через запятую:\n{regions_list}\n", reply_markup=markup) bot.register_next_step_handler_by_chat_id(chat_id, process_subscription_button, chat_id, username) def process_subscription_button(message, chat_id, username): subbed_regions = [] invalid_regions = [] if message.text.lower() == 'отмена': bot.send_message(chat_id, "Действие отменено.") telezab.state.set_state(chat_id, "SETTINGS_MENU") return show_settings_menu(chat_id) if not all(part.strip().isdigit() for part in message.text.split(',')): markup = telebot.types.InlineKeyboardMarkup() markup.add(telebot.types.InlineKeyboardButton(text="Отмена", callback_data=f"cancel_action")) bot.send_message(chat_id, "Неверный формат данных. Введите номер или номера регионов через запятую.", reply_markup=markup) bot.register_next_step_handler_by_chat_id(chat_id, process_subscription_button, chat_id, username) return region_ids = [int(part.strip()) for part in message.text.split(',')] with app.app_context(): # Получаем список валидных ID регионов из базы valid_region_ids = [r.region_id for r in Regions.query.filter(Regions.active == True).all()] for region_id in region_ids: if region_id not in valid_region_ids: invalid_regions.append(str(region_id)) continue subscription = Subscriptions.query.filter_by(chat_id=chat_id, region_id=region_id).first() if subscription: if not subscription.active: subscription.active = True db.session.add(subscription) subbed_regions.append(str(region_id)) else: # Уже подписан, можно тоже добавить для отчета subbed_regions.append(str(region_id)) else: new_sub = Subscriptions(chat_id=chat_id, region_id=region_id, active=True) db.session.add(new_sub) subbed_regions.append(str(region_id)) db.session.commit() if invalid_regions: bot.send_message(chat_id, f"Регион с ID {', '.join(invalid_regions)} не существует. Введите корректные номера или 'отмена'.") if subbed_regions: bot.send_message(chat_id, f"Подписка на регионы: {', '.join(subbed_regions)} оформлена.") log_user_event(chat_id, username, f"Subscribed to regions: {', '.join(subbed_regions)}") telezab.state.set_state(chat_id, "SETTINGS_MENU") show_settings_menu(chat_id) def handle_unsubscribe_button(message): chat_id = message.chat.id if not is_whitelisted(chat_id): bot.send_message(chat_id, "Вы не авторизованы для использования этого бота.") telebot.logger.info(f"Unauthorized access attempt by {chat_id}") telezab.state.set_state(chat_id, "REGISTRATION") return show_main_menu(chat_id) username = message.from_user.username if username: username = f"@{username}" else: username = "N/A" # Получаем список подписок пользователя user_regions = get_user_subscribed_regions(chat_id) if not user_regions: bot.send_message(chat_id, "Вы не подписаны ни на один регион.") telezab.state.set_state(chat_id, "SETTINGS_MENU") return show_settings_menu(chat_id) regions_list = format_regions_list(user_regions) markup = telebot.types.InlineKeyboardMarkup() markup.add(telebot.types.InlineKeyboardButton(text="Отмена", callback_data=f"cancel_action")) bot.send_message(chat_id, f"Отправьте номер или номера регионов, от которых хотите отписаться (через запятую):\n{regions_list}\n", reply_markup=markup) bot.register_next_step_handler_by_chat_id(chat_id, process_unsubscription_button, chat_id, username) def process_unsubscription_button(message, chat_id, username): unsubbed_regions = [] invalid_regions = [] markup = telebot.types.InlineKeyboardMarkup() markup.add(telebot.types.InlineKeyboardButton(text="Отмена", callback_data="cancel_action")) if message.text.lower() == 'отмена': bot.send_message(chat_id, "Действие отменено.") telezab.state.set_state(chat_id, "SETTINGS_MENU") return show_settings_menu(chat_id) # Проверка корректности формата ввода if not all(part.strip().isdigit() for part in message.text.split(',')): bot.send_message(chat_id, "Некорректный формат. Введите номера регионов через запятую.", reply_markup=markup) bot.register_next_step_handler_by_chat_id(chat_id, process_unsubscription_button, chat_id, username) return region_ids = [region_id.strip() for region_id in message.text.split(',')] with app.app_context(): valid_region_ids = [str(region[0]) for region in get_user_subscribed_regions(chat_id)] # get_user_subscribed_regions уже внутри app_context for region_id in region_ids: if region_id not in valid_region_ids: invalid_regions.append(region_id) continue subscription = db.session.query(Subscriptions).filter_by( chat_id=chat_id, region_id=int(region_id) ).first() if subscription: subscription.active = False unsubbed_regions.append(region_id) db.session.commit() if invalid_regions: bot.send_message(chat_id, f"Регион(ы) с ID {', '.join(invalid_regions)} не найдены в ваших подписках.") bot.send_message(chat_id, f"Отписка от регионов: {', '.join(unsubbed_regions)} выполнена.") log_user_event(chat_id, username, f"Unsubscribed from regions: {', '.join(unsubbed_regions)}") telezab.state.set_state(chat_id, "SETTINGS_MENU") show_settings_menu(chat_id)