Small cleanup code

This commit is contained in:
Влад Зверев 2024-09-19 15:21:52 +05:00
parent 4ef050e3c8
commit a1b961ae20
2 changed files with 125 additions and 134 deletions

View File

@ -29,6 +29,7 @@ class LogManager:
'flask_error': os.path.join(self.log_dir, 'flask_error.log'),
'app': os.path.join(self.log_dir, 'app.log'),
'app_error': os.path.join(self.log_dir, 'app_error.log'),
'debug': os.path.join(self.log_dir, 'debug.log'),
}
# Ensure the log directory exists
@ -49,6 +50,12 @@ class LogManager:
'error': {
'format': '[%(asctime)s] %(levelname)s %(module)s: %(message)s',
},
'werkzeug': {
'format': '[%(asctime)s] %(levelname)s %(message)s'
},
'debug': {
'format': '[%(asctime)s] %(levelname)s %(module)s [%(funcName)s:%(lineno)d]: %(message)s'
}
},
'handlers': {
'telebot_console': {
@ -59,14 +66,14 @@ class LogManager:
'flask_console': {
'class': 'log_manager.UTF8StreamHandler',
'stream': 'ext://sys.stdout',
'formatter': 'default',
'formatter': 'werkzeug',
},
'flask_file': {
'class': 'logging.handlers.TimedRotatingFileHandler',
'filename': self.log_files['flask'],
'when': 'midnight',
'backupCount': self.retention_days,
'formatter': 'default',
'formatter': 'werkzeug',
'encoding': 'utf-8',
},
'flask_error_file': {
@ -74,7 +81,7 @@ class LogManager:
'filename': self.log_files['flask_error'],
'when': 'midnight',
'backupCount': self.retention_days,
'formatter': 'error',
'formatter': 'werkzeug',
'encoding': 'utf-8',
'level': 'ERROR',
},
@ -95,6 +102,15 @@ class LogManager:
'encoding': 'utf-8',
'level': 'ERROR',
},
'debug_file': {
'class': 'logging.handlers.TimedRotatingFileHandler',
'filename': self.log_files['debug'],
'when': 'midnight',
'backupCount': self.retention_days,
'formatter': 'debug',
'encoding': 'utf-8',
'level': 'DEBUG',
},
},
'loggers': {
'flask': {
@ -107,6 +123,16 @@ class LogManager:
'handlers': ['app_file', 'app_error_file', 'telebot_console'],
'propagate': False,
},
'werkzeug': {
'level': 'INFO',
'handlers': ['flask_file', 'flask_error_file', 'flask_console'],
'propagate': False,
},
'debug': {
'level': 'DEBUG',
'handlers': ['debug_file'],
'propagate': False,
},
}
# 'root': {
# 'level': 'DEBUG',
@ -134,6 +160,19 @@ class LogManager:
# Clean up old archives
self.cleanup_old_archives()
def configure_werkzeug_logging(self):
"""Отключаем встроенный логгер Werkzeug и задаём собственные настройки логирования."""
werkzeug_logger = logging.getLogger('werkzeug')
werkzeug_logger.handlers = [] # Удаляем существующие обработчики
# Добавляем кастомный обработчик для форматирования логов
handler = TimedRotatingFileHandler(self.log_files['flask'], when='midnight', backupCount=self.retention_days, encoding='utf-8')
handler.setFormatter(logging.Formatter('[%(asctime)s] %(levelname)s %(message)s'))
werkzeug_logger.addHandler(handler)
# Отключаем дублирование логов
werkzeug_logger.propagate = False
def cleanup_old_archives(self):
"""Deletes archived logs older than retention_days."""
now = datetime.now()

View File

