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
108
telezab.py
108
telezab.py
@ -156,6 +156,28 @@ def get_regions():
|
||||
conn.close()
|
||||
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
|
||||
def get_user_subscribed_regions(chat_id):
|
||||
with db_lock:
|
||||
@ -172,6 +194,20 @@ 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:
|
||||
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
|
||||
def format_regions_list(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):
|
||||
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):
|
||||
@ -223,15 +260,13 @@ def show_main_menu(chat_id):
|
||||
|
||||
# Settings menu for users
|
||||
def show_settings_menu(chat_id):
|
||||
if user_states != 'NOTIFICATION_MODE':
|
||||
markup = telebot.types.ReplyKeyboardMarkup(one_time_keyboard=True, resize_keyboard=True)
|
||||
if str(chat_id) in ADMIN_CHAT_IDS:
|
||||
markup.add('Подписаться', 'Отписаться', 'Мои подписки', 'Активные регионы', 'Добавить регион', 'Удалить регион', 'Назад')
|
||||
else:
|
||||
markup.add('Подписаться', 'Отписаться', 'Мои подписки', 'Активные регионы', 'Назад')
|
||||
bot.send_message(chat_id, "Вы находитесь в режиме настроек. Выберите действие:", reply_markup=markup)
|
||||
else:
|
||||
pass
|
||||
|
||||
# Handle /start command
|
||||
@bot.message_handler(commands=['start'])
|
||||
def handle_start(message):
|
||||
@ -292,7 +327,7 @@ def handle_settings_menu_selection(message):
|
||||
show_settings_menu(chat_id)
|
||||
|
||||
# Handle /subscribe command to subscribe to a region
|
||||
@bot.message_handler(commands=['subscribe'])
|
||||
@bot.message_handler(commands=['subscribe', 'sub'])
|
||||
def handle_subscribe(message):
|
||||
chat_id = message.chat.id
|
||||
if not is_whitelisted(chat_id):
|
||||
@ -306,26 +341,26 @@ def handle_subscribe(message):
|
||||
else:
|
||||
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.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):
|
||||
if message.text.lower() == 'отмена':
|
||||
bot.send_message(chat_id, "Действие отменено.")
|
||||
show_settings_menu(chat_id)
|
||||
return
|
||||
return show_settings_menu(chat_id)
|
||||
|
||||
region_ids = message.text.split(',')
|
||||
valid_region_ids = get_regions()
|
||||
valid_region_ids = [region[0] for region in valid_region_ids]
|
||||
with db_lock:
|
||||
conn = sqlite3.connect('telezab.db')
|
||||
cursor = conn.cursor()
|
||||
for region_id in region_ids:
|
||||
region_id = region_id.strip()
|
||||
if not region_id.isdigit():
|
||||
bot.send_message(chat_id, "Недопустимый формат. Введите только номера регионов.")
|
||||
show_settings_menu(chat_id)
|
||||
return
|
||||
if not region_id.isdigit() or region_id not in valid_region_ids:
|
||||
bot.send_message(chat_id, f"Регион с ID {region_id} не существует или недопустимый формат. Введите только существующие номера регионов.")
|
||||
return show_settings_menu(chat_id)
|
||||
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}")
|
||||
cursor.execute(query, (chat_id, region_id, username))
|
||||
@ -336,12 +371,7 @@ def process_subscription(message, chat_id, username):
|
||||
conn.commit()
|
||||
conn.close()
|
||||
bot.send_message(chat_id, f"Подписка на регионы: {', '.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"
|
||||
app.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)}")
|
||||
show_settings_menu(chat_id)
|
||||
|
||||
@ -357,38 +387,28 @@ def handle_unsubscribe(message):
|
||||
user_regions = get_user_subscribed_regions(chat_id)
|
||||
if not user_regions:
|
||||
bot.send_message(chat_id, "Вы не подписаны ни на один регион.")
|
||||
return show_settings_menu(chat_id)
|
||||
else:
|
||||
regions_list = format_regions_list(user_regions)
|
||||
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):
|
||||
if message.text.lower() == 'отмена':
|
||||
bot.send_message(chat_id, "Действие отменено.")
|
||||
show_settings_menu(chat_id)
|
||||
return
|
||||
return show_settings_menu(chat_id)
|
||||
|
||||
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:
|
||||
conn = sqlite3.connect('telezab.db')
|
||||
cursor = conn.cursor()
|
||||
for region_id in region_ids:
|
||||
region_id = region_id.strip()
|
||||
if not region_id.isdigit():
|
||||
bot.send_message(chat_id, "Недопустимый формат. Введите только номера регионов.")
|
||||
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
|
||||
|
||||
if not region_id.isdigit() or region_id not in valid_region_ids:
|
||||
bot.send_message(chat_id, f"Регион с ID {region_id} не существует или недопустимый формат. Введите только номера регионов, на которые вы подписаны.")
|
||||
return show_settings_menu(chat_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}")
|
||||
cursor.execute(query, (chat_id, region_id))
|
||||
@ -396,11 +416,7 @@ def process_unsubscription(message, chat_id):
|
||||
conn.close()
|
||||
bot.send_message(chat_id, f"Отписка от регионов: {', '.join(region_ids)} оформлена.")
|
||||
app.logger.info(f"User {chat_id} unsubscribed from regions: {', '.join(region_ids)}.")
|
||||
username = message.from_user.username
|
||||
if username:
|
||||
username = f"@{username}"
|
||||
else:
|
||||
username = "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)}")
|
||||
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.add('Подтвердить регистрацию', 'Отмена')
|
||||
bot.send_message(chat_id, f"Ваш chat ID: {chat_id}, ваше имя пользователя: {username}. Запрос на одобрение отправлен администратору.", reply_markup=markup)
|
||||
|
||||
log_user_event(chat_id, username, "Requested registration")
|
||||
bot.register_next_step_handler(message, process_register, chat_id, username)
|
||||
|
||||
@ -497,7 +512,8 @@ def process_add_region(message):
|
||||
conn.close()
|
||||
except (IndexError, ValueError):
|
||||
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_"))
|
||||
def handle_region_action(call):
|
||||
@ -602,7 +618,7 @@ def handle_active_regions(message):
|
||||
app.logger.info(f"Unauthorized access attempt by {chat_id}")
|
||||
return
|
||||
|
||||
regions = get_regions()
|
||||
regions = get_sorted_regions() # Используем функцию для получения отсортированных регионов
|
||||
if not regions:
|
||||
bot.send_message(chat_id, "Нет активных регионов.")
|
||||
else:
|
||||
@ -675,7 +691,7 @@ if __name__ == '__main__':
|
||||
init_db()
|
||||
|
||||
# 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
|
||||
run_polling()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user