gigacook
/
main.py
138 строк · 5.3 Кб
1import logging
2from os import environ
3
4from dotenv import load_dotenv
5from telegram import BotCommand, InlineKeyboardButton, InlineKeyboardMarkup, MenuButtonCommands, Update
6from telegram.ext import Application, CallbackQueryHandler, CommandHandler, ContextTypes, MessageHandler
7from telegram.ext.filters import COMMAND, TEXT
8
9from db import Bookmark, Product, Stage, run_async_session
10from gpt import gpt_call
11
12load_dotenv()
13
14logging.basicConfig(format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", level=logging.INFO)
15logging.getLogger("httpx").setLevel(logging.WARNING)
16
17logger = logging.getLogger(__name__)
18
19
20product_create_button = [[InlineKeyboardButton("Добавить ещё", callback_data="product_create")]]
21
22
23async def command_start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
24commands = [
25("start", "Начало"),
26("products", "Товары"),
27("recipe", "Получить рецепт"),
28("bookmarks", "Закладки с рецептами"),
29]
30
31await Stage.set(user=update.effective_user.id, name="start")
32
33await update.effective_user.get_bot().set_my_commands([BotCommand(c, d) for c, d in commands])
34await update.effective_user.set_menu_button(MenuButtonCommands())
35
36await update.message.reply_html(
37"Данный бот запоминает товары и генерирует рецепт по ним.\n"
38f"Список команд:\n"
39f"{'\n'.join([f'/{c} - {d}' for c, d in commands])}"
40)
41
42
43async def command_products(update: Update, context: ContextTypes.DEFAULT_TYPE):
44await Stage.set(user=update.effective_user.id, name="product_list")
45
46buttons = [
47[InlineKeyboardButton(f"{product.name} [удалить]", callback_data=f"product_delete {product.id}")]
48for product in await Product.read(update.effective_user.id)
49] + product_create_button
50
51await update.effective_user.send_message("Текущие продукты:", reply_markup=InlineKeyboardMarkup(buttons))
52
53
54async def command_recipe(update: Update, context: ContextTypes.DEFAULT_TYPE):
55await Stage.set(user=update.effective_user.id, name="recipe")
56
57products = await Product.read(update.effective_user.id)
58if len(products) == 0:
59await update.effective_user.send_message("У вас нет товаров")
60
61payload = f"Напиши рецепт одного блюда используя только " f"{', '.join([p.name for p in products])}"
62
63await update.effective_user.send_message(
64gpt_call(payload),
65reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton("Сохранить", callback_data="bookmark_create")]]),
66)
67
68
69async def command_bookmarks(update: Update, context: ContextTypes.DEFAULT_TYPE):
70await Stage.set(user=update.effective_user.id, name="bookmark_list")
71
72for bookmark in await Bookmark.read(update.effective_user.id):
73await update.effective_user.send_message(
74bookmark.text,
75reply_markup=InlineKeyboardMarkup(
76[[InlineKeyboardButton("удалить", callback_data=f"bookmarks_delete {bookmark.id}")]]
77),
78)
79else:
80await update.effective_user.send_message("Закладок нет")
81
82
83async def message(update: Update, context: ContextTypes.DEFAULT_TYPE):
84text = update.message.text
85stage = (await Stage.read(update.effective_user.id))[0].name
86
87if stage == "product_create":
88await Product.create(user=update.effective_user.id, name=text)
89await command_products(update, context)
90else:
91await update.effective_user.send_message("Сообщение не распознано")
92
93
94async def button(update: Update, context: ContextTypes.DEFAULT_TYPE):
95await update.callback_query.answer()
96
97arr = update.callback_query.data.split()
98data, pk = arr[0], int(arr[1]) if len(arr) == 2 else None
99
100await Stage.set(user=update.effective_user.id, name=data)
101
102if data == "product_create":
103await update.effective_user.send_message("Введите название продукта")
104
105elif data == "product_delete":
106await Product.delete(pk)
107await update.effective_user.send_message("Продукт удалён")
108await command_products(update, context)
109
110elif data == "bookmark_create":
111await Bookmark.create(user=update.effective_user.id, text=update.callback_query.message.text)
112await update.effective_user.send_message("Рецепт сохранён в закладки")
113
114elif data == "bookmarks_delete":
115await Bookmark.delete(pk)
116await update.effective_user.send_message("Продукт удалён")
117await command_bookmarks(update, context)
118
119
120def run_polling_tg_app():
121application = Application.builder().token(environ["TELEGRAM_TOKEN"]).build()
122
123application.add_handler(CommandHandler("start", command_start))
124application.add_handler(CommandHandler("products", command_products))
125application.add_handler(CommandHandler("recipe", command_recipe))
126application.add_handler(CommandHandler("bookmarks", command_bookmarks))
127
128application.add_handler(MessageHandler(TEXT & ~COMMAND, message))
129
130application.add_handler(CallbackQueryHandler(button))
131
132application.run_polling(allowed_updates=Update.ALL_TYPES)
133
134
135if __name__ == "__main__":
136run_async_session()
137
138run_polling_tg_app()
139