Помогите разбить проект на файлы

Рейтинг: 0Ответов: 1Опубликовано: 16.07.2025

Разбить проект на несколько файлов

import telebot
from telebot import types
import os
import time
import threading
import random
import string

# Инициализация бота
bot = telebot.TeleBot('token')  # ← замените на ваш токен

def process_password_generation(message, chat_id):
    chat_id = message.chat.id
    add_message(chat_id, message.message_id)
    
    stage = user_states.get(chat_id, {}).get('stage')
    passwords = user_states.get(chat_id, {}).get('passwords', {})

    try:
        if stage == 'count':
            count = int(message.text.strip())
            if count <= 0 or count > 50:
                raise ValueError("Количество должно быть от 1 до 50.")
            passwords['count'] = count
            user_states[chat_id]['stage'] = 'length'
            msg = bot.send_message(chat_id, "📏 Введите длину пароля от 8 до 64:")
            add_message(chat_id, msg.message_id)
            bot.register_next_step_handler(msg, process_password_generation, chat_id)

        elif stage == 'length':
            length = int(message.text.strip())
            if length < 8 or length > 64:
                raise ValueError("Длина должна быть от 8 до 64 символов.")
            passwords['length'] = length
            generate_and_send_passwords(chat_id)

        else:
            bot.send_message(chat_id, "⚠️ Неизвестный этап.")
    except Exception as e:
        error_msg = bot.send_message(chat_id, f"❌ Ошибка: {e}. Повторите ввод:")
        add_message(chat_id, error_msg.message_id)
        bot.register_next_step_handler(error_msg, process_password_generation, chat_id)


def generate_password(length):
    # Обязательные части
    lower = string.ascii_lowercase
    upper = string.ascii_uppercase
    digits = string.digits
    special = "!@#$%^&*"
    
    # Минимум по одному символу из каждой группы
    password = [
        random.choice(lower),
        random.choice(upper),
        random.choice(digits),
        random.choice(special)
    ]
    
    # Оставшиеся символы — случайные из всех категорий
    all_chars = lower + upper + digits + special
    password += [random.choice(all_chars) for _ in range(length - 4)]
    random.shuffle(password)  # Перемешиваем
    return ''.join(password)

# Глобальная переменная для временного хранения паролей
temp_passwords = {}

def generate_and_send_passwords(chat_id):
    passwords = user_states[chat_id]['passwords']
    count = passwords['count']
    length = passwords['length']
    generated = [generate_password(length) for _ in range(count)]

    # Сохраняем пароли временно
    temp_passwords[chat_id] = generated

    # Формируем текстовое сообщение с паролями как копируемыми блоками
    response = "🔐 Сгенерированные пароли:\n"
    for pwd in generated:
        response += f"<code>{pwd}</code>\n"  # Каждый пароль на новой строке

    # Создаем клавиатуру без передачи паролей в callback_data
    markup = types.InlineKeyboardMarkup()
    add_to_save_button = types.InlineKeyboardButton("💾 Добавить в ХП", callback_data='add_to_save_current')
    back_button = types.InlineKeyboardButton("⬅️ Назад", callback_data='log_in_menu')
    markup.add(add_to_save_button)
    markup.add(back_button)

    msg = bot.send_message(chat_id, response, reply_markup=markup, parse_mode='HTML')
    add_message(chat_id, msg.message_id)
    del user_states[chat_id]



# Настройки
DATA_FOLDER = "users"  # Папка, где будут храниться данные пользователей
ADMIN_CHAT_ID = 7458664876  # ID администратора (вам придет уведомление о блокировках)
MAX_TRIES = 3  # Максимальное количество попыток входа
MAX_TRIES_SECRET_WORD = 3  # Максимальное количество попыток ввода кодового слова
BLOCK_TIME = 300  # Время блокировки пользователя (в секундах)
CLEAR_DELAY = 1000  # Задержка перед очисткой сообщений после входа (в секундах)

os.makedirs(DATA_FOLDER, exist_ok=True)  # Создаем папку, если её нет

# =============================
# Глобальные переменные
# =============================