@ -42,25 +42,25 @@ def load_value_from_file(file_name):
# Функция для получения переменной из окружения или файла
def get_variable_value(variable_name):
# Попытка получить значение из окружения
value = os.getenv(variable_name)
# Если переменная окружения не установлена, попробуем загрузить из файла
if not value:
file_value = "file_" + variable_name
value = os.getenv(file_value)
with open(value, 'r') as file:
value = file.read()
return value
return value
# def get_variable_value(variable_name):
# # Попытка получить значение из окружения
# value = os.getenv(variable_name)
#
# # Если переменная окружения не установлена, попробуем загрузить из файла
# if not value:
# file_value = "file_" + variable_name
# value = os.getenv(file_value)
# with open(value, 'r') as file:
# value = file.read()
# return value
# return value
#
DEV = get_variable_value('DEV')
DEV = os.getenv('DEV')
# Загрузка переменных окружения или значений из файлов
TOKEN = get_variable_value('TELEGRAM_TOKEN')
ZABBIX_API_TOKEN = get_variable_value('ZABBIX_API_TOKEN')
ZABBIX_URL = get_variable_value('ZABBIX_URL')
TOKEN = os.getenv('TELEGRAM_TOKEN')
ZABBIX_API_TOKEN = os.getenv('ZABBIX_API_TOKEN')
ZABBIX_URL = os.getenv('ZABBIX_URL')
DB_PATH = 'db/telezab.db'
SUPPORT_EMAIL = "shiftsupport-rtmis@rtmis.ru"
BASE_URL = '/telezab'
@ -70,7 +70,7 @@ region_api = RegionAPI(DB_PATH)
user_state_manager = UserStateManager()
# Initialize Flask application
app = Flask(__name__, template_folder='templates')
app = Flask(__name__,static_url_path='/static', template_folder='templates')
# Инициализация LogManager
log_manager = LogManager(log_dir='logs', retention_days=30)
@ -233,16 +233,6 @@ def get_admins():
conn.close()
return admins
# # Get list of regions
# def get_regions():
# with db_lock:
# conn = sqlite3.connect(DB_PATH)
# cursor = conn.cursor()
# cursor.execute('SELECT region_id, region_name FROM regions WHERE active = TRUE ORDER BY region_id')
# regions = cursor.fetchall()
# conn.close()
# return regions
def get_sorted_regions():
with db_lock:
@ -251,12 +241,10 @@ def get_sorted_regions():
cursor.execute('SELECT region_id, region_name FROM regions WHERE active = TRUE')
regions = cursor.fetchall()
conn.close()
# Сортируем регионы по числовому значению region_id
regions.sort(key=lambda x: int(x[0]))
return regions
# Check if region exists
def region_exists(region_id):
with db_lock:
@ -267,7 +255,6 @@ def region_exists(region_id):
conn.close()
return count > 0
# Get list of regions a user is subscribed to
def get_user_subscribed_regions(chat_id):
with db_lock:
@ -282,11 +269,10 @@ def get_user_subscribed_regions(chat_id):
''', (chat_id,))
regions = cursor.fetchall()
conn.close()
# Сортируем регионы по числовому значению region_id
regions.sort(key=lambda x: int(x[0]))
return regions
# Check if user is subscribed to a region
def is_subscribed(chat_id, region_id):
with db_lock:
@ -301,7 +287,6 @@ def is_subscribed(chat_id, region_id):
conn.close()
return count > 0
# Format regions list
def format_regions_list(regions):
return '\n'.join([f"{region_id} - {region_name}" for region_id, region_name in regions])
@ -327,8 +312,6 @@ def log_user_event(chat_id, username, action):
NOTIFICATION_MODE = 1
SETTINGS_MODE = 2
# Handle /help command to provide instructions
@bot.message_handler(commands=['help'])
def handle_help(message):
@ -339,13 +322,12 @@ def handle_help(message):
help_text = (
'<b>/start</b> - Показать меню бота\n'
'<b>Настройки</b> - Перейти в режим настроек и управления подписками\n'
'<b>Активные события</b> - Получение всех нерешённых событий мониторинга по выбранным сервисам в выбранного региона\n'
'<b>Активные события</b> - Получение всех нерешённых событий мониторинга по выбранным сервисам выбранного региона\n'
'<b>Помощь</b> - <a href="https://confluence.is-mis.ru/pages/viewpage.action?pageId=416785183">Описание всех возможностей бота</a>'
)
bot.send_message(message.chat.id, help_text, parse_mode="html")
show_main_menu(message.chat.id)
# Handle /register command for new user registration
def handle_register(message):
chat_id = message.chat.id
@ -363,12 +345,12 @@ def handle_register(message):
bot.send_message(chat_id,text,parse_mode="HTML")
log_user_event(chat_id, username, "Requested registration")
# Handle /start command
@bot.message_handler(commands=['start'])
def handle_start(message):
show_main_menu(message.chat.id)
def show_main_menu(chat_id):
markup = telebot.types.ReplyKeyboardMarkup(one_time_keyboard=True, resize_keyboard=True)
if is_whitelisted(chat_id):
@ -377,7 +359,6 @@ def show_main_menu(chat_id):
else:
user_state_manager.set_state(chat_id, "REGISTRATION")
markup.add('Регистрация')
bot.send_message(chat_id, "Выберите действие:", reply_markup=markup)
@ -385,8 +366,7 @@ def create_settings_keyboard(chat_id, admins_list):
markup = telebot.types.ReplyKeyboardMarkup(one_time_keyboard=True, resize_keyboard=True)
# Линия 1: "Подписаться", "Отписаться"
markup.row('Подписаться','Отписаться')
markup.row('Мои подписки')
markup.row('Режим уведомлений')
markup.row('Мои подписки','Режим уведомлений')
if DEV == '1':
if chat_id in admins_list:
markup.row('Активные регионы')
@ -394,17 +374,14 @@ def create_settings_keyboard(chat_id, admins_list):
markup.row('Назад')
return markup
# Settings menu for users
def show_settings_menu(chat_id):
if not is_whitelisted(chat_id):
user_state_manager.set_state(chat_id, "REGISTRATION")
bot.send_message(chat_id, "Вы неавторизованы для использования этого бота")
return
admins_list = get_admins()
markup = create_settings_keyboard(chat_id, admins_list)
bot.send_message(chat_id, "Вы находитесь в режиме настроек. Выберите действие:", reply_markup=markup)
# Основной обработчик меню
@ -413,15 +390,12 @@ def handle_menu_selection(message):
chat_id = message.chat.id
text = message.text.strip()
username = message.from_user.username
# Проверка авторизации
if not is_whitelisted(chat_id) and text != 'Регистрация':
bot.send_message(chat_id, "Вы не авторизованы для использования этого бота.")
return
# Получаем текущее состояние пользователя
current_state = user_state_manager.get_state(chat_id)
# Обработка команд в зависимости от состояния
if current_state == "MAIN_MENU":
handle_main_menu(message, chat_id, text)
@ -462,7 +436,6 @@ def handle_main_menu(message, chat_id, text):
def handle_settings_menu(message, chat_id, text):
"""Обработка команд в меню настроек."""
admins_list = get_admins()
if text.lower() == 'подписаться':
user_state_manager.set_state(chat_id, "SUBSCRIBE")
handle_subscribe_button(message)
@ -494,83 +467,58 @@ def handle_subscribe_button(message):
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)
# Сохраняем ID сообщения с клавиатурой для последующего редактирования
# user_state_manager.set_state(chat_id, "WAITING_FOR_INPUT",
# extra_data={"cancel_message_id": sent_message.message_id})
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, "Действие отменено.")
user_state_manager.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)
# # Сохраняем ID сообщения с клавиатурой для последующего редактирования
# user_state_manager.set_state(chat_id, "WAITING_FOR_INPUT", extra_data={"cancel_message_id": sent_message.message_id})
bot.register_next_step_handler_by_chat_id(chat_id, process_subscription_button, chat_id, username)
return
region_ids = message.text.split(',')
valid_region_ids = [region[0] for region in get_sorted_regions()]
with db_lock:
conn = sqlite3.connect(DB_PATH)
cursor = conn.cursor()
for region_id in region_ids:
region_id = region_id.strip()
if region_id not in valid_region_ids:
invalid_regions.append(region_id)
continue
cursor.execute('INSERT OR IGNORE INTO subscriptions (chat_id, region_id, username, active) VALUES (?, ?, ?, TRUE)',
(chat_id, region_id, username))
if cursor.rowcount == 0:
cursor.execute('UPDATE subscriptions SET active = TRUE WHERE chat_id = ? AND region_id = ?', (chat_id, region_id))
subbed_regions.append(region_id)
conn.commit()
# # Получаем ID сообщения с клавиатурой "Отмена" и скрываем её
# state_data = user_state_manager.get_state(chat_id)
# cancel_message_id = state_data.get("cancel_message_id")
#
# if cancel_message_id:
# try:
# bot.edit_message_reply_markup(chat_id, cancel_message_id, reply_markup=None)
# except telebot.apihelper.ApiTelegramException as e:
# telebot.logger.error(f"Failed to edit message: {e}")
if len(invalid_regions) > 0:
bot.send_message(chat_id, f"Регион с ID {', '.join(invalid_regions)} не существует. Введите корректные номера или 'отмена'.")
bot.send_message(chat_id, f"Подписка на регионы: {', '.join(subbed_regions)} оформлена.")
log_user_event(chat_id, username, f"Subscribed to regions: {', '.join(subbed_regions)}")
user_state_manager.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):
@ -578,27 +526,22 @@ def handle_unsubscribe_button(message):
telebot.logger.info(f"Unauthorized access attempt by {chat_id}")
user_state_manager.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, "Вы не подписаны ни на один регион.")
user_state_manager.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"))
markup.add(telebot.types.InlineKeyboardButton(text="Отмена", callback_data=f"cancel_action"))
bot.send_message(chat_id, f"Отправьте номер или номера регионов, от которых хотите отписаться (через запятую):\n{regions_list}\n",reply_markup=markup)
# user_state_manager.set_state(chat_id, "WAITING_FOR_INPUT",
# extra_data={"cancel_message_id": sent_message.message_id})
bot.register_next_step_handler_by_chat_id(chat_id, process_unsubscription_button, chat_id, username)
@ -606,51 +549,31 @@ def process_unsubscription_button(message, chat_id, username):
unsubbed_regions = []
invalid_regions = []
markup = telebot.types.InlineKeyboardMarkup()
markup.add(telebot.types.InlineKeyboardButton(text="Отмена",
callback_data=f"cancel_action"))
markup.add(telebot.types.InlineKeyboardButton(text="Отмена", callback_data=f"cancel_action"))
if message.text.lower() == 'отмена':
bot.send_message(chat_id, "Действие отменено.")
user_state_manager.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)
# user_state_manager.set_state(chat_id, "WAITING_FOR_INPUT",
# extra_data={"cancel_message_id": sent_message.message_id})
bot.register_next_step_handler_by_chat_id(chat_id, process_unsubscription_button, chat_id, username)
return
region_ids = message.text.split(',')
valid_region_ids = [region[0] for region in get_user_subscribed_regions(chat_id)]
with db_lock:
conn = sqlite3.connect(DB_PATH)
cursor = conn.cursor()
for region_id in region_ids:
region_id = region_id.strip()
if region_id not in valid_region_ids:
invalid_regions.append(region_id)
continue
# Удаление подписки
query = 'UPDATE subscriptions SET active = FALSE WHERE chat_id = ? AND region_id = ?'
cursor.execute(query, (chat_id, region_id))
unsubbed_regions.append(region_id)
conn.commit()
# # Получаем ID сообщения с клавиатурой "Отмена" и скрываем её
# state_data = user_state_manager.get_state(chat_id)
# cancel_message_id = state_data.get_extra_data(chat_id)
# if cancel_message_id:
# try:
# bot.edit_message_reply_markup(chat_id, cancel_message_id, reply_markup=None)
# except telebot.apihelper.ApiTelegramException as e:
# telebot.logger.error(f"Failed to edit message: {e}")
if len(invalid_regions) > 0:
bot.send_message(chat_id, f"Регион с ID {', '.join(invalid_regions)} не найден в ваших подписках.")
bot.send_message(chat_id, f"Отписка от регионов: {', '.join(unsubbed_regions)} выполнена.")
@ -670,6 +593,7 @@ def handle_cancel_action(call):
show_settings_menu(chat_id)
return
@bot.callback_query_handler(func=lambda call: call.data == "cancel_active_triggers")
def handle_cancel_active_triggers(call):
chat_id = call.message.chat.id
@ -680,13 +604,9 @@ def handle_cancel_active_triggers(call):
user_state_manager.set_state(chat_id, "MAIN_MENU")
show_main_menu(chat_id)
return
######################################################################################################################
## help_Region_Manager
##
######################################################################################################################
# Handle admin region management commands
######################################################################################################################
def handle_region_manager(chat_id: int, action: str):
if action == 'add':
bot.send_message(chat_id, "Введите ID и название региона в формате:\n<region_id> <region_name>")
@ -694,10 +614,8 @@ def handle_region_manager(chat_id: int, action: str):
elif action == 'remove':
bot.send_message(chat_id, "Введите ID региона, который хотите сделать неактивным")
bot.register_next_step_handler_by_chat_id(chat_id, process_remove_region)
######################################################################################################################
## help_Region_Manager
##
# Handle admin region management commands
######################################################################################################################
class RegionManager:
def __init__(self, db_path):
@ -812,6 +730,7 @@ def handle_region_action(call):
bot.send_message(chat_id, f"Регион {region_id} обновлен до {region_name} и активирован.")
region_manager.log_event(chat_id, username,
f"Admin replaced and reactivated region {region_id} - {region_name}")
telebot.logger.info(f"Admin {username} replaced and reactivated region {region_id} - {region_name}")
user_state_manager.set_state(chat_id, "SETTINGS_MENU")
@ -819,11 +738,12 @@ def handle_region_action(call):
region_manager.add_region(region_id, region_name)
bot.send_message(chat_id, f"Регион {region_id} активирован.")
region_manager.log_event(chat_id, username, f"Admin reactivated region {region_id} - {region_name}")
telebot.logger.info(f"Admin {username} activate {region_id} - {region_name}")
user_state_manager.set_state(chat_id, "SETTINGS_MENU")
elif action == "cancel_region":
bot.send_message(chat_id, "Действие отменено.")
telebot.logger.info(f"Admin {username} canceled region action.")
telebot.logger.info(f"Admin {username} canceled region actions.")
user_state_manager.set_state(chat_id, "SETTINGS_MENU")
bot.edit_message_reply_markup(chat_id=chat_id, message_id=call.message.message_id, reply_markup=None)
bot.answer_callback_query(call.id)
@ -840,6 +760,7 @@ def process_remove_region(message):
if success:
bot.send_message(chat_id, f"Регион {region_id} теперь неактивен, и все активные подписки обновлены.")
region_manager.log_event(chat_id, username, f"Admin {username} deactivated region {region_id}")
telebot.logger.info(f"Admin {username} deactivated region {region_id}")
user_state_manager.set_state(chat_id, "SETTINGS_MENU")
show_settings_menu(chat_id)
@ -860,27 +781,31 @@ def process_remove_region(message):
# Handle displaying active subscriptions for a user
def handle_my_subscriptions_button(message):
chat_id = message.chat.id
username = f"@{message.from_user.username}" if message.from_user.username else "N/A"
if not is_whitelisted(chat_id):
bot.send_message(chat_id, "Вы не авторизованы для использования этого бота.")
telebot.logger.info(f"Unauthorized access attempt by {chat_id}")
telebot.logger.info(f"Unauthorized access attempt by {username} {chat_id}")
return
user_regions = get_user_subscribed_regions(chat_id)
if not user_regions:
bot.send_message(chat_id, "Вы не подписаны ни на один регион.")
telebot.logger.debug(f"Запрашиваем {user_regions} for {username} {chat_id}")
else:
user_regions.sort(key=lambda x: int(x[0])) # Сортировка по числовому значению region_id
regions_list = format_regions_list(user_regions)
bot.send_message(chat_id, f"Ваши активные подписки:\n{regions_list}")
telebot.logger.debug(f"Запрашиваем {user_regions} for {username} {chat_id}")
show_settings_menu(chat_id)
# Handle displaying all active regions
def handle_active_regions_button(message):
chat_id = message.chat.id
username = f"@{message.from_user.username}" if message.from_user.username else "N/A"
if not is_whitelisted(chat_id):
bot.send_message(chat_id, "Вы не авторизованы для использования этого бота.")
telebot.logger.info(f"Unauthorized access attempt by {chat_id}")
telebot.logger.info(f"Unauthorized access attempt by {username} {chat_id}")
return
regions = get_sorted_regions() # Используем функцию для получения отсортированных регионов
@ -1010,18 +935,30 @@ def extract_region_number(host):
def handle_notification_mode_button(message):
chat_id = message.chat.id
username = f"@{message.from_user.username}" if message.from_user.username else "N/A"
telebot.logger.debug(f"Handling notification mode button for user {username} ({chat_id}).")
if not is_whitelisted(chat_id):
bot.send_message(chat_id, "Вы неавторизованы для использования этого бота")
telebot.logger.warning(f"Unauthorized access attempt by {username} ({chat_id})")
return
# Логируем успешное авторизованное использование бота
telebot.logger.info(f"User {username} ({chat_id}) is authorized and is selecting a notification mode.")
# Отправляем клавиатуру выбора режима уведомлений
markup = types.InlineKeyboardMarkup()
markup.add(types.InlineKeyboardButton(text="Критические события", callback_data="notification_mode_disaster"))
markup.add(types.InlineKeyboardButton(text="Все события", callback_data="notification_mode_all"))
bot.send_message(chat_id, "Выберите уровень событий мониторинга, уведомление о которых хотите получать:\n"
'1. <b>Критические события</b> (приоритет "DISASTER") - события, являющиеся потенциальными авариями и требующие оперативного решения.\nВ Zabbix обязательно имеют тег "CALL" для оперативного привлечения инженеров к устранению.\n\n'
'2. <b>Все события (По умолчанию)</b> - критические события, а также события Zabbix высокого ("HIGH") приоритета, имеющие потенциально значительное влияние на сервис и требующее устранение в плановом порядке.',
reply_markup=markup,parse_mode="HTML")
bot.send_message(chat_id,
"Выберите уровень событий мониторинга, уведомление о которых хотите получать:\n"
'1. <b>Критические события</b> (приоритет "DISASTER") - события, являющиеся потенциальными авариями и требующие оперативного решения.\nВ Zabbix обязательно имеют тег "CALL" для оперативного привлечения инженеров к устранению.\n\n'
'2. <b>Все события (По умолчанию)</b> - критические события, а также события Zabbix высокого ("HIGH") приоритета, имеющие потенциально значительное влияние на сервис и требующее устранение в плановом порядке.',
reply_markup=markup, parse_mode="HTML")
telebot.logger.info(f"Sent notification mode selection message to {username} ({chat_id}).")
@bot.callback_query_handler(func=lambda call: call.data.startswith("notification_mode_"))
@ -1030,13 +967,17 @@ def handle_notification_mode_selection(call):
message_id = call.message.message_id
mode = call.data.split("_")[2]
telebot.logger.debug(f"User ({chat_id}) selected notification mode: {mode}.")
# Убираем клавиатуру
bot.edit_message_reply_markup(chat_id=chat_id, message_id=message_id, reply_markup=None)
telebot.logger.debug(f"Removed inline keyboard for user ({chat_id}).")
# Обновляем режим уведомлений
disaster_only = True if mode == "disaster" else False
try:
telebot.logger.debug(f"Attempting to update notification mode in the database for user {chat_id}.")
with db_lock:
conn = sqlite3.connect(DB_PATH)
cursor = conn.cursor()
@ -1046,15 +987,25 @@ def handle_notification_mode_selection(call):
mode_text = "Критические события" if disaster_only else "Все события"
bot.send_message(chat_id, f"Режим уведомлений успешно изменён на: {mode_text}")
telebot.logger.info(f"Notification mode for user ({chat_id}) updated to: {mode_text}")
# Логируем изменение состояния пользователя
user_state_manager.set_state(chat_id, "SETTINGS_MENU")
telebot.logger.debug(f"User state for {chat_id} set to SETTINGS_MENU.")
# Показываем меню настроек
show_settings_menu(chat_id)
telebot.logger.debug(f"Displayed settings menu to {chat_id}.")
except Exception as e:
telebot.logger.error(f"Error updating notification mode for {chat_id}: {e}")
bot.send_message(chat_id, "Произошла ошибка при изменении режима уведомлений.")
finally:
conn.close()
telebot.logger.debug(f"Database connection closed for user {chat_id}.")
# Логируем успешный ответ callback-запроса
bot.answer_callback_query(call.id)
telebot.logger.debug(f"Callback query for user ({chat_id}) answered.")
@ -1349,7 +1300,7 @@ def webhook():
if region_id is None:
app.logger.error(f"Не удалось извлечь номер региона из host: {data.get('host')}")
return jsonify({"status": "error", "message": "Invalid host format"}), 400
app.logger.info(f"Извлечён номер региона: {region_id}")
app.logger.debug(f"Извлечён номер региона: {region_id}")
# Запрос подписчиков для отправки уведомления в зависимости от уровня опасности
if data['severity'] == '5': # Авария
@ -1361,7 +1312,7 @@ def webhook():
cursor.execute(query, (region_id,))
results = cursor.fetchall()
app.logger.info(f"Найдено подписчиков: {len(results)} для региона {region_id}")
app.logger.debug(f"Найдено подписчиков: {len(results)} для региона {region_id}")
# Проверка статуса региона (активен или нет)
query = 'SELECT active FROM regions WHERE region_id = ?'
@ -1369,7 +1320,7 @@ def webhook():
region_row = cursor.fetchone()
if region_row and region_row[0]: # Если регион активен
app.logger.info(f"Регион {region_id} активен. Начинаем рассылку сообщений.")
app.logger.debug(f"Регион {region_id} активен. Начинаем рассылку сообщений.")
message = format_message(data)
undelivered = False
@ -1379,7 +1330,7 @@ def webhook():
app.logger.info(f"Отправка сообщения пользователю @{username} (chat_id={chat_id}) [{formatted_message}]")
try:
send_to_queue({'chat_id': chat_id, 'username': username, 'message': message})
app.logger.info(f"Сообщение поставлено в очередь для {chat_id} (@{username})")
app.logger.debug(f"Сообщение поставлено в очередь для {chat_id} (@{username})")
except Exception as e:
app.logger.error(f"Ошибка при отправке сообщения для {chat_id} (@{username}): {e}")
undelivered = True
@ -1392,7 +1343,7 @@ def webhook():
# Коммитим изменения в базе данных
conn.commit()
app.logger.info("Изменения в базе данных успешно сохранены.")
app.logger.debug("Изменения в базе данных успешно сохранены.")
conn.close()
# Возвращаем успешный ответ
@ -1415,19 +1366,20 @@ def webhook():
def format_message(data):
try:
priority_map = {
'4': 'Высокая',
'5': 'Авария'
'High': '⚠️',
'Disaster': '⛔️'
}
priority = priority_map.get(data['severity'], 'Неизвестно')
priority = priority_map.get(data['severity'])
if data['status'].upper() == "PROBLEM":
message = (
f"⚠️ {data['host']} ({data['ip']})\n"
f"{priority} {data['host']} ({data['ip']})\n"
f"<b>Описание</b>: {data['msg']}\n"
f"Критичность: {data['severity']}"
f"<b>Критичность</b>: {data['severity']}\n"
f"<b>Время возникновения проблемы</b>: {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(int(data['date_reception'])))} Мск\n"
)
if 'link' in data:
message += f'\nURL: <a href="{data['link']}">Ссылка на график</a>'
message += f'<b>URL</b>: <a href="{data['link']}">Ссылка на график</a>'
return message
else:
message = (
@ -1435,7 +1387,7 @@ def format_message(data):
f"<b>Описание</b>: {data['msg']}\n"
f"<b>Критичность</b>: {data['severity']}\n"
f"<b>Проблема устранена!</b>\n"
f"<b>Время устранения проблемы</b>: {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(int(data['date_reception'])))}\n"
f"<b>Время устранения проблемы</b>: {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(int(data['date_reception'])))} Мск\n"
)
if 'link' in data:
message += f'<b>URL</b>: <a href="{data['link']}">Ссылка на график</a>'