1.0 Добавлена /help как проверка клавиатур, и сохздан класс простого создания reply_kb

This commit is contained in:
Verum
2025-02-25 15:02:38 +07:00
parent 47896a0597
commit c3a4d45678
11 changed files with 162 additions and 17 deletions

View File

@@ -3,4 +3,5 @@
# Экспортирование модулей во внешние слои проекта
from .user_cmd_class import *
from .keyboards_sample import *
from .inline_kb_sample import *
from .reply_kb_sample import *

View File

@@ -1,11 +1,7 @@
# BotCode/keyboards/inline_kb/base_inline_kb.py
# Базовый класс для создания инлайн-клавиатур
from aiogram.types import InlineKeyboardMarkup
from aiogram.types import InlineKeyboardMarkup, ReplyKeyboardRemove
from aiogram.utils.keyboard import InlineKeyboardBuilder
from typing import List, Tuple, Optional
class BaseInlineKeyboard:
def __init__(self, buttons: List[Tuple[str, Optional[str], Optional[str]]], row_width: int = 1):
"""
@@ -17,8 +13,8 @@ class BaseInlineKeyboard:
def get_keyboard(self) -> InlineKeyboardMarkup:
"""
Создаёт инлайн-клавиатуру.
:return: объект InlineKeyboardMarkup
Создаёт инлайн-клавиатуру и возвращает её вместе с объектом для удаления reply-клавиатуры.
:return: кортеж (InlineKeyboardMarkup, ReplyKeyboardRemove)
"""
ikb = InlineKeyboardBuilder()
for text, url, callback_data in self.buttons:
@@ -28,4 +24,4 @@ class BaseInlineKeyboard:
ikb.button(text=text, callback_data=callback_data)
ikb.adjust(self.row_width)
return ikb.as_markup()
return ikb.as_markup()

View File

@@ -0,0 +1,103 @@
# BotCode/keyboards/reply_kb/base_reply_kb.py
# Базовый класс для создания reply-клавиатур с расширенными возможностями и поддержкой row_width
from aiogram.types import ReplyKeyboardMarkup, KeyboardButton, KeyboardButtonPollType, WebAppInfo, KeyboardButtonRequestUsers, KeyboardButtonRequestChat, KeyboardButtonRequestUser
from aiogram.utils.keyboard import ReplyKeyboardBuilder
from typing import List, Union, Tuple, Optional, Dict, Any
class BaseReplyKeyboard:
def __init__(
self,
buttons: List[List[Union[str, Tuple[str, str, Optional[Dict[str, Any]]]]]],
resize_keyboard: bool = True,
one_time_keyboard: bool = False,
row_width: int = 1 # Добавляем row_width как параметр
):
"""
:param buttons: список кнопок, каждая из которых может быть:
- строкой (обычная кнопка с текстом)
- кортежем (текст, тип кнопки, дополнительные параметры).
Типы кнопок: "location", "contact", "users", "chat", "poll", "quiz", "web_app", "user".
Дополнительные параметры: словарь с настройками (опционально).
:param resize_keyboard: изменять ли размер клавиатуры под содержимое.
:param one_time_keyboard: скрывать ли клавиатуру после нажатия.
:param row_width: количество кнопок в одной строке (если требуется динамическое распределение).
"""
self.buttons = buttons
self.resize_keyboard = resize_keyboard
self.one_time_keyboard = one_time_keyboard
self.row_width = row_width
def get_keyboard(self) -> ReplyKeyboardMarkup:
"""
Создаёт reply-клавиатуру с поддержкой всех типов кнопок и динамическим распределением по row_width.
:return: объект ReplyKeyboardMarkup
"""
rkb = ReplyKeyboardBuilder()
# Преобразуем вложенные списки в плоский список для динамического распределения
flat_buttons = [button for row in self.buttons for button in row]
# Разбиваем кнопки на строки с учетом row_width
for i in range(0, len(flat_buttons), self.row_width):
row = flat_buttons[i:i + self.row_width]
buttons = []
for button in row:
if isinstance(button, tuple):
text, button_type = button[0], button[1]
params = button[2] if len(button) > 2 else {}
if button_type == "location":
buttons.append(KeyboardButton(text=text, request_location=True))
elif button_type == "contact":
buttons.append(KeyboardButton(text=text, request_contact=True))
elif button_type == "users":
buttons.append(KeyboardButton(
text=text,
request_users=KeyboardButtonRequestUsers(
request_id=params.get("request_id", 1),
user_is_bot=params.get("user_is_bot"),
user_is_premium=params.get("user_is_premium"),
max_quantity=params.get("max_quantity", 1)
)
))
elif button_type == "chat":
buttons.append(KeyboardButton(
text=text,
request_chat=KeyboardButtonRequestChat(
request_id=params.get("request_id", 1),
chat_is_channel=params.get("chat_is_channel", False),
chat_is_forum=params.get("chat_is_forum"),
chat_has_username=params.get("chat_has_username"),
chat_is_created=params.get("chat_is_created")
)
))
elif button_type == "poll":
buttons.append(KeyboardButton(
text=text,
request_poll=KeyboardButtonPollType(type="regular")
))
elif button_type == "quiz":
buttons.append(KeyboardButton(
text=text,
request_poll=KeyboardButtonPollType(type="quiz")
))
elif button_type == "web_app":
buttons.append(KeyboardButton(
text=text,
web_app=WebAppInfo(url=params.get("url", ""))
))
elif button_type == "user":
buttons.append(KeyboardButton(
text=text,
request_user=KeyboardButtonRequestUser(
request_id=params.get("request_id", 1),
user_is_bot=params.get("user_is_bot"),
user_is_premium=params.get("user_is_premium")
)
))
else:
buttons.append(KeyboardButton(text=button))
rkb.row(*buttons)
return rkb.as_markup(resize_keyboard=self.resize_keyboard, one_time_keyboard=self.one_time_keyboard)

View File

@@ -80,6 +80,22 @@ class CommandHandler:
chat_id=message.chat.id,
action=ChatAction.TYPING,
)
elif self.media == "quiz":
# Отправка викторины (quiz)
await message.reply_poll(
question=self.text_msg, # Текст сообщения используется как вопрос викторины
options=["Вариант 1", "Вариант 2"], # Заглушка, варианты нужно задавать отдельно
is_anonymous=True,
type="quiz",
correct_option_id=0, # Первый вариант по умолчанию правильный
reply_markup=self.keyboard() if self.keyboard else None,
disable_notification=self.disable_notification
)
if self.chat_action:
await message.bot.send_chat_action(
chat_id=message.chat.id,
action=ChatAction.TYPING,
)
else:
if self.media == "photo" and len(self.path_to_media) > 1:
# Отправка медиагруппы для фотографий