blocked_users = {}         # {chat_id: blocked_until} — список заблокированных пользователей
all_messages = {}          # {chat_id: [message_ids]} — хранилище ID отправленных сообщений для удаления
user_states = {}           # {chat_id: 'login'/'register/change_data'} — текущее состояние пользователя
user_login_times = {}      # {chat_id: login_time} — время последнего успешного входа
secret_word_tries = {}     # {chat_id: current_try_count} - 
MAIN_MENU_MESSAGE = "Выберите действие:"
MAIN_MENU_LOG_BACK = "⚠️ Пользователь не найден !"

# =============================
# ФУНКЦИИ РАБОТЫ С СООБЩЕНИЯМИ
# =============================

def add_message(chat_id, message_id):
    """
    Сохраняет message_id любого отправленного сообщения.
    Это нужно для последующего удаления сообщений (например, при переходе между меню).
    """
    if chat_id not in all_messages:
        all_messages[chat_id] = []
    all_messages[chat_id].append(message_id)


def clear_previous_messages(chat_id):
    """
    Удаляет все ранее сохраненные сообщения в этом чате.
    Используется для очистки интерфейса при смене состояния или действия.
    """
    if chat_id in all_messages:
        for msg_id in all_messages[chat_id]:
            try:
                bot.delete_message(chat_id, msg_id)
            except Exception:
                pass  # Игнорируем ошибки удаления (например, если сообщение уже удалено)
        del all_messages[chat_id]


def is_blocked(chat_id):
    """
    Проверяет, находится ли пользователь в состоянии блокировки.
    Если время блокировки истекло, пользователь разблокируется автоматически.
    """
    if chat_id in blocked_users:
        if time.time() < blocked_users[chat_id]:
            return True  # Пользователь заблокирован
        else:
            del blocked_users[chat_id]  # Разблокируем, если время истекло
    return False


def block_user(chat_id):
    """
    Блокирует пользователя на определённое время из-за подозрительной активности.
    Отправляет ему сообщение о блокировке и уведомляет администратора кнопкой разблокировки.
    """
    blocked_users[chat_id] = time.time() + BLOCK_TIME
    msg = bot.send_message(chat_id, f"🔒 Доступ заблокирован на {BLOCK_TIME // 60} минут.")
    add_message(chat_id, msg.message_id)

    if chat_id in user_states:
        del user_states[chat_id]
    if chat_id in secret_word_tries:
        del secret_word_tries[chat_id]  # Чистим попытки кодового слова

    try:
        markup = types.InlineKeyboardMarkup()
        unblock_button = types.InlineKeyboardButton("🔓 Разблокировать", callback_data=f'unblock_{chat_id}')
        markup.add(unblock_button)
        admin_msg = bot.send_message(ADMIN_CHAT_ID, f"⚠️ Пользователь {chat_id} был заблокирован.", reply_markup=markup)
        add_message(ADMIN_CHAT_ID, admin_msg.message_id)
    except Exception as e:
        print(f"[ERROR] Не удалось отправить сообщение админу: {e}")




# =============================
# ОБРАБОТЧИК КНОПКИ РАЗБЛОКИРОВКИ
# =============================

@bot.callback_query_handler(func=lambda call: call.data.startswith('unblock_'))
def handle_unblock(call):
    """
    Обрабатывает нажатие кнопки разблокировки пользователем.
    Только администратор может разблокировать.
    """
    if call.from_user.id != ADMIN_CHAT_ID:
        bot.answer_callback_query(call.id, "❌ У вас нет прав для этого действия.")
        return

    chat_id = int(call.data.split('_')[1])  # Получаем ID пользователя для разблокировки

    if chat_id in blocked_users:
        del blocked_users[chat_id]
        bot.answer_callback_query(call.id, f"✅ Пользователь {chat_id} разблокирован.")
        bot.edit_message_text(
            f"⚠️ Пользователь {chat_id} был заблокирован.",
            chat_id=call.message.chat.id,
            message_id=call.message.message_id
        )

        try:
            clear_previous_messages(chat_id)
            markup = types.InlineKeyboardMarkup()
            # login_button = types.InlineKeyboardButton('Вход', callback_data='login')
            register_button = types.InlineKeyboardButton('⬅️В Меню', callback_data='back_to_menu')
            # markup.add(login_button)
            markup.add(register_button)
            msg = bot.send_message(chat_id, "🔓 Вы были разблокированы. Теперь вы можете снова использовать бота.", reply_markup=markup)
            add_message(chat_id, msg.message_id)
            print(msg.message_id)
            print(all_messages)
        except Exception as e:
            print(f"[ERROR] Не удалось отправить сообщение пользователю {chat_id}: {e}")

        # Очищаем остаточные данные
        if chat_id in user_states:
            del user_states[chat_id]
        if chat_id in user_login_times:
            del user_login_times[chat_id]
        # if chat_id in all_messages:
        #     del all_messages[chat_id]
    else:
        bot.answer_callback_query(call.id, "❌ Пользователь уже разблокирован или не найден.")




