Update logging system
This commit is contained in:
parent
54784a41da
commit
4ef050e3c8
@ -51,7 +51,12 @@ class LogManager:
|
||||
},
|
||||
},
|
||||
'handlers': {
|
||||
'console': {
|
||||
'telebot_console': {
|
||||
'class': 'log_manager.UTF8StreamHandler',
|
||||
'stream': 'ext://sys.stdout',
|
||||
'formatter': 'default',
|
||||
},
|
||||
'flask_console': {
|
||||
'class': 'log_manager.UTF8StreamHandler',
|
||||
'stream': 'ext://sys.stdout',
|
||||
'formatter': 'default',
|
||||
@ -94,19 +99,19 @@ class LogManager:
|
||||
'loggers': {
|
||||
'flask': {
|
||||
'level': 'INFO',
|
||||
'handlers': ['flask_file', 'flask_error_file', 'console'],
|
||||
'handlers': ['flask_file', 'flask_error_file', 'flask_console'],
|
||||
'propagate': False,
|
||||
},
|
||||
'telebot': {
|
||||
'level': 'INFO',
|
||||
'handlers': ['app_file', 'app_error_file', 'console'],
|
||||
'handlers': ['app_file', 'app_error_file', 'telebot_console'],
|
||||
'propagate': False,
|
||||
},
|
||||
},
|
||||
'root': {
|
||||
'level': 'DEBUG',
|
||||
'handlers': ['console'],
|
||||
}
|
||||
# 'root': {
|
||||
# 'level': 'DEBUG',
|
||||
# 'handlers': ['flask_console', 'telebot_console'],
|
||||
# }
|
||||
})
|
||||
|
||||
def archive_old_logs(self):
|
||||
|
||||
@ -1,73 +1,107 @@
|
||||
# region_api.py
|
||||
|
||||
import sqlite3
|
||||
import logging
|
||||
from threading import Lock
|
||||
|
||||
db_lock = Lock()
|
||||
|
||||
# Инициализируем логгер
|
||||
logger = logging.getLogger(__name__)
|
||||
logger.setLevel(logging.DEBUG) # Устанавливаем уровень логирования
|
||||
|
||||
|
||||
class RegionAPI:
|
||||
def __init__(self, db_path):
|
||||
self.db_path = db_path
|
||||
|
||||
def add_region(self, region_id: int, region_name: str):
|
||||
if not region_id.isdigit() == True:
|
||||
logger.info(f"Запрос на добавление региона: id={region_id}, name={region_name}")
|
||||
|
||||
# Проверка валидности region_id
|
||||
if not str(region_id).isdigit():
|
||||
logger.error(f"region_id {region_id} не является числом.")
|
||||
return {"status": "failure", "message": "Region_id must be digit only"}
|
||||
|
||||
with db_lock, sqlite3.connect(self.db_path) as conn:
|
||||
cursor = conn.cursor()
|
||||
logger.debug(f"Проверка существования региона с id={region_id}")
|
||||
cursor.execute('SELECT COUNT(*) FROM regions WHERE region_id = ?', (region_id,))
|
||||
count = cursor.fetchone()[0]
|
||||
|
||||
if count == 0:
|
||||
cursor.execute('INSERT INTO regions (region_id, region_name, active) VALUES (?, ?, 1)', (region_id, region_name))
|
||||
# Добавляем новый регион
|
||||
cursor.execute('INSERT INTO regions (region_id, region_name, active) VALUES (?, ?, 1)',
|
||||
(region_id, region_name))
|
||||
conn.commit()
|
||||
logger.info(f"Регион с id={region_id} успешно добавлен.")
|
||||
return {"status": "success", "message": "Region added successfully"}
|
||||
else:
|
||||
logger.warning(f"Регион с id={region_id} уже существует.")
|
||||
return {"status": "error", "message": "Region already exists"}
|
||||
|
||||
def remove_region(self, region_id):
|
||||
logger.info(f"Запрос на удаление региона: id={region_id}")
|
||||
|
||||
with db_lock, sqlite3.connect(self.db_path) as conn:
|
||||
cursor = conn.cursor()
|
||||
logger.debug(f"Проверка существования региона с id={region_id}")
|
||||
cursor.execute('SELECT COUNT(*) FROM regions WHERE region_id = ?', (region_id,))
|
||||
count = cursor.fetchone()[0]
|
||||
|
||||
if count == 0:
|
||||
logger.warning(f"Регион с id={region_id} не найден.")
|
||||
return {"status": "error", "message": "Region not found"}
|
||||
else:
|
||||
cursor.execute('DELETE FROM regions WHERE region_id = ?', (region_id,))
|
||||
conn.commit()
|
||||
logger.info(f"Регион с id={region_id} успешно удалён.")
|
||||
return {"status": "success", "message": "Region removed successfully"}
|
||||
|
||||
def get_regions(self):
|
||||
logger.info("Запрос на получение списка регионов.")
|
||||
|
||||
with db_lock, sqlite3.connect(self.db_path) as conn:
|
||||
cursor = conn.cursor()
|
||||
logger.debug("Извлечение данных из таблицы regions.")
|
||||
cursor.execute('SELECT region_id, region_name, active FROM regions')
|
||||
regions = cursor.fetchall()
|
||||
logger.info(f"Получено {len(regions)} регионов.")
|
||||
return [{"region_id": r[0], "region_name": r[1], "regions_active": r[2]} for r in regions]
|
||||
|
||||
def change_region_status(self, region_id, active):
|
||||
logger.info(f"Запрос на изменение статуса региона: id={region_id}, статус={active}")
|
||||
|
||||
with db_lock, sqlite3.connect(self.db_path) as conn:
|
||||
cursor = conn.cursor()
|
||||
logger.debug(f"Проверка существования региона с id={region_id}")
|
||||
cursor.execute('SELECT COUNT(*) FROM regions WHERE region_id = ?', (region_id,))
|
||||
count = cursor.fetchone()[0]
|
||||
|
||||
if count == 0:
|
||||
logger.warning(f"Регион с id={region_id} не найден.")
|
||||
return {"status": "error", "message": "Region not found"}
|
||||
else:
|
||||
cursor.execute('UPDATE regions SET active = ? WHERE region_id = ?', (active, region_id))
|
||||
conn.commit()
|
||||
logger.info(f"Статус региона с id={region_id} успешно изменён.")
|
||||
return {"status": "success", "message": "Region status updated successfully"}
|
||||
|
||||
def update_region_status(self, region_id, active):
|
||||
logger.info(f"Запрос на обновление статуса региона: id={region_id}, активность={active}")
|
||||
|
||||
with db_lock, sqlite3.connect(self.db_path) as conn:
|
||||
cursor = conn.cursor()
|
||||
|
||||
# Проверяем существование региона
|
||||
logger.debug(f"Проверка существования региона с id={region_id}")
|
||||
cursor.execute("SELECT region_name FROM regions WHERE region_id = ?", (region_id,))
|
||||
result = cursor.fetchone()
|
||||
if not result:
|
||||
logger.warning(f"Регион с id={region_id} не найден.")
|
||||
return {"status": "error", "message": "Регион не найден"}
|
||||
|
||||
# Обновляем статус активности региона
|
||||
cursor.execute("UPDATE regions SET active = ? WHERE region_id = ?", (int(active), region_id))
|
||||
conn.commit()
|
||||
|
||||
action = "Активирован" if active else "Отключён"
|
||||
return {"status": "success", "message": f"Регион {region_id} {action}"}
|
||||
logger.info(f"Регион с id={region_id} {action}.")
|
||||
return {"status": "success", "message": f"Регион {region_id} {action}"}
|
||||
|
||||
224
telezab.py
224
telezab.py
@ -339,9 +339,8 @@ def handle_help(message):
|
||||
help_text = (
|
||||
'<b>/start</b> - Показать меню бота\n'
|
||||
'<b>Настройки</b> - Перейти в режим настроек и управления подписками\n'
|
||||
'<b>Активные триггеры</b> - Получение всех нерешённых событий мониторинга по сервисам в выбранном регионе\n'
|
||||
'<b>Помощь</b> - <a href="https://confluence.is-mis.ru/pages/viewpage.action?pageId=460596141">Описание всех возможностей бота</a>'
|
||||
|
||||
'<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)
|
||||
@ -374,7 +373,7 @@ def show_main_menu(chat_id):
|
||||
markup = telebot.types.ReplyKeyboardMarkup(one_time_keyboard=True, resize_keyboard=True)
|
||||
if is_whitelisted(chat_id):
|
||||
user_state_manager.set_state(chat_id, "MAIN_MENU")
|
||||
markup.add('Настройки', 'Помощь', 'Активные триггеры')
|
||||
markup.add('Настройки', 'Помощь', 'Активные события')
|
||||
else:
|
||||
user_state_manager.set_state(chat_id, "REGISTRATION")
|
||||
markup.add('Регистрация')
|
||||
@ -453,7 +452,7 @@ def handle_main_menu(message, chat_id, text):
|
||||
show_settings_menu(chat_id)
|
||||
elif text == 'Помощь':
|
||||
handle_help(message)
|
||||
elif text == 'Активные триггеры':
|
||||
elif text == 'Активные события':
|
||||
handle_active_triggers(message)
|
||||
else:
|
||||
bot.send_message(chat_id, "Команда не распознана.")
|
||||
@ -496,7 +495,11 @@ def handle_subscribe_button(message):
|
||||
bot.send_message(chat_id, "Вы не авторизованы для использования этого бота.")
|
||||
return
|
||||
|
||||
username = message.from_user.username or "N/A"
|
||||
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="Отмена",
|
||||
@ -511,6 +514,7 @@ def handle_subscribe_button(message):
|
||||
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")
|
||||
@ -928,10 +932,11 @@ async def consume_from_queue():
|
||||
for method_frame, properties, body in channel.consume(RABBITMQ_QUEUE):
|
||||
message = json.loads(body)
|
||||
chat_id = message['chat_id']
|
||||
username = message['username']
|
||||
message_text = message['message']
|
||||
|
||||
try:
|
||||
await send_notification_message(chat_id, message_text)
|
||||
await send_notification_message(chat_id, message_text, username)
|
||||
channel.basic_ack(method_frame.delivery_tag)
|
||||
except Exception as e:
|
||||
telebot.logger.error(f"Error sending message from queue: {e}")
|
||||
@ -962,7 +967,8 @@ async def send_message(chat_id, message, is_notification=False):
|
||||
telebot.logger.error(f"Failed to send message to {chat_id}: {e}")
|
||||
telebot.logger.error(f"Detailed Error: {e}", exc_info=True) # Добавлено логирование исключения
|
||||
except Exception as e:
|
||||
telebot.logger.error(f"Unexpected error while sending message to {chat_id}: {e}", exc_info=True)
|
||||
username = f"@{message.from_user.username}" if message.from_user.username else "N/A"
|
||||
telebot.logger.error(f"Unexpected error while sending message to {username} {chat_id}: {e}", exc_info=True)
|
||||
await check_telegram_api()
|
||||
finally:
|
||||
if is_notification:
|
||||
@ -970,9 +976,10 @@ async def send_message(chat_id, message, is_notification=False):
|
||||
|
||||
|
||||
|
||||
async def send_notification_message(chat_id, message):
|
||||
async def send_notification_message(chat_id, message, username):
|
||||
await send_message(chat_id, message, is_notification=True)
|
||||
telebot.logger.info(f'Send {message} notification to {chat_id}')
|
||||
formatted_message = message.replace('\n', ' ').replace('\r', '')
|
||||
telebot.logger.info(f'Send notification to {username} {chat_id} from RabbitMQ [{formatted_message}]')
|
||||
|
||||
|
||||
async def run_in_executor(func, *args):
|
||||
@ -1037,7 +1044,7 @@ def handle_notification_mode_selection(call):
|
||||
cursor.execute(query, (disaster_only, chat_id))
|
||||
conn.commit()
|
||||
|
||||
mode_text = "Только Авария" if disaster_only else "Все события"
|
||||
mode_text = "Критические события" if disaster_only else "Все события"
|
||||
bot.send_message(chat_id, f"Режим уведомлений успешно изменён на: {mode_text}")
|
||||
user_state_manager.set_state(chat_id, "SETTINGS_MENU")
|
||||
show_settings_menu(chat_id)
|
||||
@ -1051,14 +1058,14 @@ def handle_notification_mode_selection(call):
|
||||
|
||||
|
||||
|
||||
# Фаза 1: Запрос активных триггеров и выбор региона с постраничным переключением
|
||||
# Фаза 1: Запрос активных событий и выбор региона с постраничным переключением
|
||||
def handle_active_triggers(message):
|
||||
chat_id = message.chat.id
|
||||
regions = get_sorted_regions() # Используем функцию get_regions для получения регионов
|
||||
|
||||
start_index = 0
|
||||
markup = create_region_keyboard(regions, start_index)
|
||||
bot.send_message(chat_id, "Выберите регион для получения активных триггеров:", reply_markup=markup)
|
||||
bot.send_message(chat_id, "Выберите регион для получения активных событий:", reply_markup=markup)
|
||||
|
||||
|
||||
def create_region_keyboard(regions, start_index, regions_per_page=10):
|
||||
@ -1141,7 +1148,7 @@ def handle_region_selection(call, region_id):
|
||||
markup.add(types.InlineKeyboardButton(text=group['name'], callback_data=f"group_{group['groupid']}"))
|
||||
markup.add(types.InlineKeyboardButton(text="Все группы региона\n(Долгое выполнение)", callback_data=f"all_groups_{region_id}"))
|
||||
|
||||
bot.send_message(chat_id, "Выберите группу хостов или получите триггеры по всем группам региона:", reply_markup=markup)
|
||||
bot.send_message(chat_id, "Выберите группу хостов или получите события по всем группам региона:", reply_markup=markup)
|
||||
except Exception as e:
|
||||
bot.send_message(chat_id, f"Ошибка при подключении к Zabbix API.\n{str(e)}")
|
||||
show_main_menu(chat_id)
|
||||
@ -1159,22 +1166,22 @@ def handle_group_or_all_groups(call):
|
||||
# Если выбрана конкретная группа
|
||||
if call.data.startswith("group_"):
|
||||
group_id = call.data.split("_")[1]
|
||||
get_triggers_for_group(chat_id, group_id) # Сразу получаем триггеры для группы
|
||||
get_triggers_for_group(chat_id, group_id) # Сразу получаем события для группы
|
||||
show_main_menu(chat_id)
|
||||
|
||||
# Если выбраны все группы региона
|
||||
elif call.data.startswith("all_groups_"):
|
||||
region_id = call.data.split("_")[2]
|
||||
get_triggers_for_all_groups(chat_id, region_id) # Сразу получаем триггеры для всех групп региона
|
||||
get_triggers_for_all_groups(chat_id, region_id) # Сразу получаем события для всех групп региона
|
||||
show_main_menu(chat_id)
|
||||
|
||||
|
||||
|
||||
# Вспомогательная функция: получение триггеров для группы
|
||||
# Вспомогательная функция: получение событий для группы
|
||||
def get_triggers_for_group(chat_id, group_id):
|
||||
triggers = get_zabbix_triggers(group_id) # Получаем все активные триггеры без периода
|
||||
triggers = get_zabbix_triggers(group_id) # Получаем все активные события без периода
|
||||
if not triggers:
|
||||
bot.send_message(chat_id, f"Нет активных триггеров.")
|
||||
bot.send_message(chat_id, f"Нет активных событий.")
|
||||
show_main_menu(chat_id)
|
||||
else:
|
||||
send_triggers_to_user(triggers, chat_id)
|
||||
@ -1197,15 +1204,15 @@ def get_triggers_for_all_groups(chat_id, region_id):
|
||||
if all_triggers:
|
||||
send_triggers_to_user(all_triggers, chat_id)
|
||||
else:
|
||||
bot.send_message(chat_id, f"Нет активных триггеров.")
|
||||
bot.send_message(chat_id, f"Нет активных событий.")
|
||||
show_main_menu(chat_id)
|
||||
except Exception as e:
|
||||
bot.send_message(chat_id, f"Ошибка при получении триггеров.\n{str(e)}")
|
||||
bot.send_message(chat_id, f"Ошибка при получении событий.\n{str(e)}")
|
||||
show_main_menu(chat_id)
|
||||
|
||||
|
||||
|
||||
# Вспомогательная функция: отправка триггеров пользователю
|
||||
# Вспомогательная функция: отправка событий пользователю
|
||||
def send_triggers_to_user(triggers, chat_id):
|
||||
for trigger in triggers:
|
||||
bot.send_message(chat_id, trigger, parse_mode="html")
|
||||
@ -1240,7 +1247,7 @@ def get_zabbix_triggers(group_id):
|
||||
zapi.login(api_token=ZABBIX_API_TOKEN)
|
||||
telebot.logger.info(f"Fetching triggers for group {group_id}")
|
||||
|
||||
# Получение триггеров
|
||||
# Получение событий
|
||||
triggers = zapi.trigger.get(
|
||||
output=["triggerid", "description", "priority"],
|
||||
selectHosts=["hostid", "name"],
|
||||
@ -1313,77 +1320,96 @@ def get_zabbix_triggers(group_id):
|
||||
@app.route(BASE_URL + '/webhook', methods=['POST'])
|
||||
def webhook():
|
||||
try:
|
||||
# Получаем данные и логируем
|
||||
data = request.get_json()
|
||||
app.logger.info(f"Received data: {data}")
|
||||
app.logger.info(f"Получены данные: {data}")
|
||||
|
||||
# Генерация хеша события и логирование
|
||||
event_hash = hash_data(data)
|
||||
app.logger.debug(f"Сгенерирован хеш для события: {event_hash}")
|
||||
|
||||
# Работа с базой данных в блоке синхронизации
|
||||
with db_lock:
|
||||
conn = sqlite3.connect(DB_PATH)
|
||||
cursor = conn.cursor()
|
||||
|
||||
# Проверяем количество записей в таблице событий
|
||||
cursor.execute('SELECT COUNT(*) FROM events')
|
||||
count = cursor.fetchone()[0]
|
||||
app.logger.debug(f"Текущее количество записей в таблице events: {count}")
|
||||
|
||||
# Если записей >= 200, удаляем самое старое событие
|
||||
if count >= 200:
|
||||
query = 'DELETE FROM events WHERE id = (SELECT MIN(id) FROM events)'
|
||||
app.logger.debug(f"Executing query: {query}")
|
||||
app.logger.debug(f"Удаление старого события: {query}")
|
||||
cursor.execute(query)
|
||||
|
||||
# Извлечение номера региона из поля host
|
||||
region_id = extract_region_number(data.get("host"))
|
||||
if region_id is None:
|
||||
app.logger.error(f"Failed to extract region number from host: {data.get('host')}")
|
||||
app.logger.error(f"Не удалось извлечь номер региона из host: {data.get('host')}")
|
||||
return jsonify({"status": "error", "message": "Invalid host format"}), 400
|
||||
app.logger.info(f"Извлечён номер региона: {region_id}")
|
||||
|
||||
# Fetch chat_ids to send the alert based on disaster_only flag
|
||||
# Запрос подписчиков для отправки уведомления в зависимости от уровня опасности
|
||||
if data['severity'] == '5': # Авария
|
||||
query = 'SELECT chat_id,username FROM subscriptions WHERE region_id = ? AND active = TRUE'
|
||||
else: # Высокая
|
||||
query = 'SELECT chat_id,username FROM subscriptions WHERE region_id = ? AND active = TRUE AND disaster_only = FALSE'
|
||||
query = 'SELECT chat_id, username FROM subscriptions WHERE region_id = ? AND active = TRUE'
|
||||
else: # Высокая опасность
|
||||
query = 'SELECT chat_id, username FROM subscriptions WHERE region_id = ? AND active = TRUE AND disaster_only = FALSE'
|
||||
|
||||
app.logger.debug(f"Executing query: {query} with region_id={region_id}")
|
||||
app.logger.debug(f"Выполнение запроса: {query} для region_id={region_id}")
|
||||
cursor.execute(query, (region_id,))
|
||||
results = cursor.fetchall()
|
||||
|
||||
app.logger.info(f"Найдено подписчиков: {len(results)} для региона {region_id}")
|
||||
|
||||
# Check if the region is active
|
||||
# Проверка статуса региона (активен или нет)
|
||||
query = 'SELECT active FROM regions WHERE region_id = ?'
|
||||
cursor.execute(query, (region_id,))
|
||||
region_row = cursor.fetchone()
|
||||
|
||||
if region_row and region_row[0]: # Check if region_row is not None and if active
|
||||
if region_row and region_row[0]: # Если регион активен
|
||||
app.logger.info(f"Регион {region_id} активен. Начинаем рассылку сообщений.")
|
||||
message = format_message(data)
|
||||
undelivered = False
|
||||
|
||||
# Отправляем сообщения подписчикам
|
||||
for chat_id, username in results:
|
||||
app.logger.info(f"Queueing message: {message} to chat_id={chat_id}, username={username}")
|
||||
formatted_message = message.replace('\n',' ').replace('\r','')
|
||||
app.logger.info(f"Отправка сообщения пользователю @{username} (chat_id={chat_id}) [{formatted_message}]")
|
||||
try:
|
||||
send_to_queue({'chat_id': chat_id, 'message': message})
|
||||
app.logger.info(f"Queued alert for {chat_id} ({username}) for region {region_id}")
|
||||
send_to_queue({'chat_id': chat_id, 'username': username, 'message': message})
|
||||
app.logger.info(f"Сообщение поставлено в очередь для {chat_id} (@{username})")
|
||||
except Exception as e:
|
||||
app.logger.error(f"Failed to send message to {chat_id} ({username}): {e}")
|
||||
app.logger.error(f"Ошибка при отправке сообщения для {chat_id} (@{username}): {e}")
|
||||
undelivered = True
|
||||
|
||||
# Сохранение события, если были проблемы с доставкой
|
||||
if undelivered:
|
||||
query = 'INSERT OR IGNORE INTO events (hash, data, delivered) VALUES (?, ?, ?)'
|
||||
app.logger.debug(f"Executing query: {query} with hash={event_hash}, data={data}, delivered={False}")
|
||||
app.logger.debug(f"Сохранение события в базе данных: {query} (hash={event_hash}, delivered={False})")
|
||||
cursor.execute(query, (event_hash, str(data), False))
|
||||
|
||||
# Коммитим изменения в базе данных
|
||||
conn.commit()
|
||||
app.logger.info("Изменения в базе данных успешно сохранены.")
|
||||
conn.close()
|
||||
|
||||
# Возвращаем успешный ответ
|
||||
return jsonify({"status": "success"}), 200
|
||||
|
||||
except sqlite3.OperationalError as e:
|
||||
app.logger.error(f"Database operation error: {e}")
|
||||
return jsonify({"status": "error", "message": "Database operation error"}), 500
|
||||
app.logger.error(f"Ошибка операции с базой данных: {e}")
|
||||
return jsonify({"status": "error", "message": "Ошибка работы с базой данных"}), 500
|
||||
|
||||
except ValueError as e:
|
||||
app.logger.error(f"Value error: {e}")
|
||||
return jsonify({"status": "error", "message": "Invalid data"}), 400
|
||||
app.logger.error(f"Ошибка значения: {e}")
|
||||
return jsonify({"status": "error", "message": "Некорректные данные"}), 400
|
||||
|
||||
except Exception as e:
|
||||
app.logger.error(f"Unexpected error: {e}")
|
||||
return jsonify({"status": "error", "message": "Internal server error"}), 500
|
||||
app.logger.error(f"Неожиданная ошибка: {e}")
|
||||
return jsonify({"status": "error", "message": "Внутренняя ошибка сервера"}), 500
|
||||
|
||||
|
||||
|
||||
def format_message(data):
|
||||
@ -1436,79 +1462,149 @@ def validate_email(email):
|
||||
@app.route(BASE_URL + '/users/add', methods=['POST'])
|
||||
def add_user():
|
||||
data = request.get_json()
|
||||
|
||||
telegram_id = data.get('telegram_id')
|
||||
chat_id = data.get('chat_id')
|
||||
user_email = data.get('user_email')
|
||||
|
||||
# DEBUG: Логирование полученных данных
|
||||
app.logger.debug(f"Получены данные для добавления пользователя: {data}")
|
||||
|
||||
# Валидация данных
|
||||
if not validate_chat_id(chat_id):
|
||||
app.logger.warning(f"Ошибка валидации: некорректный chat_id: {chat_id}")
|
||||
return jsonify({"status": "failure", "reason": "Invalid data chat_id must be digit"}), 400
|
||||
|
||||
if not validate_telegram_id(telegram_id):
|
||||
app.logger.warning(f"Ошибка валидации: некорректный telegram_id: {telegram_id}")
|
||||
return jsonify({"status": "failure", "reason": "Invalid data telegram id must start from '@'"}), 400
|
||||
|
||||
if not validate_email(user_email):
|
||||
app.logger.warning(f"Ошибка валидации: некорректный email: {user_email}")
|
||||
return jsonify({"status": "failure", "reason": "Invalid data email address must be from rtmis"}), 400
|
||||
|
||||
if telegram_id and chat_id and user_email:
|
||||
success = rundeck_add_to_whitelist(chat_id, telegram_id, user_email)
|
||||
if success:
|
||||
app.logger.info(f"User {telegram_id} added to whitelist.")
|
||||
user_state_manager.set_state(chat_id, "MAIN_MENU")
|
||||
try:
|
||||
# INFO: Попытка отправить сообщение пользователю
|
||||
app.logger.info(f"Отправка сообщения пользователю {telegram_id} с chat_id {chat_id}")
|
||||
bot.send_message(chat_id, "Регистрация пройдена успешно.")
|
||||
show_main_menu(chat_id)
|
||||
return jsonify({"status": "success", "msg": f"User {telegram_id} with {user_email} added successfully"}), 200
|
||||
else:
|
||||
app.logger.info(f"User with chat_id {chat_id} already exists.")
|
||||
return jsonify({"status": "failure", "msg": "User already exists"}), 400
|
||||
# DEBUG: Попытка добавления пользователя в whitelist
|
||||
app.logger.debug(f"Добавление пользователя {telegram_id} в whitelist")
|
||||
success = rundeck_add_to_whitelist(chat_id, telegram_id, user_email)
|
||||
if success:
|
||||
# INFO: Пользователь успешно добавлен в whitelist
|
||||
app.logger.info(f"Пользователь {telegram_id} добавлен в whitelist.")
|
||||
user_state_manager.set_state(chat_id, "MAIN_MENU")
|
||||
|
||||
# DEBUG: Показ основного меню пользователю
|
||||
app.logger.debug(f"Отображение основного меню для пользователя с chat_id {chat_id}")
|
||||
show_main_menu(chat_id)
|
||||
return jsonify({"status": "success", "msg": f"User {telegram_id} with {user_email} added successfully"}), 200
|
||||
else:
|
||||
# INFO: Пользователь уже существует в системе
|
||||
app.logger.info(f"Пользователь с chat_id {chat_id} уже существует.")
|
||||
return jsonify({"status": "failure", "msg": "User already exists"}), 400
|
||||
except telebot.apihelper.ApiTelegramException as e:
|
||||
if e.result.status_code == 403:
|
||||
# INFO: Пользователь заблокировал бота
|
||||
app.logger.info(f"Пользователь {telegram_id} заблокировал бота")
|
||||
return jsonify({"status": "failure", "msg": f"User {telegram_id} is blocked chat with bot"})
|
||||
elif e.result.status_code == 400:
|
||||
# WARNING: Пользователь неизвестен боту, возможно не нажал /start
|
||||
app.logger.warning(f"Пользователь {telegram_id} с chat_id {chat_id} неизвестен боту, возможно, не нажал /start")
|
||||
return jsonify({"status": "failure", "msg": f"User {telegram_id} with {chat_id} is unknown to the bot, did the user press /start button?"})
|
||||
else:
|
||||
# ERROR: Неизвестная ошибка при отправке сообщения
|
||||
app.logger.error(f"Ошибка при отправке сообщения пользователю {telegram_id}: {str(e)}")
|
||||
return jsonify({"status": "failure", "msg": f"{e}"})
|
||||
else:
|
||||
app.logger.error("Invalid data received for adding user.")
|
||||
# ERROR: Ошибка валидации — недостаточно данных
|
||||
app.logger.error("Получены некорректные данные для добавления пользователя.")
|
||||
return jsonify({"status": "failure", "reason": "Invalid data"}), 400
|
||||
|
||||
|
||||
# Маршрут для удаления пользователя и его подписок
|
||||
|
||||
@app.route(BASE_URL + '/users/del', methods=['POST'])
|
||||
def delete_user():
|
||||
data = request.get_json()
|
||||
user_email = data.get('email')
|
||||
conn = sqlite3.connect(DB_PATH)
|
||||
try:
|
||||
data = request.get_json()
|
||||
user_email = data.get('email')
|
||||
# DEBUG: Получен запрос и начинается обработка
|
||||
app.logger.debug(f"Получен запрос на удаление пользователя. Данные: {data}")
|
||||
|
||||
if not user_email:
|
||||
# WARNING: Ошибка валидации данных, email отсутствует
|
||||
app.logger.warning(f"Ошибка валидации: отсутствует email")
|
||||
return jsonify({"status": "failure", "message": "Email is required"}), 400
|
||||
|
||||
cursor = conn.cursor()
|
||||
|
||||
# DEBUG: Запрос на получение chat_id
|
||||
app.logger.debug(f"Выполняется запрос на получение chat_id для email: {user_email}")
|
||||
cursor.execute("SELECT chat_id FROM whitelist WHERE user_email = ?", (user_email,))
|
||||
user = cursor.fetchone()
|
||||
|
||||
if user is None:
|
||||
# WARNING: Пользователь с указанным email не найден
|
||||
app.logger.warning(f"Пользователь с email {user_email} не найден")
|
||||
return jsonify({"status": "failure", "message": "User not found"}), 404
|
||||
chat_id = user[0]
|
||||
|
||||
# INFO: Удаление пользователя и его подписок начато
|
||||
app.logger.info(f"Начато удаление пользователя с email {user_email} и всех его подписок")
|
||||
|
||||
# DEBUG: Удаление пользователя из whitelist
|
||||
app.logger.debug(f"Удаление пользователя с email {user_email} из whitelist")
|
||||
cursor.execute("DELETE FROM whitelist WHERE user_email = ?", (user_email,))
|
||||
|
||||
# DEBUG: Удаление подписок пользователя
|
||||
app.logger.debug(f"Удаление подписок для пользователя с chat_id {chat_id}")
|
||||
cursor.execute("DELETE FROM subscriptions WHERE chat_id = ?", (chat_id,))
|
||||
|
||||
conn.commit()
|
||||
return jsonify({"status": "success", "message": f"User with email {user_email} and all subscriptions deleted."}), 200
|
||||
# INFO: Пользователь и подписки успешно удалены
|
||||
app.logger.info(f"Пользователь с email {user_email} и все его подписки успешно удалены")
|
||||
return jsonify(
|
||||
{"status": "success", "message": f"User with email {user_email} and all subscriptions deleted."}), 200
|
||||
except Exception as e:
|
||||
conn.rollback()
|
||||
# ERROR: Ошибка при удалении данных
|
||||
app.logger.error(f"Ошибка при удалении пользователя с email {user_email}: {str(e)}")
|
||||
return jsonify({"status": "failure", "message": str(e)}), 500
|
||||
finally:
|
||||
conn.close()
|
||||
# DEBUG: Соединение с базой данных закрыто
|
||||
app.logger.debug(f"Соединение с базой данных закрыто")
|
||||
|
||||
|
||||
# Маршрут для получения информации о пользователях
|
||||
@app.route(BASE_URL + '/users/get', methods=['GET'])
|
||||
def get_users():
|
||||
try:
|
||||
# INFO: Запрос на получение списка пользователей
|
||||
app.logger.info("Запрос на получение информации о пользователях получен")
|
||||
|
||||
with db_lock:
|
||||
conn = sqlite3.connect(DB_PATH)
|
||||
cursor = conn.cursor()
|
||||
|
||||
# DEBUG: Запрос данных из таблицы whitelist
|
||||
app.logger.debug("Запрос данных пользователей из таблицы whitelist")
|
||||
cursor.execute('SELECT * FROM whitelist')
|
||||
users = cursor.fetchall()
|
||||
|
||||
# DEBUG: Формирование словаря пользователей
|
||||
app.logger.debug("Формирование словаря пользователей")
|
||||
users_dict = {id: {'id': id, 'username': username, 'email': email, 'events': [], 'worker': '', 'subscriptions': []}
|
||||
for id, username, email in users}
|
||||
|
||||
# DEBUG: Запрос данных событий пользователей
|
||||
app.logger.debug("Запрос событий пользователей из таблицы user_events")
|
||||
cursor.execute('SELECT chat_id, username, action, timestamp FROM user_events')
|
||||
events = cursor.fetchall()
|
||||
|
||||
# DEBUG: Обработка событий и добавление их в словарь пользователей
|
||||
for chat_id, username, action, timestamp in events:
|
||||
if chat_id in users_dict:
|
||||
event = {'type': action, 'date': timestamp}
|
||||
@ -1517,12 +1613,18 @@ def get_users():
|
||||
event['region'] = region
|
||||
users_dict[chat_id]['events'].append(event)
|
||||
|
||||
# DEBUG: Запрос данных подписок пользователей
|
||||
app.logger.debug("Запрос активных подписок пользователей из таблицы subscriptions")
|
||||
cursor.execute('SELECT chat_id, region_id FROM subscriptions WHERE active = 1')
|
||||
subscriptions = cursor.fetchall()
|
||||
|
||||
# DEBUG: Добавление подписок к пользователям
|
||||
for chat_id, region_id in subscriptions:
|
||||
if chat_id in users_dict:
|
||||
users_dict[chat_id]['subscriptions'].append(str(region_id))
|
||||
|
||||
# INFO: Формирование результата
|
||||
app.logger.info("Формирование результата для ответа")
|
||||
result = []
|
||||
for user in users_dict.values():
|
||||
ordered_user = {
|
||||
@ -1535,11 +1637,17 @@ def get_users():
|
||||
}
|
||||
result.append(ordered_user)
|
||||
|
||||
# INFO: Успешная отправка данных пользователей
|
||||
app.logger.info("Информация о пользователях успешно отправлена")
|
||||
return jsonify(result)
|
||||
|
||||
except Exception as e:
|
||||
# ERROR: Ошибка при получении информации о пользователях
|
||||
app.logger.error(f"Ошибка при получении информации о пользователях: {str(e)}")
|
||||
return jsonify({'status': 'error', 'message': str(e)}), 500
|
||||
|
||||
|
||||
|
||||
# Маршрут для отображения HTML-страницы с информацией о пользователях
|
||||
@app.route(BASE_URL + '/users', methods=['GET'])
|
||||
def view_users():
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user