From dc35749468129396ea8ac23b7dcdf52323aa27d1 Mon Sep 17 00:00:00 2001 From: Forden Date: Tue, 4 Aug 2020 22:50:20 +0300 Subject: [PATCH] !feat: changed keyboards generation to create any buttons with any content --- keyboards/__init__.py | 1 + keyboards/default/consts.py | 41 ++++++++++-- keyboards/default/utils/__init__.py | 1 - keyboards/default/utils/misc.py | 17 ----- keyboards/inline/consts.py | 62 +++++++++++++++---- keyboards/inline/utils/__init__.py | 1 - keyboards/keyboard_utils/__init__.py | 0 .../schema_generator.py} | 14 ++--- models/__init__.py | 0 9 files changed, 93 insertions(+), 44 deletions(-) delete mode 100644 keyboards/default/utils/__init__.py delete mode 100644 keyboards/default/utils/misc.py delete mode 100644 keyboards/inline/utils/__init__.py create mode 100644 keyboards/keyboard_utils/__init__.py rename keyboards/{inline/utils/misc.py => keyboard_utils/schema_generator.py} (56%) create mode 100644 models/__init__.py diff --git a/keyboards/__init__.py b/keyboards/__init__.py index e69de29..6f27c5f 100644 --- a/keyboards/__init__.py +++ b/keyboards/__init__.py @@ -0,0 +1 @@ +from . import default, inline diff --git a/keyboards/default/consts.py b/keyboards/default/consts.py index 3203ff2..d4d381c 100644 --- a/keyboards/default/consts.py +++ b/keyboards/default/consts.py @@ -1,15 +1,44 @@ -from typing import List +from typing import Dict, List, Union -from aiogram.types import ReplyKeyboardMarkup, KeyboardButton +from aiogram.types import KeyboardButton, KeyboardButtonPollType, ReplyKeyboardMarkup -from . import utils +from ..keyboard_utils import schema_generator class DefaultConstructor: + aliases = { + 'contact': 'request_contact', + 'location': 'request_location', + 'poll': 'request_poll' + } + available_properities = ['text', 'request_contact', 'request_location', 'request_poll'] + properties_amount = 2 + @staticmethod - def _create_kb(actions: List[str], schema: List[int]) -> ReplyKeyboardMarkup: + def _create_kb( + actions: List[Union[str, Dict[str, Union[str, bool, KeyboardButtonPollType]]]], + schema: List[int] + ) -> ReplyKeyboardMarkup: + kb = ReplyKeyboardMarkup() + kb.row_width = max(schema) btns = [] + # noinspection DuplicatedCode for a in actions: - btns.append(KeyboardButton(a)) - kb = utils.misc.arrange_default_schema(btns, schema) + if isinstance(a, str): + a = {'text': a} + data: Dict[str, Union[str, bool, KeyboardButtonPollType]] = {} + for k, v in DefaultConstructor.aliases.items(): + if k in a: + a[v] = a[k] + del a[k] + for k in a: + if k in DefaultConstructor.available_properities: + if len(data) < DefaultConstructor.properties_amount: + data[k] = a[k] + else: + break + if len(data) != DefaultConstructor.properties_amount: + raise ValueError('Недостаточно данных для создания кнопки') + btns.append(KeyboardButton(**data)) + kb.keyboard = schema_generator.create_keyboard_layout(btns, schema) return kb diff --git a/keyboards/default/utils/__init__.py b/keyboards/default/utils/__init__.py deleted file mode 100644 index ab665e1..0000000 --- a/keyboards/default/utils/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from . import misc diff --git a/keyboards/default/utils/misc.py b/keyboards/default/utils/misc.py deleted file mode 100644 index a02b484..0000000 --- a/keyboards/default/utils/misc.py +++ /dev/null @@ -1,17 +0,0 @@ -from typing import List - -from aiogram.types import ReplyKeyboardMarkup, KeyboardButton - - -def arrange_default_schema(buttons: List[KeyboardButton], count: List[int]) -> ReplyKeyboardMarkup: - kb = ReplyKeyboardMarkup(resize_keyboard=True) - kb.row_width = max(count) - if sum(count) != len(buttons): - raise ValueError('Количество кнопок не совпадает со схемой') - tmplist = [] - for a in count: - tmplist.append([]) - for _ in range(a): - tmplist[-1].append(buttons.pop(0)) - kb.keyboard = tmplist - return kb diff --git a/keyboards/inline/consts.py b/keyboards/inline/consts.py index 6f5e663..dc94422 100644 --- a/keyboards/inline/consts.py +++ b/keyboards/inline/consts.py @@ -1,21 +1,59 @@ -from typing import List, Tuple, Dict +from typing import Dict, List, Tuple, Union -from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton +from aiogram.types import CallbackGame, InlineKeyboardButton, InlineKeyboardMarkup, LoginUrl from aiogram.utils.callback_data import CallbackData -from . import utils +from ..keyboard_utils import schema_generator class InlineConstructor: + aliases = { + 'cb': 'callback_data' + } + available_properities = [ + 'text', 'callback_data', 'login_url', 'switch_inline_query', 'switch_inline_query_current_chat', + 'callback_game', 'pay' + ] + properties_amount = 2 + @staticmethod - def _create_kb(actions: List[Tuple[str, Dict[str, str], CallbackData]], schema: List[int]) -> InlineKeyboardMarkup: + def _create_kb( + actions: List[Dict[ + str, + Union[ + str, + bool, + Tuple[Dict[str, str], CallbackData], + LoginUrl, + CallbackGame, + ] + ]], + schema: List[int] + ) -> InlineKeyboardMarkup: + kb = InlineKeyboardMarkup() + kb.row_width = max(schema) btns = [] - for a, b, c in actions: - btns.append( - InlineKeyboardButton( - text=a, - callback_data=c.new(**b) - ) - ) - kb = utils.misc.arrange_inline_schema(btns, schema) + # noinspection DuplicatedCode + for a in actions: + data: Dict[str, Union[str, bool, Tuple[Dict[str, str], CallbackData], LoginUrl, CallbackGame]] = {} + for k, v in InlineConstructor.aliases.items(): + if k in a: + a[v] = a[k] + del a[k] + for k in a: + if k in InlineConstructor.available_properities: + if len(data) < InlineConstructor.properties_amount: + data[k] = a[k] + else: + break + if 'callback_data' in data: + data['callback_data'] = data['callback_data'][1].new(**data['callback_data'][0]) + if 'pay' in data: + if len(btns) != 0 and data['pay']: + raise ValueError('Платежная кнопка должна идти первой в клавиатуре') + data['pay'] = a['pay'] + if len(data) != InlineConstructor.properties_amount: + raise ValueError('Недостаточно данных для создания кнопки') + btns.append(InlineKeyboardButton(**data)) + kb.inline_keyboard = schema_generator.create_keyboard_layout(btns, schema) return kb diff --git a/keyboards/inline/utils/__init__.py b/keyboards/inline/utils/__init__.py deleted file mode 100644 index ab665e1..0000000 --- a/keyboards/inline/utils/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from . import misc diff --git a/keyboards/keyboard_utils/__init__.py b/keyboards/keyboard_utils/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/keyboards/inline/utils/misc.py b/keyboards/keyboard_utils/schema_generator.py similarity index 56% rename from keyboards/inline/utils/misc.py rename to keyboards/keyboard_utils/schema_generator.py index 7366f2e..ca975a5 100644 --- a/keyboards/inline/utils/misc.py +++ b/keyboards/keyboard_utils/schema_generator.py @@ -1,11 +1,12 @@ -from typing import List +from typing import List, Union -from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup +from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup, KeyboardButton, ReplyKeyboardMarkup -def arrange_inline_schema(buttons: List[InlineKeyboardButton], count: List[int]) -> InlineKeyboardMarkup: - kb = InlineKeyboardMarkup() - kb.row_width = max(count) +def create_keyboard_layout( + buttons: List[Union[InlineKeyboardButton, KeyboardButton]], + count: List[int] +) -> Union[InlineKeyboardMarkup, ReplyKeyboardMarkup]: if sum(count) != len(buttons): raise ValueError('Количество кнопок не совпадает со схемой') tmplist = [] @@ -13,5 +14,4 @@ def arrange_inline_schema(buttons: List[InlineKeyboardButton], count: List[int]) tmplist.append([]) for _ in range(a): tmplist[-1].append(buttons.pop(0)) - kb.inline_keyboard = tmplist - return kb + return tmplist diff --git a/models/__init__.py b/models/__init__.py new file mode 100644 index 0000000..e69de29