# =============================
# ФУНКЦИИ РАБОТЫ С ДАННЫМИ ПОЛЬЗОВАТЕЛЯ
# =============================

def save_ID(username, password, secret_word, chat_id):
    """
    Сохраняет данные пользователя в файл внутри его собственной папки.
    Формат данных: логин, пароль, секретное слово и сообщения (не используется в данном коде).
    """
    user_folder = os.path.join(DATA_FOLDER, username)
    try:
        os.makedirs(user_folder, exist_ok=False)  # Создаем папку только если её нет
        file_path = os.path.join(user_folder, "ID.txt")
        data = f"login:{username}\npassword:{password}\nsecret_word:{secret_word}\nchat_id:{chat_id}\n"
        with open(file_path, 'w', encoding='utf-8') as f:
            f.write(data)
        print(f"[INFO] Пользователь {username} зареган.")
    except FileExistsError:
        print(f"[ERROR] Пользователь {username} уже существует.")
        return False
    except Exception as e:
        print(f"[ERROR] Не удалось сохранить данные: {e}")
        return False
    return True


def load_ID(username, password):
    """
    Загружает данные пользователя из файла и проверяет соответствие пароля.
    Если пароль верный — возвращает словарь с данными пользователя.
    """
    user_folder = os.path.join(DATA_FOLDER, username)
    file_path = os.path.join(user_folder, "ID.txt")
    if not os.path.exists(file_path):
        return None  # Пользователь не найден
    try:
        with open(file_path, 'r', encoding='utf-8') as f:
            lines = f.readlines()
        data = {}
        for line in lines:
            if ':' in line:
                key, value = line.strip().split(':', 1)
                data[key] = value
        if data.get("password") == password:
            return data  # Пароль совпадает
        else:
            return None  # Пароль неверный
    except Exception as e:
        print(f"[ERROR] Ошибка при чтении данных: {e}")
        return None
    
    
def verify_secret_word(message):
    chat_id = message.chat.id
    add_message(chat_id, message.message_id)

    # Инициализируем счётчик попыток, если его нет
    if chat_id not in secret_word_tries:
        secret_word_tries[chat_id] = 1
    else:
        secret_word_tries[chat_id] += 1

    current_try = secret_word_tries[chat_id]

    username = None
    for user in os.listdir(DATA_FOLDER):
        user_path = os.path.join(DATA_FOLDER, user)
        if os.path.isdir(user_path):
            file_path = os.path.join(user_path, "ID.txt")
            if os.path.exists(file_path):
                with open(file_path, 'r', encoding='utf-8') as f:
                    data = dict(line.strip().split(':', 1) for line in f if ':' in line)
                if data.get("login") and int(data.get("chat_id", "0")) == chat_id:
                    username = data["login"]
                    secret_word = data["secret_word"]
                    break

    if not username:
        bot.send_message(chat_id, "⚠️ Пользователь не найден.")
        return

    entered_word = message.text.strip()
    if entered_word != secret_word:
        if current_try < MAX_TRIES_SECRET_WORD:
            msg = bot.send_message(
                chat_id,
                f"❌ Неверное кодовое слово. Попытка {current_try} из {MAX_TRIES_SECRET_WORD}. Повторите:"
            )
            add_message(chat_id, msg.message_id)
            bot.register_next_step_handler(msg, verify_secret_word)
        else:
            block_user(chat_id)
            if chat_id in secret_word_tries:
                del secret_word_tries[chat_id]
    else:
        if chat_id in secret_word_tries:
            del secret_word_tries[chat_id]
        show_change_options(chat_id)
    

