add gitignore
This commit is contained in:
parent
b719850b15
commit
bee536c715
2
.gitignore
vendored
2
.gitignore
vendored
@ -2,3 +2,5 @@
|
||||
/.env
|
||||
/.idea
|
||||
/TODO.txt
|
||||
/logs
|
||||
/__pycache__
|
||||
116
telezab.py
116
telezab.py
@ -1,7 +1,7 @@
|
||||
import os
|
||||
from flask import Flask, request, jsonify
|
||||
import telebot
|
||||
from dotenv import load_dotenv
|
||||
import os
|
||||
import hashlib
|
||||
import logging
|
||||
from logging.config import dictConfig
|
||||
@ -19,83 +19,63 @@ import requests
|
||||
# Load environment variables
|
||||
load_dotenv()
|
||||
|
||||
# Configure logging
|
||||
DEBUG_LOGGING = os.getenv('DEBUG_LOGGING', 'false').lower() == 'true'
|
||||
|
||||
if DEBUG_LOGGING:
|
||||
log_level = 'DEBUG'
|
||||
else:
|
||||
log_level = 'INFO'
|
||||
|
||||
# Чтение переменных окружения
|
||||
# Read environment variables for logging configuration
|
||||
ENABLE_CONSOLE_LOGGING = os.getenv('ENABLE_CONSOLE_LOGGING', 'true').lower() in ['true', '1', 'yes']
|
||||
ENABLE_WSGI_LOGGING = os.getenv('ENABLE_WSGI_LOGGING', 'true').lower() in ['true', '1', 'yes']
|
||||
ENABLE_FILE_LOGGING_CONSOLE = os.getenv('ENABLE_FILE_LOGGING_CONSOLE', 'false').lower() in ['true', '1', 'yes']
|
||||
ENABLE_FILE_LOGGING_FLASK = os.getenv('ENABLE_FILE_LOGGING_FLASK', 'false').lower() in ['true', '1', 'yes']
|
||||
ENABLE_FILE_LOGGING = os.getenv('ENABLE_FILE_LOGGING', 'true').lower() in ['true', '1', 'yes']
|
||||
|
||||
# Определение путей для файлов логирования
|
||||
LOG_PATH_CONSOLE = os.getenv('LOG_PATH_CONSOLE', 'logs/console.log')
|
||||
LOG_PATH_FLASK = os.getenv('LOG_PATH_FLASK', 'logs/flask.log')
|
||||
# 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')
|
||||
|
||||
# Создание директории для логов, если она не существует
|
||||
os.makedirs(os.path.dirname(LOG_PATH_CONSOLE), exist_ok=True)
|
||||
os.makedirs(os.path.dirname(LOG_PATH_FLASK), exist_ok=True)
|
||||
# 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)
|
||||
|
||||
# Определение обработчиков на основе переменных окружения
|
||||
# Define handlers based on environment variables
|
||||
handlers = {}
|
||||
if ENABLE_CONSOLE_LOGGING:
|
||||
handlers['console'] = {
|
||||
'class': 'logging.StreamHandler',
|
||||
'stream': 'ext://sys.stdout', # Вывод в консоль
|
||||
'stream': 'ext://sys.stdout', # Output to console
|
||||
'formatter': 'console',
|
||||
}
|
||||
if ENABLE_WSGI_LOGGING:
|
||||
handlers['wsgi'] = {
|
||||
'class': 'logging.StreamHandler',
|
||||
'stream': 'ext://flask.logging.wsgi_errors_stream', # Логирование ошибок WSGI
|
||||
'formatter': 'flask',
|
||||
}
|
||||
if ENABLE_FILE_LOGGING_CONSOLE:
|
||||
handlers['file_console'] = {
|
||||
if ENABLE_FILE_LOGGING:
|
||||
handlers['file_errors'] = {
|
||||
'class': 'logging.FileHandler',
|
||||
'filename': LOG_PATH_CONSOLE,
|
||||
'formatter': 'console',
|
||||
'filename': LOG_PATH_ERRORS,
|
||||
'formatter': 'error',
|
||||
}
|
||||
if ENABLE_FILE_LOGGING_FLASK:
|
||||
handlers['file_flask'] = {
|
||||
handlers['file_events'] = {
|
||||
'class': 'logging.FileHandler',
|
||||
'filename': LOG_PATH_FLASK,
|
||||
'formatter': 'flask',
|
||||
'filename': LOG_PATH_EVENTS,
|
||||
'formatter': 'event',
|
||||
}
|
||||
|
||||
# Configure logging
|
||||
dictConfig({
|
||||
'version': 1,
|
||||
'formatters': {
|
||||
'default': {
|
||||
'format': '[%(asctime)s] %(levelname)s %(module)s: %(message)s [Location: %(extra)s]',
|
||||
'format': '[%(asctime)s] %(levelname)s %(module)s: %(message)s',
|
||||
},
|
||||
'console': {
|
||||
'format': '[Location: console] [%(asctime)s] %(levelname)s %(module)s: %(message)s ',
|
||||
'format': '[%(asctime)s] %(levelname)s %(module)s: %(message)s',
|
||||
},
|
||||
'flask': {
|
||||
'format': '[Location: flask] [%(asctime)s] %(levelname)s %(module)s: %(message)s ',
|
||||
'error': {
|
||||
'format': '[%(asctime)s] ERROR %(module)s: %(message)s',
|
||||
},
|
||||
'event': {
|
||||
'format': '[%(asctime)s] EVENT %(module)s: %(message)s',
|
||||
},
|
||||
},
|
||||
'handlers': handlers,
|
||||
'loggers': {
|
||||
'werkzeug': { # Flask логер
|
||||
'level': 'INFO',
|
||||
'handlers': ['console'] if ENABLE_CONSOLE_LOGGING else [],
|
||||
'propagate': False,
|
||||
'formatter': 'flask',
|
||||
}
|
||||
},
|
||||
'root': {
|
||||
'level': 'INFO',
|
||||
'handlers': [handler for handler in handlers.keys()],
|
||||
'handlers': list(handlers.keys()),
|
||||
}
|
||||
})
|
||||
|
||||
# Initialize Flask application
|
||||
app = Flask(__name__)
|
||||
|
||||
# Get the token from environment variables
|
||||
@ -124,6 +104,7 @@ SETTINGS_MODE = 2
|
||||
user_states = {}
|
||||
user_timers = {}
|
||||
|
||||
|
||||
# Initialize SQLite database
|
||||
def init_db():
|
||||
with db_lock:
|
||||
@ -174,10 +155,12 @@ def init_db():
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
|
||||
# Hash the incoming data
|
||||
def hash_data(data):
|
||||
return hashlib.sha256(str(data).encode('utf-8')).hexdigest()
|
||||
|
||||
|
||||
# Check if user is in whitelist
|
||||
def is_whitelisted(chat_id):
|
||||
with db_lock:
|
||||
@ -190,6 +173,7 @@ def is_whitelisted(chat_id):
|
||||
conn.close()
|
||||
return count > 0
|
||||
|
||||
|
||||
# Add user to whitelist
|
||||
def add_to_whitelist(chat_id):
|
||||
with db_lock:
|
||||
@ -201,6 +185,7 @@ def add_to_whitelist(chat_id):
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
|
||||
# Remove user from whitelist
|
||||
def remove_from_whitelist(chat_id):
|
||||
with db_lock:
|
||||
@ -212,6 +197,7 @@ def remove_from_whitelist(chat_id):
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
|
||||
# Get list of regions
|
||||
def get_regions():
|
||||
with db_lock:
|
||||
@ -222,6 +208,7 @@ def get_regions():
|
||||
conn.close()
|
||||
return regions
|
||||
|
||||
|
||||
def get_sorted_regions():
|
||||
with db_lock:
|
||||
conn = sqlite3.connect('telezab.db')
|
||||
@ -234,6 +221,7 @@ def get_sorted_regions():
|
||||
regions.sort(key=lambda x: int(x[0]))
|
||||
return regions
|
||||
|
||||
|
||||
# Check if region exists
|
||||
def region_exists(region_id):
|
||||
with db_lock:
|
||||
@ -244,6 +232,7 @@ 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:
|
||||
@ -260,6 +249,7 @@ def get_user_subscribed_regions(chat_id):
|
||||
conn.close()
|
||||
return regions
|
||||
|
||||
|
||||
# Check if user is subscribed to a region
|
||||
def is_subscribed(chat_id, region_id):
|
||||
with db_lock:
|
||||
@ -274,10 +264,12 @@ 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])
|
||||
|
||||
|
||||
# Log user events
|
||||
def log_user_event(chat_id, username, action):
|
||||
timestamp = time.strftime('%Y-%m-%d %H:%M:%S')
|
||||
@ -290,6 +282,7 @@ def log_user_event(chat_id, username, action):
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
|
||||
# Handle state transitions
|
||||
def set_user_state(chat_id, state):
|
||||
user_states[chat_id] = state
|
||||
@ -298,6 +291,7 @@ def set_user_state(chat_id, state):
|
||||
elif state == NOTIFICATION_MODE:
|
||||
cancel_settings_timer(chat_id)
|
||||
|
||||
|
||||
def start_settings_timer(chat_id):
|
||||
if chat_id in user_timers:
|
||||
user_timers[chat_id].cancel()
|
||||
@ -305,21 +299,25 @@ def start_settings_timer(chat_id):
|
||||
user_timers[chat_id] = timer
|
||||
timer.start()
|
||||
|
||||
|
||||
def cancel_settings_timer(chat_id):
|
||||
if chat_id in user_timers:
|
||||
user_timers[chat_id].cancel()
|
||||
del user_timers[chat_id]
|
||||
|
||||
|
||||
def reset_settings_timer(chat_id):
|
||||
if chat_id in user_timers:
|
||||
user_timers[chat_id].cancel()
|
||||
start_settings_timer(chat_id)
|
||||
|
||||
|
||||
def transition_to_notification_mode(chat_id):
|
||||
set_user_state(chat_id, NOTIFICATION_MODE)
|
||||
bot.send_message(chat_id, "Вы были автоматически переведены в режим получения уведомлений.")
|
||||
app.logger.info(f"User {chat_id} automatically transitioned to notification mode.")
|
||||
|
||||
|
||||
# Main menu for users
|
||||
def show_main_menu(chat_id):
|
||||
markup = telebot.types.ReplyKeyboardMarkup(one_time_keyboard=True, resize_keyboard=True)
|
||||
@ -329,6 +327,7 @@ def show_main_menu(chat_id):
|
||||
markup.add('Регистрация')
|
||||
bot.send_message(chat_id, "Выберите действие:", reply_markup=markup)
|
||||
|
||||
|
||||
# Settings menu for users
|
||||
def show_settings_menu(chat_id):
|
||||
markup = telebot.types.ReplyKeyboardMarkup(one_time_keyboard=True, resize_keyboard=True)
|
||||
@ -339,6 +338,7 @@ def show_settings_menu(chat_id):
|
||||
markup.add('Подписаться', 'Отписаться', 'Мои подписки', 'Активные регионы', 'Назад')
|
||||
bot.send_message(chat_id, "Вы находитесь в режиме настроек. Выберите действие:", reply_markup=markup)
|
||||
|
||||
|
||||
# Handle /start command
|
||||
@bot.message_handler(commands=['start'])
|
||||
def handle_start(message):
|
||||
@ -354,6 +354,7 @@ def handle_start(message):
|
||||
|
||||
app.logger.info(f"User {chat_id} ({username}) started with command /start.")
|
||||
|
||||
|
||||
# Handle menu button presses
|
||||
@bot.message_handler(func=lambda message: True)
|
||||
def handle_menu_selection(message):
|
||||
@ -377,6 +378,7 @@ def handle_menu_selection(message):
|
||||
bot.send_message(chat_id, "Команда не распознана или у вас нет прав для выполнения этой команды.")
|
||||
show_main_menu(chat_id)
|
||||
|
||||
|
||||
# Handle settings menu button presses
|
||||
def handle_settings_menu_selection(message):
|
||||
chat_id = message.chat.id
|
||||
@ -407,6 +409,7 @@ def handle_settings_menu_selection(message):
|
||||
bot.send_message(chat_id, "Команда не распознана.")
|
||||
show_settings_menu(chat_id)
|
||||
|
||||
|
||||
# Handle /subscribe command to subscribe to a region
|
||||
@bot.message_handler(commands=['subscribe', 'sub'])
|
||||
def handle_subscribe(message):
|
||||
@ -426,6 +429,7 @@ def handle_subscribe(message):
|
||||
bot.send_message(chat_id, f"Отправьте номер или номера регионов, на которые хотите подписаться (через запятую):\n{regions_list}\n\nНапишите 'отмена' для отмены.")
|
||||
bot.register_next_step_handler_by_chat_id(chat_id, process_subscription, chat_id, username)
|
||||
|
||||
|
||||
def process_subscription(message, chat_id, username):
|
||||
if message.text.lower() == 'отмена':
|
||||
bot.send_message(chat_id, "Действие отменено.")
|
||||
@ -456,6 +460,7 @@ def process_subscription(message, chat_id, username):
|
||||
log_user_event(chat_id, username, f"Subscribed to regions: {', '.join(region_ids)}")
|
||||
show_settings_menu(chat_id)
|
||||
|
||||
|
||||
# Handle /unsubscribe command to unsubscribe from a region
|
||||
@bot.message_handler(commands=['unsubscribe'])
|
||||
def handle_unsubscribe(message):
|
||||
@ -474,6 +479,7 @@ def handle_unsubscribe(message):
|
||||
bot.send_message(chat_id, f"Отправьте номер или номера регионов, от которых хотите отписаться (через запятую):\n{regions_list}\n\nНапишите 'отмена' для отмены.")
|
||||
bot.register_next_step_handler_by_chat_id(chat_id, process_unsubscription, chat_id)
|
||||
|
||||
|
||||
def process_unsubscription(message, chat_id):
|
||||
if message.text.lower() == 'отмена':
|
||||
bot.send_message(chat_id, "Действие отменено.")
|
||||
@ -501,6 +507,7 @@ def process_unsubscription(message, chat_id):
|
||||
log_user_event(chat_id, username, f"Unsubscribed from regions: {', '.join(region_ids)}")
|
||||
show_settings_menu(chat_id)
|
||||
|
||||
|
||||
# Handle /help command to provide instructions
|
||||
@bot.message_handler(commands=['help'])
|
||||
def handle_help(message):
|
||||
@ -512,6 +519,7 @@ def handle_help(message):
|
||||
bot.send_message(message.chat.id, help_text)
|
||||
show_main_menu(message.chat.id)
|
||||
|
||||
|
||||
# Handle /register command for new user registration
|
||||
@bot.message_handler(commands=['register'])
|
||||
def handle_register(message):
|
||||
@ -528,6 +536,7 @@ def handle_register(message):
|
||||
log_user_event(chat_id, username, "Requested registration")
|
||||
bot.register_next_step_handler(message, process_register, chat_id, username)
|
||||
|
||||
|
||||
def process_register(message, chat_id, username):
|
||||
if message.text.lower() == 'отмена':
|
||||
bot.send_message(chat_id, "Регистрация отменена.")
|
||||
@ -550,6 +559,7 @@ def process_register(message, chat_id, username):
|
||||
bot.send_message(chat_id, "Некорректный выбор. Регистрация отменена.")
|
||||
show_main_menu(chat_id)
|
||||
|
||||
|
||||
# Handle admin region management commands
|
||||
def prompt_admin_for_region(chat_id, action):
|
||||
if action == 'add':
|
||||
@ -559,6 +569,7 @@ def prompt_admin_for_region(chat_id, action):
|
||||
bot.send_message(chat_id, "Введите ID региона, который хотите сделать неактивным")
|
||||
bot.register_next_step_handler_by_chat_id(chat_id, process_remove_region)
|
||||
|
||||
|
||||
def process_add_region(message):
|
||||
chat_id = message.chat.id
|
||||
try:
|
||||
@ -594,6 +605,7 @@ def process_add_region(message):
|
||||
except (IndexError, ValueError):
|
||||
bot.send_message(chat_id, "Неверный формат. Используйте: <region_id> <region_name>")
|
||||
|
||||
|
||||
@bot.callback_query_handler(func=lambda call: call.data.startswith("replace_") or call.data.startswith("reactivate_"))
|
||||
def handle_region_action(call):
|
||||
parts = call.data.split("_", 2)
|
||||
@ -629,6 +641,7 @@ def handle_region_action(call):
|
||||
bot.answer_callback_query(call.id) # Завершение обработки callback
|
||||
show_settings_menu(chat_id)
|
||||
|
||||
|
||||
def process_remove_region(message):
|
||||
chat_id = message.chat.id
|
||||
try:
|
||||
@ -658,6 +671,7 @@ def process_remove_region(message):
|
||||
bot.send_message(chat_id, "Неверный формат. Используйте: <region_id>")
|
||||
show_settings_menu(chat_id)
|
||||
|
||||
|
||||
# Handle admin whitelist management commands
|
||||
def prompt_admin_for_whitelist(chat_id, action):
|
||||
if action == 'add':
|
||||
@ -667,6 +681,7 @@ def prompt_admin_for_whitelist(chat_id, action):
|
||||
bot.send_message(chat_id, "Введите ID пользователя, которого хотите удалить из белого списка")
|
||||
bot.register_next_step_handler_by_chat_id(chat_id, process_remove_whitelist)
|
||||
|
||||
|
||||
def process_add_whitelist(message):
|
||||
chat_id = message.chat.id
|
||||
try:
|
||||
@ -679,6 +694,7 @@ def process_add_whitelist(message):
|
||||
bot.send_message(chat_id, "Неверный формат. Используйте: <chat_id>")
|
||||
show_settings_menu(chat_id)
|
||||
|
||||
|
||||
def process_remove_whitelist(message):
|
||||
chat_id = message.chat.id
|
||||
try:
|
||||
@ -691,6 +707,7 @@ def process_remove_whitelist(message):
|
||||
bot.send_message(chat_id, "Неверный формат. Используйте: <chat_id>")
|
||||
show_settings_menu(chat_id)
|
||||
|
||||
|
||||
# Handle displaying active subscriptions for a user
|
||||
def handle_my_subscriptions(message):
|
||||
chat_id = message.chat.id
|
||||
@ -1003,7 +1020,7 @@ if __name__ == '__main__':
|
||||
init_db()
|
||||
|
||||
# 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()
|
||||
Thread(target=app.run, kwargs={'port': 5000, 'host': '0.0.0.0', 'debug': False, 'use_reloader': False}, daemon=True).start()
|
||||
|
||||
# Start bot polling in a separate thread
|
||||
Thread(target=run_polling, daemon=True).start()
|
||||
@ -1012,3 +1029,4 @@ if __name__ == '__main__':
|
||||
loop = asyncio.get_event_loop()
|
||||
loop.create_task(consume_from_queue())
|
||||
loop.run_forever()
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user