Привет! Сейчас я вышлю наш с тобой последний диалог. Ты мне выслал неправильный код, поэтому вышлю ещё структуру базы данных с последним рабочим кодом. Помоги мне поставленные задачи решить, пожалуйста. Вот мой код последний рабочий: import logging
import pytz
import sqlite3
from datetime import datetime, timedelta
from telegram import Update, ReplyKeyboardMarkup, InlineKeyboardMarkup, InlineKeyboardButton
from telegram.ext import ApplicationBuilder, CommandHandler, ContextTypes, MessageHandler, filters, CallbackQueryHandler, CallbackContext

# Конфигурация логирования
logging.basicConfig(
    format='%(asctime)s - %(message)s',
    level=logging.INFO,
    datefmt='%Y-%m-%d %H:%M:%S'
)

# Установка уровня логирования для telegram и telegram.ext
logging.getLogger("telegram").setLevel(logging.WARNING)
logging.getLogger("telegram.ext").setLevel(logging.WARNING)

# Логируем сообщения пользователей
def log_user_message(user_id, username, first_name, message):
    logging.info(f"{first_name} (@{username}:{user_id}) — {message}")

def get_day_name(index):
    days_rus = [
        "Понедельник",
        "Вторник",
        "Среда",
        "Четверг",
        "Пятница",
        "Суббота",
        "Воскресенье"
    ]
    return days_rus[index]

def is_even_week(date):
    week_number = date.isocalendar()[1]
    return week_number % 2 == 0

def get_week_type(date):
    return 'чётная' if is_even_week(date) else 'нечётная'

def get_week_type_short(date):
    return 'чёт' if is_even_week(date) else 'нечёт'

def is_holiday(date):
    conn = sqlite3.connect('university.db')
    c = conn.cursor()

    if date.weekday() == 6:  # Воскресенье
        conn.close()
        return True
    
    c.execute("SELECT start, end FROM holidays")
    holidays = c.fetchall()

    for start, end in holidays:
        if start is None or end is None:
            continue
        start_date = datetime.strptime(start, '%d.%m.%y').replace(tzinfo=pytz.timezone('Asia/Omsk'))
        end_date = datetime.strptime(end, '%d.%m.%y').replace(tzinfo=pytz.timezone('Asia/Omsk'))
        if start_date <= date <= end_date:
            conn.close()
            return True
    
    # Проверка на праздничный день из папки tp
    c.execute("SELECT day FROM tp")
    tp_days = c.fetchall()
    for row in tp_days:
        tp_day = datetime.strptime(row[0], '%d.%m.%y').replace(tzinfo=pytz.timezone('Asia/Omsk'))
        if tp_day == date:
            conn.close()
            return True

    conn.close()
    return False

def get_schedule_for_day(course, direction, day_name, date):
    week_type = get_week_type(date)
    conn = sqlite3.connect('university.db')
    c = conn.cursor()

    c.execute(
        "SELECT slot, time, details FROM schedule WHERE course = ? AND direction = ? AND week_type = ? AND day = ? ORDER BY slot",
        (course, direction, week_type, day_name)
    )
    results = c.fetchall()
    conn.close()

    if not results:
        return "Нет занятий"

    day_schedule = ""
    for slot, time, details in results:
        if details:
            day_schedule += f"{slot}. {time}\n{details}\n\n"

    return day_schedule.strip() if day_schedule else "Нет занятий"

async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    await update.message.reply_text('Привет! Поменяй группу и курс на соответствующие в своём личном кабинете.')
    await personal_cabinet(update, context)

    keyboard = [
        ["Выбрать дату расписания", "Расписание на завтра", "Расписание на сегодня"],
        ["Понедельник", "Вторник", "Среда"],
        ["Четверг", "Пятница", "Суббота"],
        ["Личный кабинет"]
    ]

    reply_markup = ReplyKeyboardMarkup(keyboard, one_time_keyboard=True, resize_keyboard=True)

    await update.message.reply_text('Выбери опцию:', reply_markup=reply_markup)