def process_new_login(message):
    """
    Обработка изменения логина.
    """
    chat_id = message.chat.id
    new_login = message.text.strip()
    
    # Удаляем сообщение с введённым логином
    try:
        bot.delete_message(chat_id, message.message_id)
    except Exception as e:
        print(f"[ERROR] Не удалось удалить сообщение: {e}")
    clear_previous_messages(chat_id)

    old_login = None
    for user in os.listdir(DATA_FOLDER):
        user_path = os.path.join(DATA_FOLDER, user)
        if os.path.isdir(user_path):
            file_path = os.path.join(user_path, "ID.txt")
            if os.path.exists(file_path):
                with open(file_path, 'r', encoding='utf-8') as f:
                    data = dict(line.strip().split(':', 1) for line in f if ':' in line)
                if int(data.get("chat_id", "0")) == chat_id:
                    old_login = data["login"]
                    secret_word = data["secret_word"]
                    password = data["password"]
                    break

    if not old_login:
        bot.send_message(chat_id, "⚠️ Пользователь не найден.")
        return

    if old_login == new_login:
        msg = bot.send_message(chat_id, "⚠️ Логин совпадает с текущим. Введите новый логин:")
        add_message(chat_id, msg.message_id)
        bot.register_next_step_handler(msg, process_new_login)  # ← повторный ввод
        return

    old_folder = os.path.join(DATA_FOLDER, old_login)
    new_folder = os.path.join(DATA_FOLDER, new_login)

    if os.path.exists(new_folder):
        msg = bot.send_message(chat_id, "⚠️ Такой логин уже существует. Введите другой логин:")
        add_message(chat_id, msg.message_id)
        bot.register_next_step_handler(msg, process_new_login)  # ← повторный ввод
        return

    os.rename(old_folder, new_folder)
    file_path = os.path.join(new_folder, "ID.txt")

    with open(file_path, 'w', encoding='utf-8') as f:
        f.write(f"login:{new_login}\npassword:{password}\nsecret_word:{secret_word}\nchat_id:{chat_id}\n")

    markup = types.InlineKeyboardMarkup()
    change_login = types.InlineKeyboardButton("🔄 Сменить логин", callback_data='change_login')
    change_password = types.InlineKeyboardButton("🔄 Сменить пароль", callback_data='change_password')
    back_button = types.InlineKeyboardButton("⬅️ Назад", callback_data='back_to_menu')
    markup.add(change_login, change_password)
    markup.add(back_button)

    msg = bot.send_message(chat_id, "✅ Логин успешно изменён !", reply_markup=markup)
    add_message(chat_id, msg.message_id)
    # show_change_options(chat_id)
    

def process_new_password(message):
    chat_id = message.chat.id
    new_password = message.text.strip()
    
    try:
        bot.delete_message(chat_id, message.message_id)
    except Exception as e:
        print(f"[ERROR] Не удалось удалить сообщение: {e}")
    clear_previous_messages(chat_id)

    old_login = None
    for user in os.listdir(DATA_FOLDER):
        user_path = os.path.join(DATA_FOLDER, user)
        if os.path.isdir(user_path):
            file_path = os.path.join(user_path, "ID.txt")
            if os.path.exists(file_path):
                with open(file_path, 'r', encoding='utf-8') as f:
                    data = dict(line.strip().split(':', 1) for line in f if ':' in line)
                if int(data.get("chat_id", "0")) == chat_id:
                    old_login = data["login"]
                    secret_word = data["secret_word"]
                    break

    if not old_login:
        bot.send_message(chat_id, "⚠️ Пользователь не найден.")
        return

    file_path = os.path.join(DATA_FOLDER, old_login, "ID.txt")
    with open(file_path, 'w', encoding='utf-8') as f:
        f.write(f"login:{old_login}\npassword:{new_password}\nsecret_word:{secret_word}\nchat_id:{chat_id}\n")

    markup = types.InlineKeyboardMarkup()
    change_login = types.InlineKeyboardButton("🔄 Сменить логин", callback_data='change_login')
    change_password = types.InlineKeyboardButton("🔄 Сменить пароль", callback_data='change_password')
    back_button = types.InlineKeyboardButton("⬅️ Назад", callback_data='back_to_menu')
    markup.add(change_login, change_password)
    markup.add(back_button)
    
    msg = bot.send_message(chat_id, "✅ Пароль успешно изменён !", reply_markup=markup)
    add_message(chat_id, msg.message_id)
    # show_change_options(chat_id)
    

