-
Notifications
You must be signed in to change notification settings - Fork 0
/
handlers.py
266 lines (226 loc) · 10.8 KB
/
handlers.py
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
# coding=utf-8
import datetime
import time
import twx.botapi as tel
import draw
import keyboard as kb
import transaction as journal
VERY_BIG_NUMBER = 9_876_543
IMAGE_PATH = './images'
def get_number(text, user):
if text == '0':
return 0
text = text.replace(user.currency, ' ').strip()
result = False
try:
result = float(text)
result = int(text)
finally:
return result
class ACTION(object):
Empty = 0
Spend = 1
Balance = 2
Currency = 3
AskingTutorial = 20
TutorialSpend = 21
TutorialBalance = 22
TutorialCurrency = 23
values = {
Empty: 'Action is empty',
Spend: 'When user spend some money',
Balance: 'When user set new balance',
Currency: 'Users currency',
AskingTutorial: 'Asking tutorial',
}
synonym = {
'/start': ['Cтарт', 'Начать', 'start'],
'/setbalance': ['Изменить баланс', 'setbalance'],
'/total': ['Всего', 'Статистика', 'Месяц', 'total'],
'/history': ['История', 'Выписка', 'history'],
'/balance': ['balance', 'Баланс', 'Остаток'],
'/stats': ['stats', 'Статистика'],
'/cancel': ['Отмена', 'cancel'],
'/tutorial': ['Обучение', 'tutorial'],
'/help': ['help', 'Помощь', 'Хелп'],
}
def is_command(text, command):
return text.startswith(command) or text.lower() in synonym.get(command, [])
def handle_empty(user, text: str):
answer, keyboard = False, False
if text is None:
return "Я могу отвечать только на текст.", False
elif is_command(text, '/start'):
answer = 'Привет! Я снова живу!\n\n' \
'/help для списка команд\n' \
'Я создан что бы помочь тебе следить за твоими средствами.\n' \
f'Хочешь начать с обучения, {user.name}?'
user.action = ACTION.AskingTutorial
return answer, kb.create_keyboard('Да', 'Нет')
elif is_command(text, '/tutorial'):
return handle_tutorial(user, text)
elif is_command(text, '/total'):
records = journal.show(user)
if len(records):
filename = f"{IMAGE_PATH}/{user.id}-total.png"
draw.drawCircle(filename, datetime.datetime.now().strftime("%B"), records)
file_info = tel.InputFileInfo(filename, open(filename, "rb"), "image/png")
return tel.InputFile("photo", file_info), False
else:
return "Слишком мало данных для статистики", False
elif is_command(text, '/balance'):
answer = 'Текущий баланс %d%s\n' % (user.balance, user.currency)
elif is_command(text, '/setbalance'):
user.action = ACTION.Balance
answer = 'Текущий баланс - %d%s.\n/setbalance для отмены.\nВведите новое значение - ' \
% (user.balance, user.currency)
elif is_command(text, '/history'):
answer = journal.get_history(user)
return answer, False
elif is_command(text, '/stats'):
records = journal.show(user)
if len(records):
filename = f"{IMAGE_PATH}/{user.id}-stats.png"
draw.drawLines(filename, datetime.datetime.now().strftime("%B"), records)
file_info = tel.InputFileInfo(filename, open(filename, "rb"), "image/png")
return tel.InputFile("photo", file_info), False
else:
return "Слишком мало данных для статистики", False
elif is_command(text, '/cancel'):
user.action = ACTION.Empty
journal.cancel_last_transaction(user)
return "Последняя транзакция отменена.", False
elif is_command(text, '/help'):
return '''
Введите любое число, чтобы начать транзакцию.
/start - начни обучение здесь
/setbalance - установить баланс
/total - показать суммарный баланс за месяц
/history - показать историю транзакций
/balance - проверить баланс
/stats - показать статистику за месяц
/cancel - отмена операции
/tutorial - начать обучение
/help - подсказка
/f - [debug] установить демо транзакции (стирает ваши транзакции, осторожно!)
''', False
elif is_command(text, '/f'):
journal.fill(user)
answer = "Готово"
elif is_command(text, '/save'):
from storage import save_pool
save_pool(journal.pool)
from users import User
User.save()
return 'Сохранил', False
else:
value = get_number(text, user)
if value < 0 or value > VERY_BIG_NUMBER:
return "Введите положительное разумное число!", False
if value:
answer = 'На что ты потратил %d%s?\nЕсли это заработанные средства - Жми "➕Доход"' % (value, user.currency)
keyboard = kb.create_keyboard_with_tags(journal.get_tags(user))
user.action = ACTION.Spend
user.value = value
return answer, keyboard
def handle_spend(user, text):
if is_command(text, '/cancel'):
user.action = ACTION.Empty
return 'Отмена', False
if text == "➕Доход":
user.value = -user.value
journal.pool.get(user.id, []).append(journal.Transaction(user.id, text, datetime.datetime.now(), user.value))
user.balance -= user.value
user.action = ACTION.Empty
if user.value > 0:
return 'Ты потратил %d%s на %s.\n Текущий баланс: %d%s' \
% (user.value, user.currency, text, user.balance, user.currency), False
else:
return 'Текущий баланс: %d%s' % (user.balance, user.currency), False
def handle_balance(user, text):
if text.startswith('/setbalance'):
user.action = ACTION.Empty
return "Отменено", False
value = get_number(text, user)
if value < 0 or value > VERY_BIG_NUMBER:
return "Введите положительное разумное число!", False
if value:
delta = value - user.balance
user.balance = value
journal.pool.get(user.id, []).append(journal.Transaction(user.id, "➕Доход", datetime.datetime.now(), 0))
user.balance_trans.value += delta
user.action = ACTION.Empty
answer = "Новый баланс - %d%s" % (user.balance, user.currency)
return answer, False
else:
return "Извини, но я не понимаю такое число\nВводи числа в формате, как показано ниже -" \
"\n\n123\n123 00\n123.00\n\nИ так, повторим\nКакой баланс у тебя сейчас?", False
def handle_currency(user, text):
user.currency = text
user.action = ACTION.Empty
return 'Здорово\nТеперь твой баланс %d %s\n\n' \
'А теперь давай потратим на что-нибудь деньги\n' \
'Напиши сумму, которую ты потратил(или заработал)' \
% (user.balance, user.currency), False
def handle_asking_tutorial(user, text):
if text.lower() == 'да':
return handle_tutorial(user, text)
elif text.lower() == 'нет':
user.action = ACTION.Empty
return 'Ну ладно. Посмотри /help для ознакомления с командами', False
return 'Я тебя не понял. Cкажи НЕТ если не хочешь :)', kb.create_keyboard('Да', 'Нет')
def handle_tutorial(user, text):
user.action = ACTION.TutorialBalance
return 'Давай начнём с простого! Какой у тебя текущий баланс?', False
def t_handle_spend(user, text):
user.action = ACTION.Empty
if is_command(text, '/cancel'):
return 'Обучение закончено!', False
if text == "➕Доход":
user.value = -user.value
journal.pool.get(user.id, []).append(journal.Transaction(user.id, text, datetime.datetime.now(), user.value))
user.balance -= user.value
if user.value >= 0:
return f'Ты потратил {user.value} {user.currency} на {text}.\n' \
f' Текущий баланс: {user.balance} {user.currency}', False
else:
return 'Текущий баланс: %d%s' % (user.balance, user.currency), False
def t_handle_balance(user, text):
if is_command(text, '/cancel'):
user.action = ACTION.Empty
return 'Обучение закончено!', False
value = get_number(text, user)
if value < 0 or value > VERY_BIG_NUMBER:
return "Введите положительное разумное число!", False
if value:
delta = value - user.balance
user.balance_trans.value += delta
user.balance = value
user.action = ACTION.Empty
answer = f'Твой баланс {user.balance} {user.currency}\n\n' \
f'А теперь давай потратимся на что-нибудь\n' \
'Напиши сумму, которую ты потратил(или заработал)'
return answer, False
else:
return "Извини, но я не понимаю такое число\nВводи числа в формате, как показано ниже - " \
"\n\n123\n123\n123.00\n\nИ так, повторим\nКакой баланс у тебя сейчас?", False
def t_handle_currency(user, text):
if is_command(text, '/cancel'):
user.action = ACTION.Empty
return 'Обучение закончено!', False
user.currency = text.replace('.', ' ').strip()
user.action = ACTION.Empty
return 'Твой баланс %d%s\n\nА теперь давай потратимся на что-нибудь\n' \
'Напиши сумму, которую ты потратил(или заработал)' % (user.balance, user.currency), False
action_handler = {
ACTION.Empty: handle_empty,
ACTION.Spend: handle_spend,
ACTION.Balance: handle_balance,
# ACTION.Currency: handle_currency,
ACTION.AskingTutorial: handle_asking_tutorial,
ACTION.TutorialSpend: t_handle_spend,
ACTION.TutorialBalance: t_handle_balance,
# ACTION.TutorialCurrency: t_handle_currency,
}
def handle(user, text):
return action_handler[user.action](user, text)