Passed
Push — master ( 45c585...00d29b )
by torrua
02:46
created

WordKeyboard._get_items()   A

Complexity

Conditions 2

Size

Total Lines 4
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 4
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 2
nop 1
1
from callbaker import callback_from_info
2
from keyboa import Keyboa
3
4
from app.bot.telegram import MIN_NUMBER_OF_BUTTONS
5
from app.bot.telegram.variables import (
6
    mark_entity,
7
    entity_predy,
8
    mark_action,
9
    action_predy_kb_cpx_show,
10
    mark_record_id,
11
    mark_slice_start,
12
    t,
13
    cbd,
14
    action_predy_kb_cpx_hide,
15
    action_predy_send_card,
16
)
17
18
class WordKeyboard:
19
    def __init__(self, word):
20
        self.word = word
21
        self.items = self._get_items()
22
23
    def _get_items(self):
24
        if self.word.type.parentable:
25
            return self.word.parents
26
        return self.word.complexes
27
28
    def get_title(self):
29
        if self.word.type.parentable:
30
            return "Parent" + f"{'s' if len(self.word.parents) > 1 else ''}"
31
        return "Complex" + f"{'es' if len(self.word.complexes) > 1 else ''}"
32
33
    def _keyboard_navi(self, index_start: int):
34
        """
35
        :param index_start:
36
        :return:
37
        """
38
39
        total_num = len(self.items)
40
        delimiter = self._get_delimiter(total_num)
41
        if total_num <= delimiter:
42
            return None
43
44
        index_end = self.get_slice_end(index_start, total_num)
45
46
        text_arrow_back = "\U0000276E" * 2
47
        text_arrow_forward = "\U0000276F" * 2
48
        button_back, button_forward = None, None
49
50
        common_data = {
51
            mark_entity: entity_predy,
52
            mark_action: action_predy_kb_cpx_show,
53
            mark_record_id: self.word.id,
54
        }
55
        if index_start != 0:
56
            cbd_predy_kb_cpx_back = {
57
                **common_data,
58
                mark_slice_start: index_start - delimiter,
59
            }
60
            button_back = {
61
                t: text_arrow_back,
62
                cbd: callback_from_info(cbd_predy_kb_cpx_back),
63
            }
64
65
        if index_end != len(self.word.complexes):
66
            cbd_predy_kb_cpx_forward = {
67
                **common_data,
68
                mark_slice_start: index_end,
69
            }
70
            button_forward = {
71
                t: text_arrow_forward,
72
                cbd: callback_from_info(cbd_predy_kb_cpx_forward),
73
            }
74
75
        nav_row = [b for b in [button_back, button_forward] if b]
76
        return Keyboa(nav_row, items_in_row=2)()
77
78
    def _keyboard_hide(self):
79
        """
80
        :return:
81
        """
82
83
        text_hide = f"Hide {self.get_title()}"
84
        cbd_predy_kb_cpx_hide = {
85
            mark_entity: entity_predy,
86
            mark_action: action_predy_kb_cpx_hide,
87
            mark_record_id: self.word.id,
88
        }
89
        button_predy_kb_cpx_hide = [
90
            {t: text_hide, cbd: callback_from_info(cbd_predy_kb_cpx_hide)},
91
        ]
92
        return Keyboa(button_predy_kb_cpx_hide)()
93
94
    def _keyboard_show(self):
95
        """
96
        :return:
97
        """
98
        total_num = len(self.items)
99
        number = f" ({total_num})" if total_num > 1 else ""
100
        text_cpx_show = f"Show {self.get_title()}{number}"
101
        cbd_predy_kb_cpx_show = {
102
            mark_entity: entity_predy,
103
            mark_action: action_predy_kb_cpx_show,
104
            mark_record_id: self.word.id,
105
        }
106
        button_show = [
107
            {t: text_cpx_show, cbd: callback_from_info(cbd_predy_kb_cpx_show)},
108
        ]
109
        return Keyboa.combine((Keyboa(button_show)(), kb_close()))
110
111
    @staticmethod
112
    def _get_delimiter(total_number_of_items: int):
113
        """
114
        :param total_number_of_items:
115
        :return:
116
        """
117
        allowed_range = list(range(MIN_NUMBER_OF_BUTTONS, MIN_NUMBER_OF_BUTTONS + 11))
118
        lst = [(total_number_of_items % i, i) for i in allowed_range]
119
        delimiter = min(lst, key=lambda x: abs(x[0] - MIN_NUMBER_OF_BUTTONS))[1]
120
        for i in lst:
121
            if i[0] == 0:
122
                delimiter = i[1]
123
                break
124
        return delimiter
125
126
    def _keyboard_data(self, slice_start: int):
127
        """
128
        :param slice_start:
129
        :return:
130
        """
131
        slice_end = self.get_slice_end(slice_start, len(self.items))
132
        current_item_set = self.items[slice_start:slice_end]
133
134
        kb_items = [
135
            {
136
                t: item.name,
137
                cbd: callback_from_info(
138
                    {
139
                        mark_entity: entity_predy,
140
                        mark_action: action_predy_send_card,
141
                        mark_record_id: item.id,
142
                    }
143
                ),
144
            }
145
            for item in current_item_set
146
        ]
147
        return Keyboa(items=kb_items, alignment=True, items_in_row=4)()
148
149
    def _keyboard_complete(self, slice_start: int):
150
        kb_data = self._keyboard_data(slice_start)
151
        kb_navi = self._keyboard_navi(slice_start)
152
        kb_hide = self._keyboard_hide()
153
        kb_combo = (kb_hide, kb_data, kb_navi, kb_close())
154
        return Keyboa.combine(kb_combo)
155
156
    def get_slice_end(self, slice_start: int, total_num: int) -> int:
157
        current_delimiter = self._get_delimiter(total_num)
158
        last_allowed_item = slice_start + current_delimiter
159
        slice_end = min(last_allowed_item, total_num)
160
        return slice_end
161
162
    def keyboard_cpx(self, show_list: bool = False, slice_start: int = 0):
163
        """
164
        :param show_list:
165
        :param slice_start:
166
        :return:
167
        """
168
169
        if not self.items:
170
            return kb_close()
171
172
        if not show_list:
173
            return self._keyboard_show()
174
175
        return self._keyboard_complete(slice_start)
176
177
178
def kb_close():
179
    """
180
    :return:
181
    """
182
    return Keyboa({t: "Close", cbd: "close"})()
183