async def handle_message(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    user_message = update.message.text
    user_id = update.effective_user.id
    username = update.effective_user.username or "No username"
    first_name = update.effective_user.first_name or "No first name"

    log_user_message(user_id, username, first_name, user_message)

    # Обработка выбора даты через меню
    if user_message.lower() in ["понедельник", "вторник", "среда", "четверг", "пятница", "суббота"]:
        current_date = datetime.now(pytz.timezone('Asia/Omsk'))
        target_date = current_date

        days_ahead = {
            "понедельник": 0,
            "вторник": 1,
            "среда": 2,
            "четверг": 3,
            "пятница": 4,
            "суббота": 5
        }

        day_offset = (days_ahead[user_message.lower()] - target_date.weekday()) % 7
        target_date = current_date + timedelta(days=day_offset)

        day_name = get_day_name(target_date.weekday())

        # Проверяем на выходной
        if is_holiday(target_date):
            message_text = f"{day_name} {target_date.strftime('%d.%m.%Y')} (Выходной день):\n\nВыходной день"
        else:
            conn = sqlite3.connect('university.db')
            c = conn.cursor()
            c.execute("SELECT course, direction FROM users WHERE id = ?", (user_id,))
            user_info = c.fetchone()

            if not user_info:
                await personal_cabinet(update, context)
                conn.close()
                return

            course, direction = user_info
            conn.close()

            week_type_short = get_week_type_short(target_date)
            day_schedule = get_schedule_for_day(course, direction, day_name, target_date)
            message_text = f"{day_name} {target_date.strftime('%d.%m.%Y')} ({week_type_short}):\n\n{day_schedule if day_schedule else 'Нет занятий'}"

        await update.message.reply_text(message_text)

    elif context.user_data.get('awaiting_date', False):
        if user_message.isdigit() and 1 <= int(user_message) <= 31:
            day = int(user_message)
            current_month = datetime.now(pytz.timezone('Asia/Omsk')).month
            current_year = datetime.now(pytz.timezone('Asia/Omsk')).year
            try:
                date_obj = datetime(current_year, current_month, day, tzinfo=pytz.timezone('Asia/Omsk'))
                if date_obj.month != current_month:
                    raise ValueError
                await show_schedule_by_date(update, context, date_obj)
            except ValueError:
                await update.message.reply_text('Неверный день. Пожалуйста, введи число от 1 до последнего дня месяца.')
            finally:
                context.user_data['awaiting_date'] = False
        else:
            await update.message.reply_text('Пожалуйста, введи число для получения расписания.')
        return

    if user_message.lower() in ["расписание на сегодня", "расписание на завтра"]:
        await show_schedule(update, context, user_message)

    elif user_message.lower() == "выбрать дату расписания":
        context.user_data['awaiting_date'] = True
        await update.message.reply_text("Введи необходимое число этого месяца:")

    elif user_message.lower() == "личный кабинет":
        await personal_cabinet(update, context)

    else:
        await update.message.reply_text('Выбери опцию из меню.')

async def personal_cabinet(update: Update, context: ContextTypes.DEFAULT_TYPE):
    user_id = update.effective_user.id
    username = update.effective_user.username or "No username"
    first_name = update.effective_user.first_name or "No first name"
    last_name = update.effective_user.last_name or ""

    conn = sqlite3.connect('university.db')
    c = conn.cursor()

    c.execute("SELECT username, course, direction, subscribed FROM users WHERE id = ?", (user_id,))
    user = c.fetchone()

    if not user:
        c.execute("INSERT INTO users (id, username, course, direction) VALUES (?, ?, ?, ?)", 
                  (user_id, username, 1, "Ф"))
        conn.commit()
        user = (username, 1, "Ф", 1)
    else:
        c.execute("UPDATE users SET username = ? WHERE id = ?", (username, user_id))
        conn.commit()

    c.execute("SELECT 1 FROM admins WHERE id = ?", (user_id,))
    is_admin = c.fetchone() is not None

    c.execute("SELECT tp FROM tp")
    tech_support_nick = c.fetchone()[0]

    conn.close()

    current_date = datetime.now(pytz.timezone('Asia/Omsk'))
    week_number = current_date.isocalendar()[1]
    week_type = get_week_type(current_date)
    week_status = f"{week_number} {week_type}"

    role = "Преподаватель" if is_admin else "Студент"
    subscribe_state = "Отписаться от уведомлений университета" if user[3] else "Подписаться на уведомления университета"

    message_text = (
        f"Личный кабинет\n\n"
        f"Имя: {first_name} {last_name}\n"
        f"Ник: @{user[0]}\n"
        f"ID: {user_id}\n\n"
        f"Роль: {role}\n"
        f"Группа: {user[2]}\n"
        f"Курс: {user[1]}\n\n"
        f"Неделя: {week_status}\n"
        f"Дата: {current_date.strftime('%d.%m.%Y')}\n"
        f"Время: {current_date.strftime('%H:%M:%S')}\n\n"
        f"Тех. поддержка: @{tech_support_nick}"
    )

    keyboard = [
        [
            InlineKeyboardButton("Изменить группу", callback_data='change_direction'),
            InlineKeyboardButton("Изменить курс", callback_data='change_course')
        ],
        [InlineKeyboardButton(subscribe_state, callback_data='toggle_subscription')]
    ]

    if is_admin:
        keyboard.append([
            InlineKeyboardButton("Сделать рассылку", callback_data='send_announcement'),
            InlineKeyboardButton("Глобальная рассылка", callback_data='send_global_announcement')
        ])

    reply_markup = InlineKeyboardMarkup(keyboard)

    if update.callback_query:
        await update.callback_query.edit_message_text(text=message_text, reply_markup=reply_markup)
    else:
        await update.message.reply_text(text=message_text, reply_markup=reply_markup)

async def handle_callback(update: Update, context: CallbackContext):
    query = update.callback_query
    user_id = query.from_user.id
    conn = sqlite3.connect('university.db')
    c = conn.cursor()

    try:
        if query.data == 'change_course':
            c.execute("SELECT course FROM users WHERE id = ?", (user_id,))
            current_course = c.fetchone()[0]
            new_course = 1 if current_course == 4 else current_course + 1
            c.execute("UPDATE users SET course = ? WHERE id = ?", (new_course, user_id))
            conn.commit()
            await query.answer(f"Курс изменён на {new_course}")
            await personal_cabinet(update, context)

        elif query.data == 'change_direction':
            c.execute("SELECT direction FROM users WHERE id = ?", (user_id,))
            current_direction = c.fetchone()[0]
            directions = ['Ф', 'У', 'ФМ', 'ГМУ', 'БИ']
            new_direction_index = (directions.index(current_direction) + 1) % len(directions)
            new_direction = directions[new_direction_index]
            c.execute("UPDATE users SET direction = ? WHERE id = ?", (new_direction, user_id))
            conn.commit()
            await query.answer(f"Группа изменена на {new_direction}")
            await personal_cabinet(update, context)

        elif query.data == 'toggle_subscription':
            c.execute("SELECT subscribed FROM users WHERE id = ?", (user_id,))
            current_subscription = c.fetchone()[0]
            new_subscription = 0 if current_subscription else 1
            c.execute("UPDATE users SET subscribed = ? WHERE id = ?", (new_subscription, user_id))
            conn.commit()
            await query.answer("Подписка обновлена")
            await personal_cabinet(update, context)

        elif query.data == 'send_announcement' and is_admin_user(user_id):
            c.execute("SELECT course, direction FROM users WHERE id = ?", (user_id,))
            admin_info = c.fetchone()
            context.user_data['announcement_for'] = admin_info[:2]
            context.user_data['is_sending_announcement'] = True
            await query.answer("Введите сообщение для рассылки вашей группе")

        elif query.data == 'send_global_announcement' and is_admin_user(user_id):
            context.user_data['announcement_for'] = 'global'
            context.user_data['is_sending_announcement'] = True
            await query.answer("Введите сообщение для глобальной рассылки")

        elif query.data == 'confirm_send':
            await send_announcement(context)
            await update.callback_query.edit_message_text("Успешная отправка.")
            context.user_data['announcement_for'] = None
            await query.answer("Рассылка отправлена.")

        elif query.data == 'cancel_send':
            await update.callback_query.edit_message_text("Отправка отменена.")
            context.user_data['announcement_for'] = None
            await query.answer("Рассылка отменена.")
    except Exception as e:
        logging.error(f"Error in handle_callback: {e}")
        await query.answer("Произошла ошибка, попробуйте еще раз.")
    finally:
        conn.close()

async def collect_announcement(update: Update, context: ContextTypes.DEFAULT_TYPE):
    if not context.user_data.get('is_sending_announcement', False):
        return

    message_text = update.message.text
    if not message_text:
        return

    context.user_data['message_text'] = message_text
    context.user_data['is_sending_announcement'] = False

    confirm_message = f"Вот ваш текст:\n\n{message_text}\n\nХотите отправить?"
    buttons = [
        [
            InlineKeyboardButton("Да", callback_data='confirm_send'),
            InlineKeyboardButton("Нет", callback_data='cancel_send')
        ]
    ]
    reply_markup = InlineKeyboardMarkup(buttons)

    await update.message.reply_text(confirm_message, reply_markup=reply_markup)

async def send_announcement(context: ContextTypes.DEFAULT_TYPE):
    announcement_for = context.user_data.get('announcement_for')
    message_text = context.user_data.get('message_text')

    if not announcement_for or not message_text:
        return

    context.user_data['announcement_for'] = None
    context.user_data['message_text'] = None

    conn = sqlite3.connect('university.db')
    c = conn.cursor()

    if announcement_for == 'global':
        c.execute("SELECT id FROM users WHERE subscribed = 1")
        subscribers = c.fetchall()
        c.execute("SELECT id FROM admins")
        admins = c.fetchall()
    else:
        course, direction = announcement_for
        c.execute("SELECT id FROM users WHERE course = ? AND direction = ? AND subscribed = 1", (course, direction))
        subscribers = c.fetchall()
        c.execute("SELECT id FROM admins")
        admins = c.fetchall()

    conn.close()

    all_recipients = set(subscribers) | set(admins)

    for recipient in all_recipients:
        try:
            await context.bot.send_message(chat_id=recipient[0], text=message_text)
        except Exception as e:
            logging.error(f"Failed to send message to user {recipient[0]}: {e}")

def is_admin_user(user_id):
    conn = sqlite3.connect('university.db')
    c = conn.cursor()
    c.execute("SELECT 1 FROM admins WHERE id = ?", (user_id,))
    is_admin = c.fetchone() is not None
    conn.close()
    return is_admin

async def show_schedule(update: Update, context: ContextTypes.DEFAULT_TYPE, day_command: str):
    user_id = update.message.from_user.id

    conn = sqlite3.connect('university.db')
    c = conn.cursor()
    c.execute("SELECT course, direction FROM users WHERE id = ?", (user_id,))
    user_info = c.fetchone()

    if not user_info:
        await personal_cabinet(update, context)
        c.execute("SELECT course, direction FROM users WHERE id = ?", (user_id,))
        user_info = c.fetchone()

        if not user_info:
            await update.message.reply_text("Ошибка при добавлении пользователя в базу данных.")
            return

    course, direction = user_info
    conn.close()

    current_date = datetime.now(pytz.timezone('Asia/Omsk'))
    current_weekday = current_date.weekday()

    days_map = {
        "расписание на сегодня": 0,
        "расписание на завтра": 1,
        "понедельник": 0,
        "вторник": 1,
        "среда": 2,
        "четверг": 3,
        "пятница": 4,
        "суббота": 5
    }
    day_index = days_map[day_command.lower()]

    if day_command.lower() == "расписание на сегодня":
        target_date = current_date
    elif day_command.lower() == "расписание на завтра":
        target_date = current_date + timedelta(days=1)
    else:
        day_offset = (day_index - current_weekday) % 7
        target_date = current_date + timedelta(days=day_offset)

    day_name = get_day_name(target_date.weekday())
    
    # Проверяем на выходной
    if is_holiday(target_date):
        message_text = f"{day_name} {target_date.strftime('%d.%m.%Y')} (Выходной день):\n\nВыходной день"
    else:
        week_type_short = get_week_type_short(target_date)
        day_schedule = get_schedule_for_day(course, direction, day_name, target_date)
        message_text = f"{day_name} {target_date.strftime('%d.%m.%Y')} ({week_type_short}):\n\n{day_schedule if day_schedule else 'Нет занятий'}"

    await update.message.reply_text(message_text)

async def show_schedule_by_date(update: Update, context: ContextTypes.DEFAULT_TYPE, date_obj):
    user_id = update.message.from_user.id

    conn = sqlite3.connect('university.db')
    c = conn.cursor()
    c.execute("SELECT course, direction FROM users WHERE id = ?", (user_id,))
    user_info = c.fetchone()

    if not user_info:
        await personal_cabinet(update, context)
        c.execute("SELECT course, direction FROM users WHERE id = ?", (user_id,))
        user_info = c.fetchone()

        if not user_info:
            await update.message.reply_text("Ошибка при добавлении пользователя в базу данных.")
            return

    course, direction = user_info
    conn.close()

    day_name = get_day_name(date_obj.weekday())
    
    # Проверяем на выходной
    if is_holiday(date_obj):
        message_text = f"{day_name} {date_obj.strftime('%d.%m.%Y')} (Выходной день):\n\nВыходной день"
    else:
        week_type_short = get_week_type_short(date_obj)
        day_schedule = get_schedule_for_day(course, direction, day_name, date_obj)

        message_text = f"{day_name} {date_obj.strftime('%d.%m.%Y')} ({week_type_short}):\n\n{day_schedule if day_schedule else 'Нет занятий'}"
    
    await update.message.reply_text(message_text)

def mark_holiday(start_date, end_date):
    conn = sqlite3.connect('university.db')
    c = conn.cursor()
    
    if start_date == end_date:
        c.execute("INSERT INTO holidays (start, end) VALUES (?, ?)", 
                  (start_date.strftime('%d.%m.%y'), start_date.strftime('%d.%m.%y')))
    else:
        c.execute("INSERT INTO holidays (start, end) VALUES (?, ?)", 
                  (start_date.strftime('%d.%m.%y'), end_date.strftime('%d.%m.%y')))
        
    conn.commit()
    conn.close()

def main():
    application = ApplicationBuilder().token("YOUR_BOT_TOKEN").build()

    # Добавляем обработчики
    application.add_handler(CommandHandler("start", start))
    application.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_message))
    application.add_handler(CallbackQueryHandler(handle_callback))

    # Запуск бота
    application.run_polling()

if __name__ == '__main__':
    main()  Вот Структура базы данных:
admins (ID)
android_metadata (locale)
holidays (start, end)
schedule (course, direction, week_type, day, slot, time, details)
tp (tp)
users (ID, username, course, direction, subscribed). Ладно диалог я потерял. Суть была в том, что выходной день при вызове этого дня через число и выходной день при вызове этого дня через меню, например, понедельник, разные. В первом случае пишется, что это выходной, а во втором выдаётся расписание, чего быть не должно