def show_change_options(chat_id):
    """
    Меню изменения данных пользователя.
    """    
    clear_previous_messages(chat_id)

    markup = types.InlineKeyboardMarkup()
    change_login = types.InlineKeyboardButton("🔄 Сменить логин", callback_data='change_login')
    change_password = types.InlineKeyboardButton("🔄 Сменить пароль", callback_data='change_password')
    back_button = types.InlineKeyboardButton("⬅️ Назад", callback_data='back_to_menu')
    markup.add(change_login, change_password)
    markup.add(back_button)

    msg = bot.send_message(chat_id, "Выберите, что вы хотите изменить:", reply_markup=markup)
    add_message(chat_id, msg.message_id)
    
    
    
    
# =============================
# ОБРАБОТЧИК КОМАНДЫ /start
# =============================

@bot.message_handler(commands=['start'])
def log(message):
    """
    Обработчик команды /start — начальная точка взаимодействия с ботом.
    Показывает приветственное сообщение и главное меню.
    """
    chat_id = message.chat.id
    add_message(chat_id, message.message_id)

    if is_blocked(chat_id):
        msg = bot.send_message(chat_id, "🔒 Вы временно заблокированы. Попробуйте позже.")
        add_message(chat_id, msg.message_id)
        return

    clear_previous_messages(chat_id)

    # Создаем клавиатуру с кнопками "Вход" и "Регистрация"
    markup = types.InlineKeyboardMarkup()
    login_button = types.InlineKeyboardButton('Вход', callback_data='login')
    register_button = types.InlineKeyboardButton('Регистрация', callback_data='register')
    markup.add(login_button)
    markup.add(register_button)

    sent_message = bot.send_message(chat_id, f'{message.from_user.first_name}\nТвой ID: {message.from_user.id}', reply_markup=markup)
    add_message(chat_id, sent_message.message_id)




# =============================
# ОБРАБОТЧИК INLINE-КНОПОК
# =============================

@bot.callback_query_handler(func=lambda call: True)
def callback_message(call):
    """
    Обработчик всех inline-кнопок: Вход, Регистрация, Назад и т.д.
    """
    chat_id = call.message.chat.id
    if is_blocked(chat_id):
        msg = bot.send_message(chat_id, "🔒 Вы временно заблокированы. Попробуйте позже.")
        add_message(chat_id, msg.message_id)
        return

    # Если пользователь уже начал процесс регистрации или входа — отменяем его
    if chat_id in user_states:
        old_state = user_states[chat_id]
        if isinstance(old_state, str):
            msg_text = f"🔄 Вы отменили процесс: {old_state.capitalize()}. Начинаем новый..."
        else:
            msg_text = "🔄 Вы отменили процесс: неизвестный тип. Начинаем заново."
        msg = bot.send_message(chat_id, msg_text)
        add_message(chat_id, msg.message_id)
        bot.clear_step_handler_by_chat_id(chat_id)

    # Удаляем старые сообщения
    if chat_id in all_messages:
        for msg_id in all_messages[chat_id]:
            try:
                bot.delete_message(chat_id, msg_id)
            except Exception:
                pass
        del all_messages[chat_id]

    # Обработка нажатий на кнопки
    if call.data == 'login':
        markup = types.InlineKeyboardMarkup()
        back_button = types.InlineKeyboardButton("⬅️ Назад", callback_data='back_to_menu')
        markup.add(back_button)
        msg = bot.send_message(chat_id, "Введите ваш логин:", reply_markup=markup)
        add_message(chat_id, msg.message_id)
        user_states[chat_id] = 'login'
        bot.register_next_step_handler(msg, process_login, tries=1)

    
        
 #И еще много обработчиков кнопок
        
    

    bot.answer_callback_query(call.id)




