From d8415cd463715c232766b775c9bc97feedba4519 Mon Sep 17 00:00:00 2001 From: Dmitry Kuklin Date: Sat, 30 Nov 2024 21:11:36 +0300 Subject: [PATCH] Update bot.py --- bot.py | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 105 insertions(+), 9 deletions(-) diff --git a/bot.py b/bot.py index 88749bc..62dcadb 100644 --- a/bot.py +++ b/bot.py @@ -4,16 +4,69 @@ from aiohttp import web from aiogram import F import asyncio +import asyncpg +from datetime import datetime, date +# Конфигурация BOT_TOKEN = "7953304064:AAFpvix8oyAMgrwZ1U_UHBTa7FwFptObJJY" +# Настройки подключения к базе данных +db_config = { + 'host': 'dpg-ct5l2ujtq21c7399jbag-a', + 'user': 'billiardromashkovo_user', + 'password': 'US1b3ybv3DGEbyXnDl09PCWwslf715aC', + 'dbname': 'billiardromashkovo' +} + # Создаем бота и диспетчер bot = Bot(token=BOT_TOKEN) dp = Dispatcher(storage=MemoryStorage()) router = Router() +# Функции для работы с базой данных +async def create_db_pool(): + """Создаёт пул соединений с базой данных.""" + return await asyncpg.create_pool(**db_config) + +async def create_bookings_table(pool): + """Создаёт таблицу для бронирований, если её нет.""" + async with pool.acquire() as conn: + await conn.execute(''' + CREATE TABLE IF NOT EXISTS bookings ( + id SERIAL PRIMARY KEY, + date DATE NOT NULL, + start_time TIME NOT NULL, + end_time TIME NOT NULL + ); + ''') + +async def save_booking(pool, booking_date, start_time, end_time): + """Сохраняет бронирование в базу данных.""" + async with pool.acquire() as conn: + await conn.execute(''' + INSERT INTO bookings (date, start_time, end_time) + VALUES ($1, $2, $3) + ''', booking_date, start_time, end_time) + +async def get_bookings_for_day(pool, booking_date): + """Получает все бронирования для указанного дня.""" + async with pool.acquire() as conn: + return await conn.fetch(''' + SELECT start_time, end_time FROM bookings + WHERE date = $1 + ''', booking_date) + +async def delete_old_bookings(pool): + """Удаляет устаревшие бронирования (до текущей даты).""" + async with pool.acquire() as conn: + await conn.execute(''' + DELETE FROM bookings WHERE date < CURRENT_DATE + ''') + +# Хендлеры @router.message(F.text == "/start") async def send_calendar_link(message: Message): + """Отправляет ссылку на веб-приложение календаря.""" await message.answer( "Откройте календарь:", reply_markup=InlineKeyboardMarkup( @@ -28,26 +81,69 @@ async def send_calendar_link(message: Message): ) ) -# Регистрация маршрутов -dp.include_router(router) +@router.message(F.text.startswith("/book")) +async def handle_booking(message: Message): + """Обрабатывает бронирование через команду /book.""" + pool = await create_db_pool() + parts = message.text.split() + + if len(parts) != 4: + await message.answer("Формат команды: /book YYYY-MM-DD HH:MM HH:MM") + return + + try: + booking_date = date.fromisoformat(parts[1]) + start_time = parts[2] + end_time = parts[3] + + # Проверяем пересечения бронирований + existing_bookings = await get_bookings_for_day(pool, booking_date) + for booking in existing_bookings: + if ( + (start_time >= booking["start_time"] and start_time < booking["end_time"]) or + (end_time > booking["start_time"] and end_time <= booking["end_time"]) + ): + await message.answer("Выбранное время пересекается с существующим бронированием.") + return + # Сохраняем бронирование + await save_booking(pool, booking_date, start_time, end_time) + await message.answer(f"Бронирование успешно создано: {booking_date} с {start_time} до {end_time}") + except ValueError: + await message.answer("Некорректный формат даты или времени. Используйте YYYY-MM-DD HH:MM HH:MM") + finally: + await pool.close() + +# Вебхук async def handle_webhook(request): - """Обработка запросов от Telegram через вебхук""" + """Обрабатывает запросы от Telegram через вебхук.""" data = await request.json() update = Update.to_object(data) await dp.feed_update(bot, update) return web.Response() async def main(): - # Запускаем приложение aiohttp - app = web.Application() - app.router.add_post("/webhook", handle_webhook) # Слушаем /webhook + # Создаём пул соединений с базой данных + pool = await create_db_pool() + + # Создаём таблицу, если её нет + await create_bookings_table(pool) + + # Удаляем устаревшие бронирования + await delete_old_bookings(pool) - # Устанавливаем webhook в Telegram - webhook_url = "https://billiard-romashkovo.onrender.com" # Укажите URL вашего сервера + # Включаем маршруты + dp.include_router(router) + + # Устанавливаем вебхук + webhook_url = "https://billiard-romashkovo.onrender.com/webhook" # Укажите ваш URL await bot.set_webhook(webhook_url) - # Запускаем aiohttp + # Создаём приложение aiohttp + app = web.Application() + app.router.add_post("/webhook", handle_webhook) + + # Запускаем сервер runner = web.AppRunner(app) await runner.setup() site = web.TCPSite(runner, host="0.0.0.0", port=4000)