From 26c78d3550d5f883c87b5d92c22eaacccc5f30d3 Mon Sep 17 00:00:00 2001 From: ollyhearn Date: Thu, 8 Jun 2023 17:57:59 +0300 Subject: [PATCH] a --- bot/app/bot.py | 89 ++++++++++++++++++++++++++++++++++++++++-- bot/app/db/models.py | 3 ++ bot/app/db/settings.py | 15 +++---- bot/app/keyboards.py | 41 +++++++++++++------ bot/app/textbook.py | 6 +++ 5 files changed, 131 insertions(+), 23 deletions(-) diff --git a/bot/app/bot.py b/bot/app/bot.py index 25c9e59..c6f415a 100644 --- a/bot/app/bot.py +++ b/bot/app/bot.py @@ -30,21 +30,95 @@ from db.models import User, Queue, QueueUser bot = AsyncTeleBot(token, state_storage=StatePickleStorage()) + class States(StatesGroup): default = State() +def get_queue_stats_text(queue: Queue) -> str: + s = f"Название: {queue.name}" f"Количество участников: {len(queue.users)}" + return s + + @bot.message_handler(commands=["start"]) async def start(msg: Message): if msg.chat.type == "private": user = session.query(User).filter_by(id=msg.from_user.id).first() if not user: - new_user = User(id=msg.from_user.id, name=msg.from_user.first_name, username=msg.from_user.username) + new_user = User( + id=msg.from_user.id, + name=msg.from_user.first_name, + username=msg.from_user.username, + ) session.add(new_user) session.commit() await bot.send_message(chat_id=msg.chat.id, text=textbook.start) await bot.set_state(user_id=msg.from_user.id, state=States.default) - await bot.send_message(chat_id=msg.chat.id, text=textbook.menu, reply_markup=keyboards.menu()) + await bot.send_message( + chat_id=msg.chat.id, text=textbook.menu, reply_markup=keyboards.menu() + ) + +@bot.callback_query_handler(func=lambda c: c.data == "to_menu") +async def to_menu_handler(call: types.CallbackQuery): + await bot.set_state(user_id=call.from_user.id, state=States.default) + await bot.send_message( + chat_id=call.message.chat.id, text=textbook.menu, reply_markup=keyboards.menu() + ) + +@bot.callback_query_handler(func=lambda c: c.data == "new_queue") +async def new_queue_handler(call: types.CallbackQuery): + user = session.query(User).filter_by(id=call.from_user.id).first() + if user: + if len(user.owns_queues) < 4: + queue = Queue(owner_id=call.from_user.id) + sessio.add(queue) + session.commit() + await bot.answer_callback_query( + callback_query_id=call.id, + text=textbook.new_queue_created.format(id=queue.id), + show_alert=True, + ) + else: + await bot.answer_callback_query( + callback_query_id=call.id, text=textbook.queue_limit, show_alert=True + ) + await bot.answer_callback_query(callback_query_id=call.id) + + +@bot.callback_query_handler(func=lambda c: c.data == "my_queues") +async def my_queues_handler(call: types.CallbackQuery): + user = session.query(User).filter_by(id=call.from_user.id).first() + queues = user.owns_queues + await bot.edit_message_text( + chat_id=call.message.chat.id, + message_id=call.message.id, + text=textbook.my_queues_list.format(count=len(queues)), + reply_markup=keyboards.my_queues(queues), + ) + await bot.answer_callback_query(callback_query_id=call.id) + + +@bot.callback_query_handler(func=lambda c: c.data[:2] == "q:") +async def edit_queue_handler(call: types.CallbackQuery): + queue_id = call.data[:2] + queue = session.query(Queue).filter_by(id=queue_id).first() + if not queue: + await bot.answer_callback_query( + callback_query_id=call.id, text=textbook.error + ) + return None + async with bot.retrieve_data( + user_id=call.from_user.id, chat_id=call.message.chat.id + ) as state_data: + state_data["queue"] = call.data[2:] + await bot.edit_message_text( + chat_id=call.message.chat.id, + message_id=call.message.id, + text=get_queue_stats_text(queue), + reply_markup=keyboards.queue_menu(), + ) + await bot.answer_callback_query(callback_query_id=call.id) + @bot.message_handler(commands=["new_queue"]) async def nq(msg: Message): @@ -52,7 +126,10 @@ async def nq(msg: Message): queue = Queue(owner_id=user.id) session.add(queue) session.commit() - await bot.send_message(chat_id=msg.chat.id, text=f"Создана новая очередь: {queue.id}") + await bot.send_message( + chat_id=msg.chat.id, text=f"Создана новая очередь: {queue.id}" + ) + @bot.message_handler(commands=["take_part"]) async def tp(msg: Message): @@ -66,6 +143,7 @@ async def tp(msg: Message): session.commit() await bot.send_message(chat_id=msg.chat.id, text="Вы приняли участие в очереди!") + @bot.message_handler(commands=["queue"]) async def q(msg: Message): try: @@ -76,10 +154,13 @@ async def q(msg: Message): queue = session.query(Queue).filter_by(id=queue_id).first() if queue: users = [q.user.name for q in queue.users] - await bot.send_message(chat_id=msg.chat.id, text=f"Пользователи этой очереди: {', '.join(users)}") + await bot.send_message( + chat_id=msg.chat.id, text=f"Пользователи этой очереди: {', '.join(users)}" + ) else: await bot.send_message(chat_id=msg.chat.id, text="Очередь не найдена!") + async def main(): a = asyncio.create_task(bot.polling(non_stop=True)) await a diff --git a/bot/app/db/models.py b/bot/app/db/models.py index 8c7cf58..e365a76 100644 --- a/bot/app/db/models.py +++ b/bot/app/db/models.py @@ -7,6 +7,7 @@ import uuid from db.base import Base + class User(Base): __tablename__ = "user" @@ -22,6 +23,7 @@ class Queue(Base): __tablename__ = "queue" id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) + name = Column(String, default="Новая очередь") owner_id = Column(BigInteger, ForeignKey("user.id")) users = relationship("QueueUser", backref="queue") @@ -33,3 +35,4 @@ class QueueUser(Base): id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) user_id = Column(BigInteger, ForeignKey("user.id")) queue_id = Column(UUID(as_uuid=True), ForeignKey("queue.id")) + position = Column(Integer) diff --git a/bot/app/db/settings.py b/bot/app/db/settings.py index 3affb82..b9d4ae2 100644 --- a/bot/app/db/settings.py +++ b/bot/app/db/settings.py @@ -1,15 +1,16 @@ from dataclasses import dataclass import os + @dataclass class Settings: - dialect: str = os.getenv('DIALECT', "postgresql") - driver: str = os.getenv('DRIVER', "psycopg2") - user: str = os.getenv('USER', "user") - password: str = os.getenv('PASSWORD', "password") - db_name: str = os.getenv('DB_NAME', "db") - host: str = os.getenv('HOST', "postgres") - port: int = os.getenv('PORT', 5432) + dialect: str = os.getenv("DIALECT", "postgresql") + driver: str = os.getenv("DRIVER", "psycopg2") + user: str = os.getenv("USER", "user") + password: str = os.getenv("PASSWORD", "password") + db_name: str = os.getenv("DB_NAME", "db") + host: str = os.getenv("HOST", "postgres") + port: int = os.getenv("PORT", 5432) @property def uri(self) -> str: diff --git a/bot/app/keyboards.py b/bot/app/keyboards.py index 79323e8..67d9eb3 100644 --- a/bot/app/keyboards.py +++ b/bot/app/keyboards.py @@ -1,15 +1,32 @@ -from telebot.types import InlineKeyboardButton as button, InlineKeyboardMarkup as keyboard +from telebot.types import ( + InlineKeyboardButton as button, + InlineKeyboardMarkup as keyboard, +) +from db.models import Queue -def menu(): + +def menu() -> keyboard: return keyboard( keyboard=[ - [ - button(text="➕ Новая очередь", callback_data="new") - ], - [ - button(text="📋 Мои очереди", callback_data="my") - ], - [ - button(text="ℹ️ О боте", callback_data="about") - ], - ]) + [button(text="➕ Новая очередь", callback_data="new_queue")], + [button(text="📋 Мои очереди", callback_data="my_queues")], + [button(text="ℹ️ О боте", callback_data="about")], + ] + ) + + +def my_queues(queues: list[Queue]) -> keyboard: + kb = [[button(text=q.name, callback_data=f"q:{q.id}")] for q in queues] + kb.append([button(text="⬅️ В меню", callback_data="to_menu")]) + return keyboard(kb) + + +def queue_menu() -> keyboard: + return keyboard( + keyboard=[ + [button(text="✏️ Изменить название", callback_data="edit_queue_name")], + [button(text="🫂 Список участников", callback_data="participants")], + [button(text="❌ Удалить очередь", callback_data="delete_queue")], + [button(text="⬅️ В меню", callback_data="to_menu")], + ] + ) diff --git a/bot/app/textbook.py b/bot/app/textbook.py index 82e28a0..5858355 100644 --- a/bot/app/textbook.py +++ b/bot/app/textbook.py @@ -1,3 +1,9 @@ start = "Привет! Я помогу тебе вести очередность людей! Это бывает очень полезно для сдачи работ, к примеру, когда люди договариваются в разных чатах, а ближе к сдаче получается путаница. Ты можешь создавать очереди, отправлять ссылки на вступление, менять очередноcть, создавать очереди в групповых чатах и т.д.!" start_group = "Привет, я QUEUEBOT 2.0, помогаю создавать очереди в твоих групповых чатах!\n\nЧтобы пользоваться мной в этом чате, пользователь с правами админа должен настроить меня, комманда /settings, также не забудь выдать мне права администратора, чтобы я мог видеть список участников этой группы!" menu = "Главное меню" +new_queue_created = ( + 'Создана новая очередь: {id}. Редактировать ее можно в меню "➕ Новая очередь"' +) +queue_limit = "Ты достиг лимита очередей (4). Удали свои очереди, или воспользуйся другим аккаунтом!" +my_queues_list = "У тебя {count} очереди/ей" +error = "Произошла непредвиденная ошибка!"