- Implemented the initial version of the web interface. refactor: Begin Telegram bot refactoring - Started restructuring the bot’s code for better maintainability. chore: Migrate to Flask project structure - Reorganized the application to follow Flask's project structure. cleanup: Extensive code cleanup - Removed redundant code and improved readability. Signed-off-by: UdoChudo <stream@udochudo.ru>
199 lines
9.2 KiB
Python
199 lines
9.2 KiB
Python
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)
|