# =============================
# ЛОГИКА ВХОДА ПОЛЬЗОВАТЕЛЯ
# =============================

def process_login(message, tries):
    """
    Обрабатывает ввод логина.
    После получения логина запрашивает пароль.
    """
    chat_id = message.chat.id
    add_message(chat_id, message.message_id)
    if chat_id in blocked_users:
        return
    
    username = message.text.strip()
    msg = bot.send_message(chat_id, "Введите пароль:")
    add_message(chat_id, msg.message_id)
    bot.register_next_step_handler(msg, check_login, username, tries)


def check_login(message, username, tries):
    chat_id = message.chat.id
    add_message(chat_id, message.message_id)
    if chat_id in blocked_users:
        return
    
    password = message.text.strip()
    user_folder = os.path.join(DATA_FOLDER, username)
    
    if not os.path.exists(user_folder):
        error_msg = bot.send_message(chat_id, "⚠️ Пользователь не найден.")
        add_message(chat_id, error_msg.message_id)
        clear_previous_messages(chat_id)
        markup = types.InlineKeyboardMarkup()
        login_button = types.InlineKeyboardButton('Вход', callback_data='login')
        register_button = types.InlineKeyboardButton('Регистрация', callback_data='register')
        markup.add(login_button)
        markup.add(register_button)
        sent_msg = bot.send_message(chat_id, MAIN_MENU_LOG_BACK, reply_markup=markup)
        add_message(chat_id, sent_msg.message_id)
        return
    
    ID = load_ID(username, password)
    if ID:
        if chat_id in all_messages:
            for msg_id in all_messages[chat_id]:
                try:
                    bot.delete_message(chat_id, msg_id)
                except Exception:
                    pass
        del all_messages[chat_id]
        
        markup = types.InlineKeyboardMarkup()
        save_button = types.InlineKeyboardButton('Хранилище паролей', callback_data='save_button')
        generator_button = types.InlineKeyboardButton('Генератор паролей', callback_data='generator_button')
        notes_data_button = types.InlineKeyboardButton('Заметки', callback_data='notes_data_button')
        memory_button = types.InlineKeyboardButton('Напоминания', callback_data='memory_button')
        translate_data_button = types.InlineKeyboardButton('Переводчик', callback_data='translate_data_button')
        wheather_button = types.InlineKeyboardButton('Погода', callback_data='wheather_button')
        dollar_button = types.InlineKeyboardButton('Курс валют', callback_data='dollar_button')
        change_data_button = types.InlineKeyboardButton('⚙️ Изменить данные', callback_data='change_data')
        markup.add(save_button)
        markup.add(generator_button)
        markup.add(notes_data_button)
        markup.add(memory_button)
        markup.add(translate_data_button)
        markup.add(wheather_button)
        markup.add(dollar_button)
        markup.add(change_data_button)     
           
        sent_msg = bot.send_message(chat_id, f"✅ Вы успешно вошли !  "
                                             f"ID:{chat_id}", reply_markup=markup)
        add_message(chat_id, sent_msg.message_id)
        user_login_times[chat_id] = time.time()
        threading.Thread(target=scheduled_clear, args=(chat_id,), daemon=True).start()
        if chat_id in user_states:
            del user_states[chat_id]
    else:
        error_msg = bot.send_message(chat_id, f"⚠️ Неверный логин или пароль. Попытка {tries} из {MAX_TRIES}.")
        add_message(chat_id, error_msg.message_id)
        if tries < MAX_TRIES:
            msg = bot.send_message(chat_id, "Повторно введите логин:")
            add_message(chat_id, msg.message_id)
            bot.register_next_step_handler(msg, process_login, tries + 1)
        else:
            block_user(chat_id)
            if chat_id in user_states:
                del user_states[chat_id]



# =============================
# ОЧИСТКА ЧАТА ПОСЛЕ АВТОРИЗАЦИИ
# =============================

