Fix bugs with missing regions id while trying subscribe and unsubscribe to it. Restrict unexpected events
This commit is contained in:
parent
656300d166
commit
85893af256
118
telezab.py
118
telezab.py
@ -156,6 +156,28 @@ def get_regions():
|
|||||||
conn.close()
|
conn.close()
|
||||||
return regions
|
return regions
|
||||||
|
|
||||||
|
def get_sorted_regions():
|
||||||
|
with db_lock:
|
||||||
|
conn = sqlite3.connect('telezab.db')
|
||||||
|
cursor = conn.cursor()
|
||||||
|
cursor.execute('SELECT region_id, region_name FROM regions WHERE active = TRUE')
|
||||||
|
regions = cursor.fetchall()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
# Сортируем регионы по числовому значению region_id
|
||||||
|
regions.sort(key=lambda x: int(x[0]))
|
||||||
|
return regions
|
||||||
|
|
||||||
|
# Check if region exists
|
||||||
|
def region_exists(region_id):
|
||||||
|
with db_lock:
|
||||||
|
conn = sqlite3.connect('telezab.db')
|
||||||
|
cursor = conn.cursor()
|
||||||
|
cursor.execute('SELECT COUNT(*) FROM regions WHERE region_id = ? AND active = TRUE', (region_id,))
|
||||||
|
count = cursor.fetchone()[0]
|
||||||
|
conn.close()
|
||||||
|
return count > 0
|
||||||
|
|
||||||
# Get list of regions a user is subscribed to
|
# Get list of regions a user is subscribed to
|
||||||
def get_user_subscribed_regions(chat_id):
|
def get_user_subscribed_regions(chat_id):
|
||||||
with db_lock:
|
with db_lock:
|
||||||
@ -172,6 +194,20 @@ def get_user_subscribed_regions(chat_id):
|
|||||||
conn.close()
|
conn.close()
|
||||||
return regions
|
return regions
|
||||||
|
|
||||||
|
# Check if user is subscribed to a region
|
||||||
|
def is_subscribed(chat_id, region_id):
|
||||||
|
with db_lock:
|
||||||
|
conn = sqlite3.connect('telezab.db')
|
||||||
|
cursor = conn.cursor()
|
||||||
|
cursor.execute('''
|
||||||
|
SELECT COUNT(*)
|
||||||
|
FROM subscriptions
|
||||||
|
WHERE chat_id = ? AND region_id = ? AND active = TRUE AND skip = FALSE
|
||||||
|
''', (chat_id, region_id))
|
||||||
|
count = cursor.fetchone()[0]
|
||||||
|
conn.close()
|
||||||
|
return count > 0
|
||||||
|
|
||||||
# Format regions list
|
# Format regions list
|
||||||
def format_regions_list(regions):
|
def format_regions_list(regions):
|
||||||
return '\n'.join([f"{region_id} - {region_name}" for region_id, region_name in regions])
|
return '\n'.join([f"{region_id} - {region_name}" for region_id, region_name in regions])
|
||||||
@ -210,7 +246,8 @@ def cancel_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, "Вы были автоматически переведены в режим получения уведомлений.")
|
||||||
|
app.logger.info(f"User {chat_id} automatically transitioned to notification mode.")
|
||||||
|
|
||||||
# Main menu for users
|
# Main menu for users
|
||||||
def show_main_menu(chat_id):
|
def show_main_menu(chat_id):
|
||||||
@ -223,15 +260,13 @@ def show_main_menu(chat_id):
|
|||||||
|
|
||||||
# Settings menu for users
|
# Settings menu for users
|
||||||
def show_settings_menu(chat_id):
|
def show_settings_menu(chat_id):
|
||||||
if user_states != 'NOTIFICATION_MODE':
|
markup = telebot.types.ReplyKeyboardMarkup(one_time_keyboard=True, resize_keyboard=True)
|
||||||
markup = telebot.types.ReplyKeyboardMarkup(one_time_keyboard=True, resize_keyboard=True)
|
if str(chat_id) in ADMIN_CHAT_IDS:
|
||||||
if str(chat_id) in ADMIN_CHAT_IDS:
|
markup.add('Подписаться', 'Отписаться', 'Мои подписки', 'Активные регионы', 'Добавить регион', 'Удалить регион', 'Назад')
|
||||||
markup.add('Подписаться', 'Отписаться', 'Мои подписки', 'Активные регионы', 'Добавить регион', 'Удалить регион', 'Назад')
|
|
||||||
else:
|
|
||||||
markup.add('Подписаться', 'Отписаться', 'Мои подписки', 'Активные регионы', 'Назад')
|
|
||||||
bot.send_message(chat_id, "Вы находитесь в режиме настроек. Выберите действие:", reply_markup=markup)
|
|
||||||
else:
|
else:
|
||||||
pass
|
markup.add('Подписаться', 'Отписаться', 'Мои подписки', 'Активные регионы', 'Назад')
|
||||||
|
bot.send_message(chat_id, "Вы находитесь в режиме настроек. Выберите действие:", reply_markup=markup)
|
||||||
|
|
||||||
# Handle /start command
|
# Handle /start command
|
||||||
@bot.message_handler(commands=['start'])
|
@bot.message_handler(commands=['start'])
|
||||||
def handle_start(message):
|
def handle_start(message):
|
||||||
@ -292,7 +327,7 @@ def handle_settings_menu_selection(message):
|
|||||||
show_settings_menu(chat_id)
|
show_settings_menu(chat_id)
|
||||||
|
|
||||||
# Handle /subscribe command to subscribe to a region
|
# Handle /subscribe command to subscribe to a region
|
||||||
@bot.message_handler(commands=['subscribe'])
|
@bot.message_handler(commands=['subscribe', 'sub'])
|
||||||
def handle_subscribe(message):
|
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):
|
||||||
@ -306,26 +341,26 @@ def handle_subscribe(message):
|
|||||||
else:
|
else:
|
||||||
username = "N/A"
|
username = "N/A"
|
||||||
|
|
||||||
regions_list = format_regions_list(get_regions())
|
regions_list = format_regions_list(get_sorted_regions())
|
||||||
bot.send_message(chat_id, f"Отправьте номер или номера регионов, на которые хотите подписаться (через запятую):\n{regions_list}\n\nНапишите 'отмена' для отмены.")
|
bot.send_message(chat_id, f"Отправьте номер или номера регионов, на которые хотите подписаться (через запятую):\n{regions_list}\n\nНапишите 'отмена' для отмены.")
|
||||||
bot.register_next_step_handler(message, process_subscription, chat_id, username)
|
bot.register_next_step_handler_by_chat_id(chat_id, process_subscription, chat_id, username)
|
||||||
|
|
||||||
def process_subscription(message, chat_id, username):
|
def process_subscription(message, chat_id, username):
|
||||||
if message.text.lower() == 'отмена':
|
if message.text.lower() == 'отмена':
|
||||||
bot.send_message(chat_id, "Действие отменено.")
|
bot.send_message(chat_id, "Действие отменено.")
|
||||||
show_settings_menu(chat_id)
|
return show_settings_menu(chat_id)
|
||||||
return
|
|
||||||
|
|
||||||
region_ids = message.text.split(',')
|
region_ids = message.text.split(',')
|
||||||
|
valid_region_ids = get_regions()
|
||||||
|
valid_region_ids = [region[0] for region in valid_region_ids]
|
||||||
with db_lock:
|
with db_lock:
|
||||||
conn = sqlite3.connect('telezab.db')
|
conn = sqlite3.connect('telezab.db')
|
||||||
cursor = conn.cursor()
|
cursor = conn.cursor()
|
||||||
for region_id in region_ids:
|
for region_id in region_ids:
|
||||||
region_id = region_id.strip()
|
region_id = region_id.strip()
|
||||||
if not region_id.isdigit():
|
if not region_id.isdigit() or region_id not in valid_region_ids:
|
||||||
bot.send_message(chat_id, "Недопустимый формат. Введите только номера регионов.")
|
bot.send_message(chat_id, f"Регион с ID {region_id} не существует или недопустимый формат. Введите только существующие номера регионов.")
|
||||||
show_settings_menu(chat_id)
|
return show_settings_menu(chat_id)
|
||||||
return
|
|
||||||
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}")
|
app.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))
|
||||||
@ -336,12 +371,7 @@ def process_subscription(message, chat_id, username):
|
|||||||
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)}.")
|
app.logger.info(f"User {chat_id} ({username}) subscribed to regions: {', '.join(region_ids)}.")
|
||||||
username = message.from_user.username
|
|
||||||
if username:
|
|
||||||
username = f"@{username}"
|
|
||||||
else:
|
|
||||||
username = "N/A"
|
|
||||||
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)
|
||||||
|
|
||||||
@ -357,38 +387,28 @@ def handle_unsubscribe(message):
|
|||||||
user_regions = get_user_subscribed_regions(chat_id)
|
user_regions = get_user_subscribed_regions(chat_id)
|
||||||
if not user_regions:
|
if not user_regions:
|
||||||
bot.send_message(chat_id, "Вы не подписаны ни на один регион.")
|
bot.send_message(chat_id, "Вы не подписаны ни на один регион.")
|
||||||
|
return show_settings_menu(chat_id)
|
||||||
else:
|
else:
|
||||||
regions_list = format_regions_list(user_regions)
|
regions_list = format_regions_list(user_regions)
|
||||||
bot.send_message(chat_id, f"Отправьте номер или номера регионов, от которых хотите отписаться (через запятую):\n{regions_list}\n\nНапишите 'отмена' для отмены.")
|
bot.send_message(chat_id, f"Отправьте номер или номера регионов, от которых хотите отписаться (через запятую):\n{regions_list}\n\nНапишите 'отмена' для отмены.")
|
||||||
bot.register_next_step_handler(message, process_unsubscription, chat_id)
|
bot.register_next_step_handler_by_chat_id(chat_id, process_unsubscription, chat_id)
|
||||||
|
|
||||||
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, "Действие отменено.")
|
||||||
show_settings_menu(chat_id)
|
return show_settings_menu(chat_id)
|
||||||
return
|
|
||||||
|
|
||||||
region_ids = message.text.split(',')
|
region_ids = message.text.split(',')
|
||||||
|
valid_region_ids = get_user_subscribed_regions(chat_id)
|
||||||
|
valid_region_ids = [region[0] for region in valid_region_ids]
|
||||||
with db_lock:
|
with db_lock:
|
||||||
conn = sqlite3.connect('telezab.db')
|
conn = sqlite3.connect('telezab.db')
|
||||||
cursor = conn.cursor()
|
cursor = conn.cursor()
|
||||||
for region_id in region_ids:
|
for region_id in region_ids:
|
||||||
region_id = region_id.strip()
|
region_id = region_id.strip()
|
||||||
if not region_id.isdigit():
|
if not region_id.isdigit() or region_id not in valid_region_ids:
|
||||||
bot.send_message(chat_id, "Недопустимый формат. Введите только номера регионов.")
|
bot.send_message(chat_id, f"Регион с ID {region_id} не существует или недопустимый формат. Введите только номера регионов, на которые вы подписаны.")
|
||||||
show_settings_menu(chat_id)
|
return show_settings_menu(chat_id)
|
||||||
return
|
|
||||||
|
|
||||||
# Проверяем, существует ли указанный region_id в базе данных
|
|
||||||
query_check = 'SELECT COUNT(*) FROM regions WHERE region_id = ?'
|
|
||||||
cursor.execute(query_check, (region_id,))
|
|
||||||
result = cursor.fetchone()
|
|
||||||
|
|
||||||
if not result or result[0] == 0:
|
|
||||||
bot.send_message(chat_id, f"Регион с номером {region_id} не существует.")
|
|
||||||
show_settings_menu(chat_id)
|
|
||||||
return
|
|
||||||
|
|
||||||
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}")
|
app.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))
|
||||||
@ -396,11 +416,7 @@ def process_unsubscription(message, chat_id):
|
|||||||
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)}.")
|
app.logger.info(f"User {chat_id} unsubscribed from regions: {', '.join(region_ids)}.")
|
||||||
username = message.from_user.username
|
username = message.from_user.username if message.from_user.username else "N/A"
|
||||||
if username:
|
|
||||||
username = f"@{username}"
|
|
||||||
else:
|
|
||||||
username = "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)
|
||||||
|
|
||||||
@ -428,7 +444,6 @@ def handle_register(message):
|
|||||||
markup = telebot.types.ReplyKeyboardMarkup(one_time_keyboard=True, resize_keyboard=True)
|
markup = telebot.types.ReplyKeyboardMarkup(one_time_keyboard=True, resize_keyboard=True)
|
||||||
markup.add('Подтвердить регистрацию', 'Отмена')
|
markup.add('Подтвердить регистрацию', 'Отмена')
|
||||||
bot.send_message(chat_id, f"Ваш chat ID: {chat_id}, ваше имя пользователя: {username}. Запрос на одобрение отправлен администратору.", reply_markup=markup)
|
bot.send_message(chat_id, f"Ваш chat ID: {chat_id}, ваше имя пользователя: {username}. Запрос на одобрение отправлен администратору.", reply_markup=markup)
|
||||||
|
|
||||||
log_user_event(chat_id, username, "Requested registration")
|
log_user_event(chat_id, username, "Requested registration")
|
||||||
bot.register_next_step_handler(message, process_register, chat_id, username)
|
bot.register_next_step_handler(message, process_register, chat_id, username)
|
||||||
|
|
||||||
@ -497,7 +512,8 @@ def process_add_region(message):
|
|||||||
conn.close()
|
conn.close()
|
||||||
except (IndexError, ValueError):
|
except (IndexError, ValueError):
|
||||||
bot.send_message(chat_id, "Неверный формат. Используйте: <region_id> <region_name>")
|
bot.send_message(chat_id, "Неверный формат. Используйте: <region_id> <region_name>")
|
||||||
show_settings_menu(chat_id)
|
# Remove this line to avoid repetitive settings menu message
|
||||||
|
# show_settings_menu(chat_id)
|
||||||
|
|
||||||
@bot.callback_query_handler(func=lambda call: call.data.startswith("replace_") or call.data.startswith("reactivate_"))
|
@bot.callback_query_handler(func=lambda call: call.data.startswith("replace_") or call.data.startswith("reactivate_"))
|
||||||
def handle_region_action(call):
|
def handle_region_action(call):
|
||||||
@ -602,7 +618,7 @@ def handle_active_regions(message):
|
|||||||
app.logger.info(f"Unauthorized access attempt by {chat_id}")
|
app.logger.info(f"Unauthorized access attempt by {chat_id}")
|
||||||
return
|
return
|
||||||
|
|
||||||
regions = get_regions()
|
regions = get_sorted_regions() # Используем функцию для получения отсортированных регионов
|
||||||
if not regions:
|
if not regions:
|
||||||
bot.send_message(chat_id, "Нет активных регионов.")
|
bot.send_message(chat_id, "Нет активных регионов.")
|
||||||
else:
|
else:
|
||||||
@ -675,7 +691,7 @@ if __name__ == '__main__':
|
|||||||
init_db()
|
init_db()
|
||||||
|
|
||||||
# Start Flask app in a separate thread
|
# Start Flask app in a separate thread
|
||||||
Thread(target=app.run, kwargs={'port': 5000, 'use_reloader': False, 'debug': True}, daemon=True).start()
|
Thread(target=app.run, kwargs={'port': 5000, 'debug': True, 'use_reloader': False}, daemon=True).start()
|
||||||
|
|
||||||
# Start bot polling
|
# Start bot polling
|
||||||
run_polling()
|
run_polling()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user