Add Log rotation
Add logging for Telebot and Flask Add routing for Enable debugging for Flask and Telebot separately
This commit is contained in:
parent
41487ef5c6
commit
730de38cee
360
telezab.py
360
telezab.py
@ -1,8 +1,10 @@
|
|||||||
import os
|
import os
|
||||||
from flask import Flask, request, jsonify
|
from flask import Flask, request, jsonify
|
||||||
import telebot
|
import schedule
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
import hashlib
|
import hashlib
|
||||||
|
import telebot
|
||||||
|
from telebot import logger
|
||||||
import logging
|
import logging
|
||||||
from logging.config import dictConfig
|
from logging.config import dictConfig
|
||||||
import zipfile
|
import zipfile
|
||||||
@ -23,21 +25,6 @@ import re
|
|||||||
# Load environment variables
|
# Load environment variables
|
||||||
load_dotenv()
|
load_dotenv()
|
||||||
|
|
||||||
# Read environment variables for logging configuration
|
|
||||||
ENABLE_CONSOLE_LOGGING = os.getenv('ENABLE_CONSOLE_LOGGING', 'true').lower() in ['true', '1', 'yes']
|
|
||||||
ENABLE_FILE_LOGGING = os.getenv('ENABLE_FILE_LOGGING', 'true').lower() in ['true', '1', 'yes']
|
|
||||||
|
|
||||||
# Define log paths
|
|
||||||
LOG_PATH_ERRORS = os.getenv('LOG_PATH_ERRORS', 'logs/errors.log')
|
|
||||||
LOG_PATH_EVENTS = os.getenv('LOG_PATH_EVENTS', 'logs/events.log')
|
|
||||||
LOG_PATH_FLASK = os.getenv('LOG_PATH_FLASK', 'logs/flask.log')
|
|
||||||
LOG_ARCHIVE_PATH = os.getenv('LOG_ARCHIVE_PATH', 'logs/archive')
|
|
||||||
|
|
||||||
# Create log directories if they do not exist
|
|
||||||
os.makedirs(os.path.dirname(LOG_PATH_ERRORS), exist_ok=True)
|
|
||||||
os.makedirs(os.path.dirname(LOG_PATH_EVENTS), exist_ok=True)
|
|
||||||
os.makedirs(LOG_ARCHIVE_PATH, exist_ok=True)
|
|
||||||
|
|
||||||
class UTF8StreamHandler(logging.StreamHandler):
|
class UTF8StreamHandler(logging.StreamHandler):
|
||||||
def __init__(self, stream=None):
|
def __init__(self, stream=None):
|
||||||
super().__init__(stream)
|
super().__init__(stream)
|
||||||
@ -48,120 +35,90 @@ class UTF8StreamHandler(logging.StreamHandler):
|
|||||||
if hasattr(stream, 'reconfigure'):
|
if hasattr(stream, 'reconfigure'):
|
||||||
stream.reconfigure(encoding='utf-8')
|
stream.reconfigure(encoding='utf-8')
|
||||||
|
|
||||||
# Конфигурация логирования
|
|
||||||
handlers = {}
|
|
||||||
if ENABLE_CONSOLE_LOGGING:
|
|
||||||
handlers['console'] = {
|
|
||||||
'class': 'telezab.UTF8StreamHandler',
|
|
||||||
'stream': 'ext://sys.stdout', # Вывод в консоль
|
|
||||||
'formatter': 'console',
|
|
||||||
}
|
|
||||||
if ENABLE_FILE_LOGGING:
|
|
||||||
handlers['file_errors'] = {
|
|
||||||
'class': 'logging.handlers.TimedRotatingFileHandler',
|
|
||||||
'filename': LOG_PATH_ERRORS,
|
|
||||||
'when': 'midnight',
|
|
||||||
'interval': 1,
|
|
||||||
'backupCount': 7,
|
|
||||||
'formatter': 'error',
|
|
||||||
'encoding': 'utf-8', # Убедитесь, что используется кодировка UTF-8
|
|
||||||
}
|
|
||||||
handlers['file_events'] = {
|
|
||||||
'class': 'logging.handlers.TimedRotatingFileHandler',
|
|
||||||
'filename': LOG_PATH_EVENTS,
|
|
||||||
'when': 'midnight',
|
|
||||||
'interval': 1,
|
|
||||||
'backupCount': 7,
|
|
||||||
'formatter': 'event',
|
|
||||||
'encoding': 'utf-8', # Убедитесь, что используется кодировка UTF-8
|
|
||||||
}
|
|
||||||
# Configure Flask logger
|
|
||||||
flask_handlers = {
|
|
||||||
'flask': {
|
|
||||||
'class': 'logging.handlers.TimedRotatingFileHandler',
|
|
||||||
'filename': LOG_PATH_FLASK,
|
|
||||||
'when': 'midnight',
|
|
||||||
'interval': 1,
|
|
||||||
'backupCount': 7,
|
|
||||||
'formatter': 'default',
|
|
||||||
'encoding': 'utf-8',
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Include flask_handlers in dictConfig
|
# Определение пути к основному лог-файлу
|
||||||
|
LOG_FILE = 'logs/app.log'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Определение функции архивирования логов
|
||||||
|
def archive_old_logs():
|
||||||
|
# Получаем дату предыдущего дня
|
||||||
|
yesterday_date = (datetime.now() - timedelta(days=1)).strftime('%Y-%m-%d')
|
||||||
|
|
||||||
|
# Проверяем существует ли основной лог-файл
|
||||||
|
if os.path.exists(LOG_FILE):
|
||||||
|
# Путь к архиву в той же папке
|
||||||
|
archive_name = f"app_{yesterday_date}.zip"
|
||||||
|
archive_path = os.path.join(os.path.dirname(LOG_FILE), archive_name)
|
||||||
|
|
||||||
|
# Создание архива и добавление лог-файла
|
||||||
|
with zipfile.ZipFile(archive_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
|
||||||
|
zipf.write(LOG_FILE, arcname=os.path.basename(LOG_FILE))
|
||||||
|
|
||||||
|
# Удаление старого лог-файла после архивирования
|
||||||
|
os.remove(LOG_FILE)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class FilterByMessage(logging.Filter):
|
||||||
|
def filter(self, record):
|
||||||
|
# Фильтруем сообщения, содержащие 'Received 1 new updates'
|
||||||
|
return 'Received ' not in record.getMessage()
|
||||||
|
|
||||||
|
|
||||||
|
# Initialize Flask application
|
||||||
|
app = Flask(__name__)
|
||||||
|
|
||||||
|
# Настройка логирования
|
||||||
dictConfig({
|
dictConfig({
|
||||||
'version': 1,
|
'version': 1,
|
||||||
'formatters': {
|
'formatters': {
|
||||||
'default': {
|
'default': {
|
||||||
'format': '[%(asctime)s] %(levelname)s %(module)s: %(message)s',
|
'format': '[%(asctime)s] %(levelname)s %(module)s: %(message)s',
|
||||||
},
|
},
|
||||||
|
},
|
||||||
|
'handlers': {
|
||||||
'console': {
|
'console': {
|
||||||
'format': '[%(asctime)s] %(levelname)s %(module)s: %(message)s',
|
'class': 'telezab.UTF8StreamHandler', # Замените на путь к вашему классу UTF8StreamHandler
|
||||||
|
'stream': 'ext://sys.stdout', # Вывод в консоль
|
||||||
|
'formatter': 'default',
|
||||||
|
'filters': ['filter_by_message']
|
||||||
},
|
},
|
||||||
'error': {
|
'file': {
|
||||||
'format': '[%(asctime)s] ERROR %(module)s: %(message)s',
|
'class': 'logging.FileHandler',
|
||||||
},
|
'filename': 'app.log', # Запись в файл
|
||||||
'event': {
|
'formatter': 'default',
|
||||||
'format': '[%(asctime)s] EVENT %(module)s: %(message)s',
|
'encoding': 'utf-8', # Кодировка файла
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'filters': {
|
||||||
|
'filter_by_message': {
|
||||||
|
'()': FilterByMessage,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
'handlers': {**handlers, **flask_handlers},
|
|
||||||
'loggers': {
|
'loggers': {
|
||||||
'default': {
|
|
||||||
'level': 'INFO',
|
|
||||||
'handlers': ['console', 'file_events'],
|
|
||||||
},
|
|
||||||
'error': {
|
|
||||||
'level': 'ERROR',
|
|
||||||
'handlers': ['console', 'file_errors'],
|
|
||||||
'propagate': False,
|
|
||||||
},
|
|
||||||
'flask': {
|
'flask': {
|
||||||
'level': 'INFO',
|
'level': 'DEBUG',
|
||||||
'handlers': ['flask'],
|
'handlers': ['console', 'file'],
|
||||||
'propagate': False,
|
'propagate': False,
|
||||||
}
|
},
|
||||||
|
'telebot': {
|
||||||
|
'level': 'DEBUG',
|
||||||
|
'handlers': ['console', 'file'],
|
||||||
|
'propagate': False,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
'root': {
|
'root': {
|
||||||
'level': 'INFO',
|
'level': 'DEBUG',
|
||||||
'handlers': ['console', 'file_events'],
|
'handlers': ['console', 'file'],
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
# Настройка уровня логирования для Flask
|
||||||
|
app.logger.setLevel(logging.DEBUG)
|
||||||
# Set Flask app logger to use the 'flask' logger
|
# Настройка pyTelegramBotAPI logger
|
||||||
|
telebot.logger = logging.getLogger('telebot')
|
||||||
|
|
||||||
# Определение функции архивирования логов
|
|
||||||
def archive_old_logs():
|
|
||||||
yesterday_date = (datetime.now() - timedelta(days=1)).strftime('%Y-%m-%d')
|
|
||||||
for log_file in [LOG_PATH_ERRORS, LOG_PATH_EVENTS]:
|
|
||||||
log_dir, log_filename = os.path.split(log_file)
|
|
||||||
for filename in os.listdir(log_dir):
|
|
||||||
if filename.startswith(log_filename) and filename != log_filename:
|
|
||||||
log_file_path = os.path.join(log_dir, filename)
|
|
||||||
archive_name = f"{log_filename}_{yesterday_date}.zip"
|
|
||||||
archive_path = os.path.join(LOG_ARCHIVE_PATH, archive_name)
|
|
||||||
with zipfile.ZipFile(archive_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
|
|
||||||
zipf.write(log_file_path, arcname=filename)
|
|
||||||
os.remove(log_file_path)
|
|
||||||
|
|
||||||
# Create loggers
|
|
||||||
logger = logging.getLogger('default')
|
|
||||||
error_logger = logging.getLogger('error')
|
|
||||||
|
|
||||||
# Call archive_old_logs function after logging setup
|
|
||||||
archive_old_logs()
|
|
||||||
|
|
||||||
# Initialize Flask application
|
|
||||||
app = Flask(__name__)
|
|
||||||
|
|
||||||
app.logger.handlers = []
|
|
||||||
app.logger.propagate = True
|
|
||||||
flask_logger = logging.getLogger('flask')
|
|
||||||
app.logger.addHandler(flask_logger.handlers[0])
|
|
||||||
|
|
||||||
# Get the token from environment variables
|
# Get the token from environment variables
|
||||||
TOKEN = os.getenv('TELEGRAM_TOKEN')
|
TOKEN = os.getenv('TELEGRAM_TOKEN')
|
||||||
ZABBIX_URL = os.getenv('ZABBIX_URL')
|
ZABBIX_URL = os.getenv('ZABBIX_URL')
|
||||||
@ -191,17 +148,22 @@ user_timers = {}
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Initialize SQLite database
|
|
||||||
def init_db():
|
def init_db():
|
||||||
|
global st
|
||||||
|
st = datetime.now()
|
||||||
try:
|
try:
|
||||||
with db_lock:
|
with db_lock:
|
||||||
conn = sqlite3.connect('telezab.db')
|
conn = sqlite3.connect('telezab.db')
|
||||||
cursor = conn.cursor()
|
cursor = conn.cursor()
|
||||||
|
|
||||||
|
# Create events table
|
||||||
cursor.execute('''CREATE TABLE IF NOT EXISTS events (
|
cursor.execute('''CREATE TABLE IF NOT EXISTS events (
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
hash TEXT UNIQUE,
|
hash TEXT UNIQUE,
|
||||||
data TEXT,
|
data TEXT,
|
||||||
delivered BOOLEAN)''')
|
delivered BOOLEAN)''')
|
||||||
|
|
||||||
|
# Create subscriptions table with username and active flag
|
||||||
cursor.execute('''CREATE TABLE IF NOT EXISTS subscriptions (
|
cursor.execute('''CREATE TABLE IF NOT EXISTS subscriptions (
|
||||||
chat_id INTEGER,
|
chat_id INTEGER,
|
||||||
region_id TEXT,
|
region_id TEXT,
|
||||||
@ -209,29 +171,39 @@ def init_db():
|
|||||||
active BOOLEAN DEFAULT TRUE,
|
active BOOLEAN DEFAULT TRUE,
|
||||||
skip BOOLEAN DEFAULT FALSE,
|
skip BOOLEAN DEFAULT FALSE,
|
||||||
UNIQUE(chat_id, region_id))''')
|
UNIQUE(chat_id, region_id))''')
|
||||||
|
|
||||||
|
# Create whitelist table
|
||||||
cursor.execute('''CREATE TABLE IF NOT EXISTS whitelist (
|
cursor.execute('''CREATE TABLE IF NOT EXISTS whitelist (
|
||||||
chat_id INTEGER PRIMARY KEY)''')
|
chat_id INTEGER PRIMARY KEY)''')
|
||||||
|
|
||||||
|
# Create regions table with active flag
|
||||||
cursor.execute('''CREATE TABLE IF NOT EXISTS regions (
|
cursor.execute('''CREATE TABLE IF NOT EXISTS regions (
|
||||||
region_id TEXT PRIMARY KEY,
|
region_id TEXT PRIMARY KEY,
|
||||||
region_name TEXT,
|
region_name TEXT,
|
||||||
active BOOLEAN DEFAULT TRUE)''')
|
active BOOLEAN DEFAULT TRUE)''')
|
||||||
|
|
||||||
|
# Create user events table for logging
|
||||||
cursor.execute('''CREATE TABLE IF NOT EXISTS user_events (
|
cursor.execute('''CREATE TABLE IF NOT EXISTS user_events (
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
chat_id INTEGER,
|
chat_id INTEGER,
|
||||||
username TEXT,
|
username TEXT,
|
||||||
action TEXT,
|
action TEXT,
|
||||||
timestamp TEXT)''')
|
timestamp TEXT)''')
|
||||||
|
|
||||||
|
# Insert sample regions
|
||||||
cursor.execute('''INSERT OR IGNORE INTO regions (region_id, region_name) VALUES
|
cursor.execute('''INSERT OR IGNORE INTO regions (region_id, region_name) VALUES
|
||||||
('01', 'Адыгея'),
|
('01', 'Адыгея'),
|
||||||
('02', 'Башкортостан (Уфа)'),
|
('02', 'Башкортостан (Уфа)'),
|
||||||
('04', 'Алтай'),
|
('04', 'Алтай'),
|
||||||
('19', 'Республика Хакасия')''')
|
('19', 'Республика Хакасия')''')
|
||||||
|
|
||||||
conn.commit()
|
conn.commit()
|
||||||
logger.info("Database initialized successfully.")
|
app.logger.info("Database initialized successfully.")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
error_logger.error(f"Error initializing database: {e}")
|
app.logger.error(f"Error initializing database: {e}")
|
||||||
finally:
|
finally:
|
||||||
conn.close()
|
conn.close()
|
||||||
|
app.logger.info(f"init_db completed in {datetime.now() - st}")
|
||||||
|
|
||||||
|
|
||||||
# Hash the incoming data
|
# Hash the incoming data
|
||||||
@ -245,7 +217,7 @@ def is_whitelisted(chat_id):
|
|||||||
conn = sqlite3.connect('telezab.db')
|
conn = sqlite3.connect('telezab.db')
|
||||||
cursor = conn.cursor()
|
cursor = conn.cursor()
|
||||||
query = 'SELECT COUNT(*) FROM whitelist WHERE chat_id = ?'
|
query = 'SELECT COUNT(*) FROM whitelist WHERE chat_id = ?'
|
||||||
app.logger.debug(f"Executing query: {query} with chat_id={chat_id}")
|
telebot.logger.debug(f"Executing query: {query} with chat_id={chat_id}")
|
||||||
cursor.execute(query, (chat_id,))
|
cursor.execute(query, (chat_id,))
|
||||||
count = cursor.fetchone()[0]
|
count = cursor.fetchone()[0]
|
||||||
conn.close()
|
conn.close()
|
||||||
@ -258,7 +230,7 @@ def add_to_whitelist(chat_id, username):
|
|||||||
conn = sqlite3.connect('telezab.db')
|
conn = sqlite3.connect('telezab.db')
|
||||||
cursor = conn.cursor()
|
cursor = conn.cursor()
|
||||||
query = 'INSERT OR IGNORE INTO whitelist (chat_id, username) VALUES (?, ?)'
|
query = 'INSERT OR IGNORE INTO whitelist (chat_id, username) VALUES (?, ?)'
|
||||||
app.logger.debug(f"Executing query: {query} with chat_id={chat_id}, username={username}")
|
telebot.logger.debug(f"Executing query: {query} with chat_id={chat_id}, username={username}")
|
||||||
cursor.execute(query, (chat_id, username))
|
cursor.execute(query, (chat_id, username))
|
||||||
conn.commit()
|
conn.commit()
|
||||||
conn.close()
|
conn.close()
|
||||||
@ -270,7 +242,7 @@ def remove_from_whitelist(chat_id):
|
|||||||
conn = sqlite3.connect('telezab.db')
|
conn = sqlite3.connect('telezab.db')
|
||||||
cursor = conn.cursor()
|
cursor = conn.cursor()
|
||||||
query = 'DELETE FROM whitelist WHERE chat_id = ?'
|
query = 'DELETE FROM whitelist WHERE chat_id = ?'
|
||||||
app.logger.debug(f"Executing query: {query} with chat_id={chat_id}")
|
telebot.logger.debug(f"Executing query: {query} with chat_id={chat_id}")
|
||||||
cursor.execute(query, (chat_id,))
|
cursor.execute(query, (chat_id,))
|
||||||
conn.commit()
|
conn.commit()
|
||||||
conn.close()
|
conn.close()
|
||||||
@ -355,12 +327,12 @@ def log_user_event(chat_id, username, action):
|
|||||||
conn = sqlite3.connect('telezab.db')
|
conn = sqlite3.connect('telezab.db')
|
||||||
cursor = conn.cursor()
|
cursor = conn.cursor()
|
||||||
query = 'INSERT INTO user_events (chat_id, username, action, timestamp) VALUES (?, ?, ?, ?)'
|
query = 'INSERT INTO user_events (chat_id, username, action, timestamp) VALUES (?, ?, ?, ?)'
|
||||||
logger.debug(f"Executing query: {query} with chat_id={chat_id}, username={username}, action={action}, timestamp={timestamp}")
|
telebot.logger.debug(f"Executing query: {query} with chat_id={chat_id}, username={username}, action={action}, timestamp={timestamp}")
|
||||||
cursor.execute(query, (chat_id, username, action, timestamp))
|
cursor.execute(query, (chat_id, username, action, timestamp))
|
||||||
conn.commit()
|
conn.commit()
|
||||||
logger.info(f"User event logged: {chat_id} ({username}) - {action} at {timestamp}.")
|
telebot.logger.info(f"User event logged: {chat_id} ({username}) - {action} at {timestamp}.")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
error_logger.error(f"Error logging user event: {e}")
|
telebot.logger.error(f"Error logging user event: {e}")
|
||||||
finally:
|
finally:
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|
||||||
@ -397,7 +369,8 @@ def reset_settings_timer(chat_id):
|
|||||||
def transition_to_notification_mode(chat_id):
|
def transition_to_notification_mode(chat_id):
|
||||||
set_user_state(chat_id, NOTIFICATION_MODE)
|
set_user_state(chat_id, NOTIFICATION_MODE)
|
||||||
bot.send_message(chat_id, "Вы были автоматически переведены в режим получения уведомлений.")
|
bot.send_message(chat_id, "Вы были автоматически переведены в режим получения уведомлений.")
|
||||||
app.logger.info(f"User {chat_id} automatically transitioned to notification mode.")
|
show_main_menu(chat_id)
|
||||||
|
telebot.logger.info(f"User {chat_id} automatically transitioned to notification mode.")
|
||||||
|
|
||||||
|
|
||||||
# Main menu for users
|
# Main menu for users
|
||||||
@ -434,7 +407,7 @@ def handle_start(message):
|
|||||||
set_user_state(chat_id, NOTIFICATION_MODE)
|
set_user_state(chat_id, NOTIFICATION_MODE)
|
||||||
show_main_menu(chat_id)
|
show_main_menu(chat_id)
|
||||||
|
|
||||||
app.logger.info(f"User {chat_id} ({username}) started with command /start.")
|
telebot.logger.info(f"User {chat_id} ({username}) started with command /start.")
|
||||||
|
|
||||||
|
|
||||||
# Handle menu button presses
|
# Handle menu button presses
|
||||||
@ -498,7 +471,7 @@ def handle_subscribe(message):
|
|||||||
chat_id = message.chat.id
|
chat_id = message.chat.id
|
||||||
if not is_whitelisted(chat_id):
|
if not is_whitelisted(chat_id):
|
||||||
bot.send_message(chat_id, "Вы не авторизованы для использования этого бота.")
|
bot.send_message(chat_id, "Вы не авторизованы для использования этого бота.")
|
||||||
app.logger.info(f"Unauthorized access attempt by {chat_id}")
|
telebot.logger.info(f"Unauthorized access attempt by {chat_id}")
|
||||||
return
|
return
|
||||||
|
|
||||||
username = message.from_user.username
|
username = message.from_user.username
|
||||||
@ -529,16 +502,16 @@ def process_subscription(message, chat_id, username):
|
|||||||
bot.send_message(chat_id, f"Регион с ID {region_id} не существует или недопустимый формат. Введите только существующие номера регионов.")
|
bot.send_message(chat_id, f"Регион с ID {region_id} не существует или недопустимый формат. Введите только существующие номера регионов.")
|
||||||
return show_settings_menu(chat_id)
|
return show_settings_menu(chat_id)
|
||||||
query = 'INSERT OR IGNORE INTO subscriptions (chat_id, region_id, username, active) VALUES (?, ?, ?, TRUE)'
|
query = 'INSERT OR IGNORE INTO subscriptions (chat_id, region_id, username, active) VALUES (?, ?, ?, TRUE)'
|
||||||
app.logger.debug(f"Executing query: {query} with chat_id={chat_id}, region_id={region_id}, username={username}")
|
telebot.logger.debug(f"Executing query: {query} with chat_id={chat_id}, region_id={region_id}, username={username}")
|
||||||
cursor.execute(query, (chat_id, region_id, username))
|
cursor.execute(query, (chat_id, region_id, username))
|
||||||
if cursor.rowcount == 0:
|
if cursor.rowcount == 0:
|
||||||
query = 'UPDATE subscriptions SET active = TRUE WHERE chat_id = ? AND region_id = ?'
|
query = 'UPDATE subscriptions SET active = TRUE WHERE chat_id = ? AND region_id = ?'
|
||||||
app.logger.debug(f"Executing query: {query} with chat_id={chat_id}, region_id={region_id}")
|
telebot.logger.debug(f"Executing query: {query} with chat_id={chat_id}, region_id={region_id}")
|
||||||
cursor.execute(query, (chat_id, region_id))
|
cursor.execute(query, (chat_id, region_id))
|
||||||
conn.commit()
|
conn.commit()
|
||||||
conn.close()
|
conn.close()
|
||||||
bot.send_message(chat_id, f"Подписка на регионы: {', '.join(region_ids)} оформлена.")
|
bot.send_message(chat_id, f"Подписка на регионы: {', '.join(region_ids)} оформлена.")
|
||||||
app.logger.info(f"User {chat_id} ({username}) subscribed to regions: {', '.join(region_ids)}.")
|
telebot.logger.info(f"User {chat_id} ({username}) subscribed to regions: {', '.join(region_ids)}.")
|
||||||
log_user_event(chat_id, username, f"Subscribed to regions: {', '.join(region_ids)}")
|
log_user_event(chat_id, username, f"Subscribed to regions: {', '.join(region_ids)}")
|
||||||
show_settings_menu(chat_id)
|
show_settings_menu(chat_id)
|
||||||
|
|
||||||
@ -549,7 +522,7 @@ def handle_unsubscribe(message):
|
|||||||
chat_id = message.chat.id
|
chat_id = message.chat.id
|
||||||
if not is_whitelisted(chat_id):
|
if not is_whitelisted(chat_id):
|
||||||
bot.send_message(chat_id, "Вы не авторизованы для использования этого бота.")
|
bot.send_message(chat_id, "Вы не авторизованы для использования этого бота.")
|
||||||
app.logger.info(f"Unauthorized access attempt by {chat_id}")
|
telebot.logger.info(f"Unauthorized access attempt by {chat_id}")
|
||||||
return
|
return
|
||||||
|
|
||||||
user_regions = get_user_subscribed_regions(chat_id)
|
user_regions = get_user_subscribed_regions(chat_id)
|
||||||
@ -562,6 +535,7 @@ def handle_unsubscribe(message):
|
|||||||
bot.register_next_step_handler_by_chat_id(chat_id, process_unsubscription, chat_id)
|
bot.register_next_step_handler_by_chat_id(chat_id, process_unsubscription, chat_id)
|
||||||
|
|
||||||
|
|
||||||
|
# Пример функции, которая использует bot и log
|
||||||
def process_unsubscription(message, chat_id):
|
def process_unsubscription(message, chat_id):
|
||||||
if message.text.lower() == 'отмена':
|
if message.text.lower() == 'отмена':
|
||||||
bot.send_message(chat_id, "Действие отменено.")
|
bot.send_message(chat_id, "Действие отменено.")
|
||||||
@ -579,13 +553,13 @@ def process_unsubscription(message, chat_id):
|
|||||||
bot.send_message(chat_id, f"Регион с ID {region_id} не существует или недопустимый формат. Введите только номера регионов, на которые вы подписаны.")
|
bot.send_message(chat_id, f"Регион с ID {region_id} не существует или недопустимый формат. Введите только номера регионов, на которые вы подписаны.")
|
||||||
return show_settings_menu(chat_id)
|
return show_settings_menu(chat_id)
|
||||||
query = 'UPDATE subscriptions SET active = FALSE WHERE chat_id = ? AND region_id = ?'
|
query = 'UPDATE subscriptions SET active = FALSE WHERE chat_id = ? AND region_id = ?'
|
||||||
app.logger.debug(f"Executing query: {query} with chat_id={chat_id}, region_id={region_id}")
|
telebot.logger.debug(f"Executing query: {query} with chat_id={chat_id}, region_id={region_id}")
|
||||||
cursor.execute(query, (chat_id, region_id))
|
cursor.execute(query, (chat_id, region_id))
|
||||||
conn.commit()
|
conn.commit()
|
||||||
conn.close()
|
conn.close()
|
||||||
bot.send_message(chat_id, f"Отписка от регионов: {', '.join(region_ids)} оформлена.")
|
bot.send_message(chat_id, f"Отписка от регионов: {', '.join(region_ids)} оформлена.")
|
||||||
app.logger.info(f"User {chat_id} unsubscribed from regions: {', '.join(region_ids)}.")
|
telebot.logger.info(f"User {chat_id} unsubscribed from regions: {', '.join(region_ids)}.")
|
||||||
username = message.from_user.username if message.from_user.username else "N/A"
|
username = "@" + message.from_user.username if message.from_user.username else "N/A"
|
||||||
log_user_event(chat_id, username, f"Unsubscribed from regions: {', '.join(region_ids)}")
|
log_user_event(chat_id, username, f"Unsubscribed from regions: {', '.join(region_ids)}")
|
||||||
show_settings_menu(chat_id)
|
show_settings_menu(chat_id)
|
||||||
|
|
||||||
@ -663,7 +637,7 @@ def process_register(message, chat_id, username):
|
|||||||
reply_markup=markup
|
reply_markup=markup
|
||||||
)
|
)
|
||||||
bot.send_message(chat_id, "Запрос отправлен администратору для одобрения.")
|
bot.send_message(chat_id, "Запрос отправлен администратору для одобрения.")
|
||||||
app.logger.info(f"User {chat_id} ({username}) requested registration.")
|
telebot.logger.info(f"User {chat_id} ({username}) requested registration.")
|
||||||
else:
|
else:
|
||||||
bot.send_message(chat_id, "Некорректный выбор. Регистрация отменена.")
|
bot.send_message(chat_id, "Некорректный выбор. Регистрация отменена.")
|
||||||
show_main_menu(chat_id)
|
show_main_menu(chat_id)
|
||||||
@ -688,17 +662,17 @@ def process_add_region(message):
|
|||||||
conn = sqlite3.connect('telezab.db')
|
conn = sqlite3.connect('telezab.db')
|
||||||
cursor = conn.cursor()
|
cursor = conn.cursor()
|
||||||
query = 'SELECT region_name, active FROM regions WHERE region_id = ?'
|
query = 'SELECT region_name, active FROM regions WHERE region_id = ?'
|
||||||
app.logger.debug(f"Executing query: {query} with region_id={region_id}")
|
telebot.logger.debug(f"Executing query: {query} with region_id={region_id}")
|
||||||
cursor.execute(query, (region_id,))
|
cursor.execute(query, (region_id,))
|
||||||
result = cursor.fetchone()
|
result = cursor.fetchone()
|
||||||
if result:
|
if result:
|
||||||
existing_region_name, active = result
|
existing_region_name, active = result
|
||||||
if existing_region_name == region_name:
|
if existing_region_name == region_name:
|
||||||
query = 'UPDATE regions SET active = TRUE WHERE region_id = ?'
|
query = 'UPDATE regions SET active = TRUE WHERE region_id = ?'
|
||||||
app.logger.debug(f"Executing query: {query} with region_id={region_id}")
|
telebot.logger.debug(f"Executing query: {query} with region_id={region_id}")
|
||||||
cursor.execute(query, (region_id,))
|
cursor.execute(query, (region_id,))
|
||||||
bot.send_message(chat_id, f"Регион {region_id} - {region_name} активирован.")
|
bot.send_message(chat_id, f"Регион {region_id} - {region_name} активирован.")
|
||||||
app.logger.info(f"Admin {chat_id} reactivated region {region_id} - {region_name}.")
|
telebot.logger.info(f"Admin {chat_id} reactivated region {region_id} - {region_name}.")
|
||||||
else:
|
else:
|
||||||
markup = telebot.types.InlineKeyboardMarkup()
|
markup = telebot.types.InlineKeyboardMarkup()
|
||||||
markup.add(telebot.types.InlineKeyboardButton(text="Заменить", callback_data=f"replace_{region_id}_{region_name}"))
|
markup.add(telebot.types.InlineKeyboardButton(text="Заменить", callback_data=f"replace_{region_id}_{region_name}"))
|
||||||
@ -707,10 +681,10 @@ def process_add_region(message):
|
|||||||
bot.send_message(chat_id, f"Регион {region_id} уже существует с названием {existing_region_name}. Хотите заменить его или активировать старый регион?", reply_markup=markup)
|
bot.send_message(chat_id, f"Регион {region_id} уже существует с названием {existing_region_name}. Хотите заменить его или активировать старый регион?", reply_markup=markup)
|
||||||
else:
|
else:
|
||||||
query = 'INSERT OR IGNORE INTO regions (region_id, region_name) VALUES (?, ?)'
|
query = 'INSERT OR IGNORE INTO regions (region_id, region_name) VALUES (?, ?)'
|
||||||
app.logger.debug(f"Executing query: {query} with region_id={region_id}, region_name={region_name}")
|
telebot.logger.debug(f"Executing query: {query} with region_id={region_id}, region_name={region_name}")
|
||||||
cursor.execute(query, (region_id, region_name))
|
cursor.execute(query, (region_id, region_name))
|
||||||
bot.send_message(chat_id, f"Регион {region_id} - {region_name} добавлен.")
|
bot.send_message(chat_id, f"Регион {region_id} - {region_name} добавлен.")
|
||||||
app.logger.info(f"Admin {chat_id} added region {region_id} - {region_name}.")
|
telebot.logger.info(f"Admin {chat_id} added region {region_id} - {region_name}.")
|
||||||
conn.commit()
|
conn.commit()
|
||||||
conn.close()
|
conn.close()
|
||||||
except (IndexError, ValueError):
|
except (IndexError, ValueError):
|
||||||
@ -736,19 +710,19 @@ def handle_region_action(call):
|
|||||||
cursor = conn.cursor()
|
cursor = conn.cursor()
|
||||||
if action == "replace":
|
if action == "replace":
|
||||||
query = 'UPDATE regions SET region_name = ?, active = TRUE WHERE region_id = ?'
|
query = 'UPDATE regions SET region_name = ?, active = TRUE WHERE region_id = ?'
|
||||||
app.logger.debug(f"Executing query: {query} with region_name={region_name}, region_id={region_id}")
|
telebot.logger.debug(f"Executing query: {query} with region_name={region_name}, region_id={region_id}")
|
||||||
cursor.execute(query, (region_name, region_id))
|
cursor.execute(query, (region_name, region_id))
|
||||||
bot.send_message(chat_id, f"Регион {region_id} обновлен до {region_name} и активирован.")
|
bot.send_message(chat_id, f"Регион {region_id} обновлен до {region_name} и активирован.")
|
||||||
app.logger.info(f"Admin {chat_id} replaced and reactivated region {region_id} with {region_name}.")
|
telebot.logger.info(f"Admin {chat_id} replaced and reactivated region {region_id} with {region_name}.")
|
||||||
elif action == "reactivate":
|
elif action == "reactivate":
|
||||||
query = 'UPDATE regions SET active = TRUE WHERE region_id = ?'
|
query = 'UPDATE regions SET active = TRUE WHERE region_id = ?'
|
||||||
app.logger.debug(f"Executing query: {query} with region_id={region_id}")
|
telebot.logger.debug(f"Executing query: {query} with region_id={region_id}")
|
||||||
cursor.execute(query, (region_id,))
|
cursor.execute(query, (region_id,))
|
||||||
bot.send_message(chat_id, f"Регион {region_id} активирован.")
|
bot.send_message(chat_id, f"Регион {region_id} активирован.")
|
||||||
app.logger.info(f"Admin {chat_id} reactivated region {region_id}.")
|
telebot.logger.info(f"Admin {chat_id} reactivated region {region_id}.")
|
||||||
elif action == "cancel_region":
|
elif action == "cancel_region":
|
||||||
bot.send_message(chat_id, "Действие отменено.")
|
bot.send_message(chat_id, "Действие отменено.")
|
||||||
app.logger.info(f"Admin {chat_id} canceled region action.")
|
telebot.logger.info(f"Admin {chat_id} canceled region action.")
|
||||||
conn.commit()
|
conn.commit()
|
||||||
conn.close()
|
conn.close()
|
||||||
bot.edit_message_reply_markup(call.message.chat.id, call.message.message_id, reply_markup=None)
|
bot.edit_message_reply_markup(call.message.chat.id, call.message.message_id, reply_markup=None)
|
||||||
@ -771,15 +745,15 @@ def process_remove_region(message):
|
|||||||
return show_settings_menu(chat_id)
|
return show_settings_menu(chat_id)
|
||||||
|
|
||||||
query = 'UPDATE regions SET active = FALSE WHERE region_id = ?'
|
query = 'UPDATE regions SET active = FALSE WHERE region_id = ?'
|
||||||
app.logger.debug(f"Executing query: {query} with region_id={region_id}")
|
telebot.logger.debug(f"Executing query: {query} with region_id={region_id}")
|
||||||
cursor.execute(query, (region_id,))
|
cursor.execute(query, (region_id,))
|
||||||
query = 'UPDATE subscriptions SET active = FALSE WHERE region_id = ? AND active = TRUE'
|
query = 'UPDATE subscriptions SET active = FALSE WHERE region_id = ? AND active = TRUE'
|
||||||
app.logger.debug(f"Executing query: {query} with region_id={region_id}")
|
telebot.logger.debug(f"Executing query: {query} with region_id={region_id}")
|
||||||
cursor.execute(query, (region_id,))
|
cursor.execute(query, (region_id,))
|
||||||
conn.commit()
|
conn.commit()
|
||||||
conn.close()
|
conn.close()
|
||||||
bot.send_message(chat_id, f"Регион {region_id} теперь неактивен и все активные подписки обновлены.")
|
bot.send_message(chat_id, f"Регион {region_id} теперь неактивен и все активные подписки обновлены.")
|
||||||
app.logger.info(f"Admin {chat_id} set region {region_id} to inactive and updated subscriptions.")
|
telebot.logger.info(f"Admin {chat_id} set region {region_id} to inactive and updated subscriptions.")
|
||||||
except IndexError:
|
except IndexError:
|
||||||
bot.send_message(chat_id, "Неверный формат. Используйте: <region_id>")
|
bot.send_message(chat_id, "Неверный формат. Используйте: <region_id>")
|
||||||
show_settings_menu(chat_id)
|
show_settings_menu(chat_id)
|
||||||
@ -789,7 +763,7 @@ def handle_my_subscriptions(message):
|
|||||||
chat_id = message.chat.id
|
chat_id = message.chat.id
|
||||||
if not is_whitelisted(chat_id):
|
if not is_whitelisted(chat_id):
|
||||||
bot.send_message(chat_id, "Вы не авторизованы для использования этого бота.")
|
bot.send_message(chat_id, "Вы не авторизованы для использования этого бота.")
|
||||||
app.logger.info(f"Unauthorized access attempt by {chat_id}")
|
telebot.logger.info(f"Unauthorized access attempt by {chat_id}")
|
||||||
return
|
return
|
||||||
|
|
||||||
user_regions = get_user_subscribed_regions(chat_id)
|
user_regions = get_user_subscribed_regions(chat_id)
|
||||||
@ -807,7 +781,7 @@ def handle_active_regions(message):
|
|||||||
chat_id = message.chat.id
|
chat_id = message.chat.id
|
||||||
if not is_whitelisted(chat_id):
|
if not is_whitelisted(chat_id):
|
||||||
bot.send_message(chat_id, "Вы не авторизованы для использования этого бота.")
|
bot.send_message(chat_id, "Вы не авторизованы для использования этого бота.")
|
||||||
app.logger.info(f"Unauthorized access attempt by {chat_id}")
|
telebot.logger.info(f"Unauthorized access attempt by {chat_id}")
|
||||||
return
|
return
|
||||||
|
|
||||||
regions = get_sorted_regions() # Используем функцию для получения отсортированных регионов
|
regions = get_sorted_regions() # Используем функцию для получения отсортированных регионов
|
||||||
@ -855,7 +829,7 @@ async def consume_from_queue():
|
|||||||
await send_notification_message(chat_id, message_text)
|
await send_notification_message(chat_id, message_text)
|
||||||
channel.basic_ack(method_frame.delivery_tag)
|
channel.basic_ack(method_frame.delivery_tag)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
app.logger.error(f"Error sending message from queue: {e}")
|
telebot.logger.error(f"Error sending message from queue: {e}")
|
||||||
# Optionally, you can nack the message to requeue it
|
# Optionally, you can nack the message to requeue it
|
||||||
# channel.basic_nack(method_frame.delivery_tag)
|
# channel.basic_nack(method_frame.delivery_tag)
|
||||||
|
|
||||||
@ -869,13 +843,13 @@ async def send_message(chat_id, message, is_notification=False):
|
|||||||
await run_in_executor(bot.send_message, chat_id, message)
|
await run_in_executor(bot.send_message, chat_id, message)
|
||||||
except telebot.apihelper.ApiTelegramException as e:
|
except telebot.apihelper.ApiTelegramException as e:
|
||||||
if "429" in str(e):
|
if "429" in str(e):
|
||||||
app.logger.warning(f"Rate limit exceeded for chat_id {chat_id}. Retrying...")
|
telebot.logger.warning(f"Rate limit exceeded for chat_id {chat_id}. Retrying...")
|
||||||
await asyncio.sleep(1)
|
await asyncio.sleep(1)
|
||||||
await send_message(chat_id, message, is_notification)
|
await send_message(chat_id, message, is_notification)
|
||||||
else:
|
else:
|
||||||
app.logger.error(f"Failed to send message to {chat_id}: {e}")
|
telebot.logger.error(f"Failed to send message to {chat_id}: {e}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
app.logger.error(f"Error sending message to {chat_id}: {e}")
|
telebot.logger.error(f"Error sending message to {chat_id}: {e}")
|
||||||
await check_telegram_api()
|
await check_telegram_api()
|
||||||
finally:
|
finally:
|
||||||
if is_notification:
|
if is_notification:
|
||||||
@ -897,11 +871,11 @@ async def check_telegram_api():
|
|||||||
async with aiohttp.ClientSession() as session:
|
async with aiohttp.ClientSession() as session:
|
||||||
async with session.get('https://api.telegram.org') as response:
|
async with session.get('https://api.telegram.org') as response:
|
||||||
if response.status == 200:
|
if response.status == 200:
|
||||||
app.logger.info("Telegram API is reachable.")
|
telebot.logger.info("Telegram API is reachable.")
|
||||||
else:
|
else:
|
||||||
app.logger.error("Telegram API is not reachable.")
|
telebot.logger.error("Telegram API is not reachable.")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
app.logger.error(f"Error checking Telegram API: {e}")
|
telebot.logger.error(f"Error checking Telegram API: {e}")
|
||||||
|
|
||||||
|
|
||||||
def extract_region_number(host):
|
def extract_region_number(host):
|
||||||
@ -1029,6 +1003,48 @@ def add_user():
|
|||||||
app.logger.error("Invalid data received for adding user.")
|
app.logger.error("Invalid data received for adding user.")
|
||||||
return jsonify({"status": "failure", "reason": "Invalid data"}), 400
|
return jsonify({"status": "failure", "reason": "Invalid data"}), 400
|
||||||
|
|
||||||
|
|
||||||
|
# Обработчик для переключения уровня логирования Flask
|
||||||
|
@app.route('/debug/flask', methods=['POST'])
|
||||||
|
def toggle_flask_debug():
|
||||||
|
try:
|
||||||
|
data = request.get_json()
|
||||||
|
level = data.get('level', 'DEBUG').upper()
|
||||||
|
if level not in ['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL']:
|
||||||
|
return jsonify({'status': 'error', 'message': 'Invalid log level'}), 400
|
||||||
|
|
||||||
|
log_level = getattr(logging, level, logging.DEBUG)
|
||||||
|
app.logger.setLevel(log_level)
|
||||||
|
|
||||||
|
# Обновление уровня логирования для каждого обработчика
|
||||||
|
for handler in app.logger.handlers:
|
||||||
|
handler.setLevel(log_level)
|
||||||
|
|
||||||
|
return jsonify({'status': 'success', 'level': level})
|
||||||
|
except Exception as e:
|
||||||
|
return jsonify({'status': 'error', 'message': str(e)}), 500
|
||||||
|
|
||||||
|
|
||||||
|
# Обработчик для переключения уровня логирования Telebot
|
||||||
|
@app.route('/debug/telebot', methods=['POST'])
|
||||||
|
def toggle_telebot_debug():
|
||||||
|
try:
|
||||||
|
data = request.get_json()
|
||||||
|
level = data.get('level', 'DEBUG').upper()
|
||||||
|
if level not in ['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL']:
|
||||||
|
return jsonify({'status': 'error', 'message': 'Invalid log level'}), 400
|
||||||
|
|
||||||
|
log_level = getattr(logging, level, logging.DEBUG)
|
||||||
|
telebot.logger.setLevel(log_level)
|
||||||
|
|
||||||
|
# Обновление уровня логирования для каждого обработчика
|
||||||
|
for handler in telebot.logger.handlers:
|
||||||
|
handler.setLevel(log_level)
|
||||||
|
|
||||||
|
return jsonify({'status': 'success', 'level': level})
|
||||||
|
except Exception as e:
|
||||||
|
return jsonify({'status': 'error', 'message': str(e)}), 500
|
||||||
|
|
||||||
# Handle active triggers
|
# Handle active triggers
|
||||||
def handle_active_triggers(message):
|
def handle_active_triggers(message):
|
||||||
chat_id = message.chat.id
|
chat_id = message.chat.id
|
||||||
@ -1090,7 +1106,7 @@ def handle_region_selection(call):
|
|||||||
|
|
||||||
bot.send_message(chat_id, f"Найдены следующие группы хостов для региона {region_id}:", reply_markup=markup)
|
bot.send_message(chat_id, f"Найдены следующие группы хостов для региона {region_id}:", reply_markup=markup)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.error(f"Error connecting to Zabbix API: {e}")
|
telebot.logger.error(f"Error connecting to Zabbix API: {e}")
|
||||||
bot.send_message(chat_id, "Не удалось подключиться к Zabbix API. Пожалуйста, попробуйте позже.")
|
bot.send_message(chat_id, "Не удалось подключиться к Zabbix API. Пожалуйста, попробуйте позже.")
|
||||||
|
|
||||||
bot.edit_message_reply_markup(call.message.chat.id, call.message.message_id, reply_markup=None)
|
bot.edit_message_reply_markup(call.message.chat.id, call.message.message_id, reply_markup=None)
|
||||||
@ -1113,7 +1129,7 @@ def handle_group_selection(call):
|
|||||||
bot.send_message(chat_id, trigger, parse_mode="html")
|
bot.send_message(chat_id, trigger, parse_mode="html")
|
||||||
time.sleep(1/5)
|
time.sleep(1/5)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.error(f"Error processing group selection: {e}")
|
telebot.logger.error(f"Error processing group selection: {e}")
|
||||||
bot.send_message(chat_id, "Произошла ошибка при обработке вашего запроса. Пожалуйста, попробуйте позже.")
|
bot.send_message(chat_id, "Произошла ошибка при обработке вашего запроса. Пожалуйста, попробуйте позже.")
|
||||||
|
|
||||||
bot.edit_message_reply_markup(call.message.chat.id, call.message.message_id, reply_markup=None)
|
bot.edit_message_reply_markup(call.message.chat.id, call.message.message_id, reply_markup=None)
|
||||||
@ -1219,7 +1235,7 @@ def get_zabbix_triggers(group_id):
|
|||||||
|
|
||||||
return trigger_messages
|
return trigger_messages
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.error(f"Error connecting to Zabbix API: {e}")
|
telebot.logger.error(f"Error connecting to Zabbix API: {e}")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
@ -1264,20 +1280,34 @@ def simulate_triggers(message):
|
|||||||
|
|
||||||
|
|
||||||
def run_polling():
|
def run_polling():
|
||||||
bot.polling(none_stop=True, interval=0)
|
bot.polling(non_stop=True, interval=0)
|
||||||
|
|
||||||
|
# Запуск Flask-приложения
|
||||||
|
def run_flask():
|
||||||
|
app.run(port=5000, host='0.0.0.0', debug=True, use_reloader=False)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
def schedule_jobs():
|
||||||
|
schedule.every().day.at("00:00").do(archive_old_logs)
|
||||||
|
|
||||||
|
while True:
|
||||||
|
schedule.run_pending()
|
||||||
|
time.sleep(60) # Проверять раз в минуту
|
||||||
|
|
||||||
|
# Основная функция для запуска
|
||||||
|
def main():
|
||||||
|
# Инициализация базы данных
|
||||||
init_db()
|
init_db()
|
||||||
print('Bootstrap wait...')
|
print('Bootstrap wait...')
|
||||||
# Start Flask app in a separate thread
|
|
||||||
Thread(target=app.run, kwargs={'port': 5000, 'host': '0.0.0.0', 'debug': True, 'use_reloader': False}, daemon=True).start()
|
|
||||||
|
|
||||||
# Start bot polling in a separate thread
|
# Запуск Flask и бота в отдельных потоках
|
||||||
|
Thread(target=run_flask, daemon=True).start()
|
||||||
Thread(target=run_polling, daemon=True).start()
|
Thread(target=run_polling, daemon=True).start()
|
||||||
|
# Запуск планировщика задач в отдельном потоке
|
||||||
|
Thread(target=schedule_jobs, daemon=True).start()
|
||||||
|
# Запуск асинхронных задач
|
||||||
|
asyncio.run(consume_from_queue())
|
||||||
|
|
||||||
# Start async message consumer
|
if __name__ == '__main__':
|
||||||
loop = asyncio.get_event_loop()
|
main()
|
||||||
loop.create_task(consume_from_queue())
|
|
||||||
loop.run_forever()
|
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user