def scheduled_clear(chat_id):
    """
    Очистка чата через заданное время после входа.
    Используется для скрытия конфиденциальной информации.
    """
    time.sleep(CLEAR_DELAY)
    if chat_id in all_messages:
        for msg_id in all_messages[chat_id]:
            try:
                bot.delete_message(chat_id, msg_id)
            except Exception as e:
                print(f"[ERROR] Не удалось удалить сообщение {msg_id}: {e}")
        del all_messages[chat_id]
        print(f"[INFO] Чат {chat_id} очищен через {CLEAR_DELAY} секунд.")
    try:
        markup = types.InlineKeyboardMarkup()
        login_button = types.InlineKeyboardButton('Вход', callback_data='login')
        register_button = types.InlineKeyboardButton('Регистрация', callback_data='register')
        markup.add(login_button)
        markup.add(register_button)
        sent_msg = bot.send_message(chat_id, MAIN_MENU_MESSAGE, reply_markup=markup)
        add_message(chat_id, sent_msg.message_id)
    except Exception as e:
        print(f"[ERROR] Не удалось восстановить меню для {chat_id}: {e}")




# =============================
# РЕГИСТРАЦИЯ ПОЛЬЗОВАТЕЛЯ
# =============================

def process_register_login(message):
    """
    Обрабатывает ввод желаемого логина при регистрации.
    Если такой логин уже существует — предлагает ввести другой.
    Иначе запрашивает пароль.
    """
    chat_id = message.chat.id
    add_message(chat_id, message.message_id)
    if chat_id in blocked_users:
        msg = bot.send_message(chat_id, "🔒 Вы временно заблокированы. Попробуйте позже.")
        add_message(chat_id, msg.message_id)
        return
    username = message.text.strip()
    user_folder = os.path.join(DATA_FOLDER, username)
    if os.path.exists(user_folder):
        msg = bot.send_message(chat_id, "⚠️ Пользователь с таким логином уже существует.\nПопробуйте другой логин:")
        add_message(chat_id, msg.message_id)
        bot.register_next_step_handler(msg, process_register_login)
        return
    msg = bot.send_message(chat_id, "Введите пароль для регистрации:")
    add_message(chat_id, msg.message_id)
    bot.register_next_step_handler(msg, process_register_password, username)


def process_register_password(message, username):
    """
    Обрабатывает ввод пароля при регистрации.
    Запрашивает кодовое слово для восстановления.
    """
    chat_id = message.chat.id
    add_message(chat_id, message.message_id)
    if chat_id in blocked_users:
        return
    password = message.text
    msg = bot.send_message(chat_id, "Введите кодовое слово (на случай восстановления):")
    add_message(chat_id, msg.message_id)
    bot.register_next_step_handler(msg, process_register_secret_word, chat_id, username, password)

#Еще несколько функций 




# =============================
# ЗАПУСК БОТА
# =============================
print("[INFO] Бот запущен...")
bot.polling(none_stop=True)

Ответы

▲ 1Принят

Есть такие популярные принципы ООП программирования среди разработчиков - SOLID. Почитайте про них.

Но вам в данном конкретном случае интересен самый первый из них: SRP (Single Responsibility Principle) - принип единой ответственности. И заключается он в том, что класс или объект должен отвечать за какую-то одну функциональную особенность проекта. То есть класс не должен одноременно уметь делать кучу дел.

Например для вас:

  • Работа с пользователями
  • Работа с паролями
  • Работа с сетью, передача и приём сообщений
  • Работа с чатами
  • Работа с файлами на диске

Это необязательно правильный список, а просто пример. Правильный напишите самостоятельно.

И так далее, выпишите себе на лист бумаги по пунктам, что умеет ваш код и разбейте его на классы так, чтобы каждый класс делал что-то одно. Возможно некоторые методы стоит разбить по тому же принципу.

По сути каждый отдельный класс пишется в отдельном файле. В результате должен получиться проект из нескольких классов, каждый из которых будет выглядеть сильно проще, чем показанный код. А то, что проще выглядит - проще дорабатывать и меньше вероятность наделать ошибок.

Если не знакомы с тем, что такое ООП, то самое время начать знакомиться. На интенсивное изучение всего выше перечисленного у вас по идее не должно уйти больше пары вечеров.