-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnavigation_menu.py
More file actions
134 lines (114 loc) · 4.54 KB
/
navigation_menu.py
File metadata and controls
134 lines (114 loc) · 4.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
from typing import List, Callable, Tuple, Any, Type, Union
from telebot.types import ReplyKeyboardMarkup, KeyboardButton, Message
from abc import ABC, abstractmethod
class Action(ABC):
@abstractmethod
def run(self, message) -> Any:
pass
class Item:
def __init__(self, name: str, prev_item: Type['Item']=None):
self.__name: str = name
self.__prev: Item = prev_item
self.__next: List[Item] = []
self.__actions: List[Action] = []
self.__is_empty = True
def add_next_item(self, name: str):
item = Item(name, self)
self.__next.append(item)
self.__is_empty = False
return item
def add_action(self, action: Action):
self.__actions.append(action)
print("Action:", action, "is added")
def get_name(self):
return self.__name
def get_prev_item(self):
return self.__prev
def get_next_items(self) -> List[Type['Item']]:
return self.__next
def get_actions(self) -> List[Action]:
return self.__actions
def is_empty(self):
return self.__is_empty
def __getstate__(self):
return {
"name" : self.__name,
"prev" : self.__prev,
"next" : self.__next,
"actions" : self.__actions,
"is_empty" : self.__is_empty,
}
def __setstate__(self, state):
self.__name = state["name"]
self.__prev = state["prev"]
self.__next = state["next"]
self.__actions = state["actions"]
self.__is_empty = state["is_empty"]
class Navigator:
def __init__(self, start_item: Item, back_button_name: str=None):
self.__start_item = start_item
self.__current_item = start_item
self.__back_button_name = back_button_name
self.__results_buffer: List[Any] = []
self.__run_actions()
def get_keyboard(self):
keyboard = ReplyKeyboardMarkup(resize_keyboard=True)
next_items = self.__current_item.get_next_items()
for next_item in next_items:
keyboard.add(next_item.get_name())
if self.__back_button_name and self.__current_item.get_name() != self.__start_item.get_name():
keyboard.add(self.__back_button_name)
return keyboard
def get_item_name(self):
return self.__current_item.get_name()
def get_results_buffer(self):
return self.__results_buffer
def __run_actions(self, message: Message=None) -> List[Any]:
print("Start run actions")
actions = self.__current_item.get_actions()
self.__results_buffer = []
if message:
print("Current item:", self.__current_item.get_name())
print("Actions:", actions)
for action in actions:
print("Run action:", action.run)
result = action.run(message=message)
self.__results_buffer.append(result)
print("Finish run actions")
return self.__results_buffer
def goto(self, message: Message) -> Tuple[bool, List[Any]]:
name: str = message['text']
results: List[Any] = []
next_items = self.__current_item.get_next_items()
is_changed = False
if name == self.__back_button_name:
is_changed = self.__go_back(True)
return (is_changed, results)
for next_item in next_items:
if next_item.get_name() == name:
self.__current_item = next_item
results = self.__run_actions(message)
if self.__current_item.is_empty():
is_changed = self.__go_back(False)
return (is_changed, results)
is_changed = True
return (is_changed, results)
return (False, results)
def __go_back(self, is_changed: bool):
if not self.__current_item.get_prev_item():
self.__current_item = self.__start_item
else:
self.__current_item = self.__current_item.get_prev_item()
return is_changed
def __getstate__(self):
return {
"start_item" : self.__start_item,
"current_item" : self.__current_item,
"back_button_name" : self.__back_button_name,
# "results_buffer" : self.__results_buffer,
}
def __setstate__(self, state):
self.__start_item = state["start_item"]
self.__current_item = state["current_item"]
self.__back_button_name = state["back_button_name"]
# self.__results_buffer = state["results_buffer"]