Passed
Push — master ( fd05b8...265ada )
by torrua
02:26
created

keyboa.keyboards.get_generated_keyboard()   A

Complexity

Conditions 2

Size

Total Lines 43
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 23
nop 8
dl 0
loc 43
ccs 8
cts 8
cp 1
crap 2
rs 9.328
c 0
b 0
f 0

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
# -*- coding:utf-8 -*-
2 1
"""
3
This module contains all the necessary functions for
4
creating complex and functional inline keyboards.
5
"""
6
7
8 1
from typing import Union, Optional, Tuple
9 1
from telebot.types import InlineKeyboardMarkup
10
11 1
from keyboa.base import Base
12 1
from keyboa.button import Button
13 1
from keyboa.constants import (
14
    DEFAULT_ITEMS_IN_LINE,
15
    AUTO_ALIGNMENT_RANGE,
16
)
17
18
19 1
class Keyboa(Base):
20
    """Default Keyboa class"""
21
22 1
    def slice(
23
        self,
24
        slice_: slice = slice(None, None, None),
25
    ) -> InlineKeyboardMarkup:
26
        """
27
        :return:
28
        """
29 1
        self._items_sliced = self.items[slice_]
30
31 1
        keyboard = (
32
            self._generated_keyboa
33
            if self.items_in_row or self.alignment
34
            else self._preformatted_keyboa
35
        )
36 1
        self._items_sliced = None
37 1
        return keyboard
38
39 1
    @property
40 1
    def keyboa(self) -> InlineKeyboardMarkup:
41
        """
42
        :return:
43
        """
44 1
        return self.slice()
45
46 1
    @property
47 1
    def _calculated_items_in_row(self) -> Optional[int]:
48
        """
49
        :return:
50
        """
51
52 1
        items_in_row = None
53
54 1
        for divider in self.alignment_range:
55 1
            if not len(self._items_sliced) % divider:
56 1
                items_in_row = divider
57 1
                break
58
59 1
        return items_in_row
60
61 1
    @property
62 1
    def _verified_items_in_row(self) -> int:
63
        """
64
        :return:
65
        """
66 1
        items_in_row = None
67 1
        if self.alignment:
68 1
            items_in_row = self._calculated_items_in_row
69
70 1
        if not items_in_row:
71 1
            items_in_row = DEFAULT_ITEMS_IN_LINE
72 1
        return items_in_row
73
74 1
    @property
75
    def alignment_range(self):
76
        """
77
        :return:
78
        """
79
80 1
        alignment_range = (
81
            AUTO_ALIGNMENT_RANGE if isinstance(self.alignment, bool) else self.alignment
82
        )
83 1
        return (
84
            reversed(alignment_range)
85
            if self.alignment_reverse_range
86
            else alignment_range
87
        )
88
89 1
    @property
90 1
    def _preformatted_keyboa(self) -> InlineKeyboardMarkup:
91
        """
92
        :return:
93
        """
94 1
        self.verify_preformatted_items()
95 1
        keyboard = InlineKeyboardMarkup()
96 1
        for row in self._items_sliced:
97 1
            buttons = self.convert_items_to_buttons(row)
98 1
            keyboard.row(*buttons)
99 1
        return keyboard
100
101 1
    def verify_preformatted_items(self) -> None:
102
        """
103
        Check that every row in kb is a list
104
        :return:
105
        """
106 1
        for index, item in enumerate(self._items_sliced):
107 1
            if not isinstance(item, list):
108 1
                self._items_sliced[index] = [
109
                    item,
110
                ]
111
112 1
    def convert_items_to_buttons(self, items) -> list:
113
        """
114
        :param items:
115
        :return:
116
        """
117 1
        return [
118
            Button(
119
                button_data=item,
120
                front_marker=self.front_marker,
121
                back_marker=self.back_marker,
122
                copy_text_to_callback=self.copy_text_to_callback,
123
            ).generate()
124
            for item in items
125
        ]
126
127 1
    @property
128 1
    def _generated_keyboa(self) -> InlineKeyboardMarkup:
129
        """
130
        :return:
131
        """
132 1
        keyboard = InlineKeyboardMarkup()
133 1
        items_in_row = self._verified_items_in_row
134 1
        rows_in_keyboard = len(self._items_sliced) // items_in_row
135 1
        buttons = self.convert_items_to_buttons(self._items_sliced)
136
137 1
        for _row in range(rows_in_keyboard):
138 1
            keyboard.row(*[buttons.pop(0) for _button in range(items_in_row)])
139 1
        keyboard.row(*buttons)
140
141 1
        return keyboard
142
143 1
    @staticmethod
144
    def merge_keyboards_data(keyboards):
145
        """
146
        :param keyboards:
147
        :return:
148
        """
149 1
        data = []
150 1
        for keyboard in keyboards:
151 1
            if keyboard is None:
152 1
                continue
153
154 1
            if not isinstance(keyboard, InlineKeyboardMarkup):
155 1
                type_error_message = (
156
                    "Keyboard cannot be %s. Only InlineKeyboardMarkup allowed."
157
                    % type(keyboard)
158
                )
159 1
                raise TypeError(type_error_message)
160 1
            data.extend(keyboard.keyboard)
161 1
        return data
162
163 1
    @classmethod
164 1
    def combine(
165
        cls,
166
        keyboards: Optional[
167
            Union[Tuple[InlineKeyboardMarkup, ...], InlineKeyboardMarkup]
168
        ] = None,
169
    ) -> InlineKeyboardMarkup:
170
        """
171
        This function combines multiple InlineKeyboardMarkup objects into one.
172
173
        :param keyboards: Sequence of InlineKeyboardMarkup objects.
174
            Also could be presented as a standalone InlineKeyboardMarkup.
175
176
        :return: InlineKeyboardMarkup
177
        """
178
179 1
        if keyboards is None:
180 1
            return InlineKeyboardMarkup()
181
182 1
        if isinstance(keyboards, InlineKeyboardMarkup):
183 1
            keyboards = (keyboards,)
184
185 1
        for keyboard in keyboards:
186 1
            cls.is_keyboard_proper_type(keyboard)
187
188 1
        data = cls.merge_keyboards_data(keyboards)
189
190
        return cls(items=data).keyboa
191