add gitignore

This commit is contained in:
Udo Chudo 2024-07-29 16:11:22 +05:00
parent b719850b15
commit bee536c715
2 changed files with 69 additions and 49 deletions

2
.gitignore vendored
View File

@ -2,3 +2,5 @@
/.env
/.idea
/TODO.txt
/logs
/__pycache__

View File

@ -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()