Passed
Pull Request — master (#117)
by
unknown
05:28
created

main.load_attachs()   B

Complexity

Conditions 7

Size

Total Lines 23
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 23
dl 0
loc 23
rs 7.9279
c 0
b 0
f 0
cc 7
nop 0
1
import datetime
2
import json
3
import os
4
import re
5
from enum import Enum
6
from typing import Tuple
7
8
import requests
9
from psycopg2 import ProgrammingError
10
from vk_api.bot_longpoll import VkBotEventType
11
12
from bot import Bot
13
from database import Database
14
from keyboard import Keyboards
15
from scheduler import Date
16
from scheduler import Schedule
17
18
db = Database(os.environ["DATABASE_URL"])
19
bot = Bot()
20
kbs = Keyboards()
21
22
bot.auth()
23
bot.update_version()
24
25
26
class EventTypes(Enum):
27
    NEW_MESSAGE = VkBotEventType.MESSAGE_NEW
28
29
30
def send_schedule(date: str):
31
    group = db.get_group_of_user(event["message"]["from_id"])
32
    gid = db.get_schedule_descriptor(group)
33
    s = Schedule(date, gid)
34
    s.get_raw()
35
    if s.is_exist():
36
        sch = s.generate()
37
        bot.send_message(msg=sch, pid=event["message"]["from_id"])
38
    else:
39
        bot.send_message(msg="Расписание отсутствует.", pid=event["message"]["from_id"])
40
41
42
def generate_call_message():
43
    f = db.get_names_using_status(event["message"]["from_id"])
44
    students_ids = db.get_call_ids(event["message"]["from_id"])
45
    if students_ids is not None:
46
        mentions = bot.generate_mentions(ids=students_ids, names=f)
47
    else:
48
        mentions = ""
49
    message = db.get_call_message(event["message"]["from_id"]) or ""
50
    message = f"{mentions}\n{message}"
51
    return message
52
53
54
def generate_debtors_message():
55
    f = db.get_names_using_status(event["message"]["from_id"])
56
    students_ids = db.get_call_ids(event["message"]["from_id"])
57
    slg = db.get_active_expenses_category(event["message"]["from_id"])
58
    nm = db.get_expense_category_by_slug(slg)
59
    sm = db.get_expense_summ(slg)
60
    if students_ids is not None:
61
        mentions = bot.generate_mentions(ids=students_ids, names=f)
62
    else:
63
        mentions = ""
64
    message = f"{mentions}, вам нужно принести по {sm} руб. на {nm}."
65
    return message
66
67
68
def send_call_confirm():
69
    chat_id = db.get_conversation(event["message"]["from_id"])
70
    if db.get_session_state(event["message"]["from_id"]) == "debtors_forming":
71
        message = generate_debtors_message()
72
    else:
73
        message = generate_call_message()
74
    atch = db.get_call_attaches(event["message"]["from_id"])
75
    if atch is None:
76
        atch = ""
77
    if message != "\n" or atch:
78
        bot.send_message(
79
            msg=f"В {'основную ' if chat_id else 'тестовую '}"
80
            f"беседу будет отправлено сообщение:",
81
            pid=event["message"]["from_id"],
82
            keyboard=kbs.prompt(event["message"]["from_id"]),
83
        )
84
        bot.send_message(msg=message, pid=event["message"]["from_id"], attachment=atch)
85
    else:
86
        db.empty_call_storage(event["message"]["from_id"])
87
        bot.send_gui(
88
            pid=event["message"]["from_id"],
89
            text="Сообщение не может быть пустым. Отмена...",
90
        )
91
92
93
def load_attachs():
94
    attachments = []
95
    for i, v in enumerate(event["message"]["attachments"]):
96
        m = -1
97
        m_url = ""
98
        for ind, val in enumerate(event["message"]["attachments"][i]["photo"]["sizes"]):
99
            if val["height"] > m:
100
                m_url = val["url"]
101
        req = requests.get(m_url)
102
        server = bot.bot_vk.photos.getMessagesUploadServer()
103
        with open(f"photo.jpg", "wb") as f:
104
            f.write(req.content)
105
        file = open(f"photo.jpg", "rb")
106
        upload = requests.post(server["upload_url"], files={"photo": file},).json()
107
        save = bot.bot_vk.photos.saveMessagesPhoto(**upload)
108
        photo = f"photo{save[0]['owner_id']}_{save[0]['id']}"
109
        attachments.append(photo)
110
    atch = ",".join(attachments)
111
    state = db.get_session_state(event["message"]["from_id"])
112
    if state == "ask_for_mailing_message":
113
        db.update_mailing_attaches(event["message"]["from_id"], atch)
114
    elif state == "ask_for_call_message":
115
        db.update_call_attaches(event["message"]["from_id"], atch)
116
117
118
def invite_bot():
119
    """Срабатывает, если текущее событие - приглашение бота в беседу
120
    """
121
    try:
122
        if event["message"]["action"][
123
            "type"
124
        ] == "chat_invite_user" and event.object.message["action"]["member_id"] == -int(
125
            bot.gid
126
        ):
127
            if (
128
                event.objects.message["peer_id"] not in db.get_cached_chats()
129
                and event.objects.message["peer_id"] not in db.get_registered_chats()
130
            ):
131
                db.add_cached_chat(event.objects.message["peer_id"])
132
            bot.send_message(
133
                msg="Привет! Для полноценной работы меня нужно сделать администратором",
134
                pid=event.object.message["peer_id"],
135
            )
136
    except (KeyError, TypeError):
137
        pass
138
139
140
for event in bot.longpoll.listen():
141
    event = {
142
        "type": event.type,
143
        "client_info": event.object.client_info,
144
        "message": event.object.message,
145
    }
146
147
    invite_bot()
148
149
    if (
150
        event["type"] == EventTypes.NEW_MESSAGE.value
151
        and (event["message"]["text"] or event["message"]["attachments"])
152
        and event["message"]["out"] == 0
153
        and event["message"]["from_id"] == event["message"]["peer_id"]
154
    ):
155
        try:
156
            payload = json.loads(event["message"]["payload"])
157
        except KeyError:
158
            payload = {"button": ""}
159
        text = event["message"]["text"].lower()
160
161
        # :blockstart: Запуск интерфейса
162
        if text in ["начать", "старт", "r"]:
163
            if not db.is_user_exist(event["message"]["from_id"]):
164
                db.create_user(event["message"]["from_id"])
165
            if not db.is_session_exist(event["message"]["from_id"]):
166
                db.create_session(event["message"]["from_id"])
167
            bot.send_gui(pid=event["message"]["from_id"])
168
        # :blockend: Запуск интерфейса
169
170
        # :blockstart: Возврат на главный экран
171
        elif payload["button"] == "home":
172
            bot.send_gui(text="Главный экран", pid=event["message"]["from_id"])
173
        # :blockend: Возврат на главный экран
174
175
        # :blockstart: Призыв
176
        elif payload["button"] == "call":
177
            db.update_session_state(event["message"]["from_id"], "ask_for_call_message")
178
            if not db.call_session_exist(event["message"]["from_id"]):
179
                db.create_call_session(event["message"]["from_id"])
180
            bot.send_message(
181
                msg="Отправьте сообщение к призыву (есть поддержка изображений)",
182
                pid=event["message"]["from_id"],
183
                keyboard=kbs.skip(),
184
            )
185
        elif payload["button"] == "letter":
186
            group = db.get_group_of_user(event["message"]["from_id"])
187
            bot.send_message(
188
                msg=f"Отправка клавиатуры с фамилиями на букву \"{payload['letter']}\"",
189
                pid=event["message"]["from_id"],
190
                keyboard=kbs.generate_names_keyboard(payload["letter"], group),
191
            )
192
        elif (
193
            payload["button"] == "student"
194
            and db.get_session_state(event["message"]["from_id"]) != "select_donater"
195
        ):
196
            ids = db.get_call_ids(event["message"]["from_id"])
197
            if ids:
198
                students = ids.split(",")
199
            else:
200
                students = [ids]
201
            if str(db.get_vk_id(payload["id"])) in students:
202
                bot.send_message(
203
                    msg=f"{payload['name']} уже был выбран для призыва. Пропуск.",
204
                    pid=event["message"]["from_id"],
205
                )
206
            else:
207
                db.append_to_call_ids(
208
                    event["message"]["from_id"], db.get_vk_id(payload["id"])
209
                )
210
                bot.send_message(
211
                    msg=f"{payload['name']} добавлен к списку призыва.",
212
                    pid=event["message"]["from_id"],
213
                )
214
        elif (
215
            payload["button"] == "back"
216
            and db.get_session_state(event["message"]["from_id"]) != "select_donater"
217
        ):
218
            group = db.get_group_of_user(event["message"]["from_id"])
219
            bot.send_message(
220
                msg="Отправка клавиатуры с алфавитом.",
221
                pid=event["message"]["from_id"],
222
                keyboard=kbs.generate_call_prompt(group),
223
            )
224
        elif payload["button"] == "skip":
225
            db.update_session_state(event["message"]["from_id"], "call_configuring")
226
            group = db.get_group_of_user(event["message"]["from_id"])
227
            bot.send_message(
228
                msg="Отправка клавиатуры с алфавитом.",
229
                pid=event["message"]["from_id"],
230
                keyboard=kbs.generate_call_prompt(group),
231
            )
232
        elif (
233
            db.get_session_state(event["message"]["from_id"]) == "ask_for_call_message"
234
        ):
235
            db.update_call_message(
236
                event["message"]["from_id"], event["message"]["text"]
237
            )
238
            if event["message"]["attachments"]:
239
                load_attachs()
240
            group = db.get_group_of_user(event["message"]["from_id"])
241
            bot.send_message(
242
                msg="Отправка клавиатуры призыва",
243
                pid=event["message"]["from_id"],
244
                keyboard=kbs.generate_call_prompt(group),
245
            )
246
            db.update_session_state(event["message"]["from_id"], "call_configuring")
247
        elif payload["button"] == "send_to_all":
248
            group = db.get_group_of_user(event["message"]["from_id"])
249
            ids = ",".join(db.get_active_students_ids(group))
250
            db.update_call_ids(event["message"]["from_id"], ids)
251
            bot.send_message(
252
                msg="Все студенты отмечены как получатели уведомления",
253
                pid=event["message"]["from_id"],
254
            )
255
            send_call_confirm()
256
        elif payload["button"] == "save":
257
            send_call_confirm()
258
        elif (
259
            payload["button"] == "cancel"
260
            and db.get_session_state(event["message"]["from_id"]) == "call_configuring"
261
        ):
262
            db.empty_call_storage(event["message"]["from_id"])
263
            db.update_session_state(event["message"]["from_id"], "main")
264
            bot.send_gui(
265
                text="Выполнение команды отменено.", pid=event["message"]["from_id"]
266
            )
267
        elif payload["button"] == "confirm" and db.get_session_state(
268
            event["message"]["from_id"]
269
        ) in ["call_configuring", "debtors_forming"]:
270
            bot.log.info("Отправка призыва...")
271
            chat_type = db.get_conversation(event["message"]["from_id"])
272
            group = db.get_group_of_user(event["message"]["from_id"])
273
            cid = db.get_chat_id(group, chat_type)
274
            if db.get_session_state(event["message"]["from_id"]) == "debtors_forming":
275
                text = generate_debtors_message()
276
            else:
277
                text = generate_call_message()
278
            attachment = db.get_call_attaches(event["message"]["from_id"])
279
            if attachment is None:
280
                attachment = ""
281
            bot.send_message(pid=cid, msg=text, attachment=attachment)
282
            db.empty_call_storage(event["message"]["from_id"])
283
            db.update_session_state(event["message"]["from_id"], "main")
284
            bot.send_gui(text="Сообщение отправлено.", pid=event["message"]["from_id"])
285
        elif payload["button"] == "deny" and db.get_session_state(
286
            event["message"]["from_id"]
287
        ) in ["call_configuring", "debtors_forming"]:
288
            db.update_call_message(event["message"]["from_id"], " ")
289
            db.update_call_ids(event["message"]["from_id"], " ")
290
            db.update_session_state(event["message"]["from_id"], "main")
291
            bot.send_gui(
292
                text="Выполнение команды отменено.", pid=event["message"]["from_id"]
293
            )
294
        elif payload["button"] == "chconv_call":
295
            conv = db.get_conversation(event["message"]["from_id"])
296
            if conv == 0:
297
                db.update_conversation(event["message"]["from_id"], 1)
298
                chat = 2
299
            elif conv == 1:
300
                db.update_conversation(event["message"]["from_id"], 0)
301
                chat = 1
302
            send_call_confirm()
303
304
        elif payload["button"] == "chnames_call":
305
            if db.get_names_using_status(event["message"]["from_id"]):
306
                status = 0
307
            else:
308
                status = 1
309
            db.update_names_using_status(event["message"]["from_id"], status)
310
            send_call_confirm()
311
        # :blockend: Призыв
312
313
        # :blockstart: Расписание
314
        elif payload["button"] == "schedule":
315
            bot.send_message(
316
                msg="Отправка клавиатуры с расписанием.",
317
                pid=event["message"]["from_id"],
318
                keyboard=kbs.generate_schedule_keyboard(),
319
            )
320
        elif payload["button"] == "today":
321
            d = Date()
322
            send_schedule(d.today)
323
        elif payload["button"] == "tomorrow":
324
            d = Date()
325
            send_schedule(d.tomorrow)
326
        elif payload["button"] == "day_after_tomorrow":
327
            d = Date()
328
            send_schedule(d.day_after_tomorrow)
329
        elif payload["button"] == "arbitrary":
330
            bot.send_message(
331
                msg="Напишите дату в формате ДД-ММ-ГГГГ.",
332
                pid=event["message"]["from_id"],
333
                keyboard=kbs.cancel(),
334
            )
335
            db.update_session_state(
336
                event["message"]["from_id"], "ask_for_schedule_date"
337
            )
338
        elif (
339
            payload["button"] == "cancel"
340
            and db.get_session_state(event["message"]["from_id"])
341
            == "ask_for_schedule_date"
342
        ):
343
            db.update_session_state(event["message"]["from_id"], "main")
344
            bot.send_message(
345
                msg="Выполнение команды отменено.",
346
                pid=event["message"]["from_id"],
347
                keyboard=kbs.generate_schedule_keyboard(),
348
            )
349
        elif (
350
            db.get_session_state(event["message"]["from_id"]) == "ask_for_schedule_date"
351
        ):
352
            if re.match(r"^\d\d(.|-|/)\d\d(.|-|/)20\d\d$", event["message"]["text"]):
353
                try:
354
                    d = datetime.datetime.strptime(
355
                        event["message"]["text"], "%d-%m-%Y"
356
                    ).strftime("%Y-%m-%d")
357
                except ValueError:
358
                    bot.send_message(
359
                        msg="Неверный формат даты. Попробуйте еще раз.",
360
                        pid=event["message"]["from_id"],
361
                    )
362
                else:
363
                    group = db.get_group_of_user(event["message"]["from_id"])
364
                    s = Schedule(d, group)
365
                    s.get_raw()
366
                    if s.is_exist():
367
                        schedule = s.generate()
368
                        bot.send_message(
369
                            msg=schedule,
370
                            pid=event["message"]["from_id"],
371
                            keyboard=kbs.generate_schedule_keyboard(),
372
                        )
373
                        db.update_session_state(event["message"]["from_id"], "main")
374
                    else:
375
                        bot.send_message(
376
                            msg="Расписание отсутствует.\nПопробуй указать другую "
377
                            "дату.",
378
                            pid=event["message"]["from_id"],
379
                        )
380
                        db.update_session_state(
381
                            event["message"]["from_id"], "ask_for_schedule_date"
382
                        )
383
            else:
384
                bot.send_message(
385
                    msg="Неверный формат даты. Попробуйте еще раз.",
386
                    pid=event["message"]["from_id"],
387
                )
388
        # :blockend: Расписание
389
390
        # :blockstart: Рассылки
391
        elif payload["button"] == "mailings":
392
            group = db.get_group_of_user(event["message"]["from_id"])
393
            bot.send_message(
394
                msg="Отправка клавиатуры со списком рассылок.",
395
                pid=event["message"]["from_id"],
396
                keyboard=kbs.generate_mailings_keyboard(group),
397
            )
398
        elif payload["button"] == "mailing":
399
            if not db.mailing_session_exist(event["message"]["from_id"]):
400
                db.create_mailing_session(event["message"]["from_id"])
401
            db.update_mailing_session(event["message"]["from_id"], payload["id"])
402
            bot.send_message(
403
                msg=f"Меню управления рассылкой \"{payload['name']}\":",
404
                pid=event["message"]["from_id"],
405
                keyboard=kbs.generate_mailing_mgmt(
406
                    is_admin=bot.is_admin(event["message"]["from_id"]),
407
                    m_id=payload["id"],
408
                    user_id=event["message"]["from_id"],
409
                ),
410
            )
411
        elif payload["button"] == "subscribe":
412
            u_id = db.get_user_id(payload["user_id"])
413
            db.update_subscribe_state(payload["slug"], u_id, 1)
414
            bot.send_message(
415
                msg="Вы были успешно подписаны на рассылку.",
416
                pid=event["message"]["from_id"],
417
                keyboard=kbs.generate_mailing_mgmt(
418
                    is_admin=bot.is_admin(event["message"]["from_id"]),
419
                    m_id=payload["id"],
420
                    user_id=event["message"]["from_id"],
421
                ),
422
            )
423
        elif payload["button"] == "unsubscribe":
424
            u_id = db.get_user_id(payload["user_id"])
425
            db.update_subscribe_state(payload["slug"], u_id, 0)
426
            bot.send_message(
427
                msg="Вы были успешно отписаны от рассылки.",
428
                pid=event["message"]["from_id"],
429
                keyboard=kbs.generate_mailing_mgmt(
430
                    is_admin=bot.is_admin(event["message"]["from_id"]),
431
                    m_id=payload["id"],
432
                    user_id=event["message"]["from_id"],
433
                ),
434
            )
435
        elif payload["button"] == "inline_unsubscribe":
436
            u_id = db.get_user_id(payload["user_id"])
437
            db.update_subscribe_state(payload["slug"], u_id, 0)
438
            bot.send_message(
439
                msg="Вы были успешно отписаны от рассылки.",
440
                pid=event["message"]["from_id"],
441
            )
442
        elif payload["button"] == "send_mailing":
443
            db.update_session_state(
444
                event["message"]["from_id"], "ask_for_mailing_message"
445
            )
446
            bot.send_message(
447
                msg="Отправьте текст рассылки (есть поддержка изображений)",
448
                pid=event["message"]["from_id"],
449
                keyboard=kbs.cancel(),
450
            )
451
        elif (
452
            payload["button"] == "cancel"
453
            and db.get_session_state(event["message"]["from_id"])
454
            == "ask_for_mailing_message"
455
        ):
456
            bot.send_message(
457
                msg="Выполнение команды отменено. Возвращаюсь на экран управления "
458
                "рассылкой.",
459
                pid=event["message"]["from_id"],
460
                keyboard=kbs.generate_mailing_mgmt(
461
                    is_admin=bot.is_admin(event["message"]["from_id"]),
462
                    m_id=db.get_mailing_session(event["message"]["from_id"]),
463
                    user_id=event["message"]["from_id"],
464
                ),
465
            )
466
            db.update_session_state(event["message"]["from_id"], "main")
467
        elif (
468
            db.get_session_state(event["message"]["from_id"])
469
            == "ask_for_mailing_message"
470
        ):
471
            db.update_mailing_message(
472
                event["message"]["from_id"], event["message"]["text"]
473
            )
474
            if event["message"]["attachments"]:
475
                load_attachs()
476
            bot.send_message(
477
                msg="Всем подписчикам рассылки будет отправлено сообщение с указанным вами текстом",
478
                pid=event["message"]["from_id"],
479
                keyboard=kbs.prompt(),
480
                forward=f"{event['message']['id']}",
481
            )
482
            db.update_session_state(event["message"]["from_id"], "prompt_mailing")
483
        elif (
484
            payload["button"] == "confirm"
485
            and db.get_session_state(event["message"]["from_id"]) == "prompt_mailing"
486
        ):
487
            group = db.get_group_of_user(event["message"]["from_id"])
488
            attach = db.get_mailing_attaches(event["message"]["from_id"])
489
            if attach is None:
490
                attach = ""
491
            bot.send_mailing(
492
                m_id=db.get_mailing_session(event["message"]["from_id"]),
493
                text=db.get_mailing_message(event["message"]["from_id"]),
494
                attach=attach,
495
                group=group,
496
            )
497
            db.update_mailing_message(event["message"]["from_id"], "")
498
            db.update_mailing_attaches(event["message"]["from_id"], "")
499
            bot.send_message(
500
                msg="Рассылка отправлена.",
501
                pid=event["message"]["from_id"],
502
                keyboard=kbs.generate_mailings_keyboard(group),
503
            )
504
        elif (
505
            payload["button"] == "deny"
506
            and db.get_session_state(event["message"]["from_id"]) == "prompt_mailing"
507
        ):
508
            group = db.get_group_of_user(event["message"]["from_id"])
509
            db.empty_mailing_storage(event["message"]["from_id"])
510
            bot.send_message(
511
                msg="Отправка рассылки отменена.",
512
                pid=event["message"]["from_id"],
513
                keyboard=kbs.generate_mailings_keyboard(group),
514
            )
515
        # :blockend: Рассылки
516
517
        # :blockstart: Параметры
518
        elif payload["button"] == "prefs":
519
            bot.send_message(
520
                msg="Параметры",
521
                pid=event["message"]["from_id"],
522
                keyboard=kbs.generate_prefs_keyboard(),
523
            )
524
        elif payload["button"] == "names":
525
            status = db.get_names_using_status(event["message"]["from_id"])
526
            msg = (
527
                f"Использование имён в призыве "
528
                f"{'активно' if status else 'неактивно'}."
529
            )
530
            bot.send_message(
531
                msg=msg,
532
                pid=event["message"]["from_id"],
533
                keyboard=kbs.generate_names_selector(status),
534
            )
535
536
        elif payload["button"] == "off_using_names":
537
            status = 0
538
            db.update_names_using_status(event["message"]["from_id"], status)
539
            bot.send_message(
540
                msg="Использование имён в призыве отключено.",
541
                pid=event["message"]["from_id"],
542
                keyboard=kbs.generate_names_selector(bool(status)),
543
            )
544
        elif payload["button"] == "on_using_names":
545
            status = 1
546
            db.update_names_using_status(event["message"]["from_id"], status)
547
            bot.send_message(
548
                msg="Использование имён в призыве включено.",
549
                pid=event["message"]["from_id"],
550
                keyboard=kbs.generate_names_selector(bool(status)),
551
            )
552
553
        elif payload["button"] == "chats":
554
            bot.send_message(
555
                msg="Настройки чатов",
556
                pid=event["message"]["from_id"],
557
                keyboard=kbs.generate_chat_prefs(),
558
            )
559
560
        elif payload["button"] == "local_chat":
561
            chat = db.get_conversation(event["message"]["from_id"])
562
            bot.send_message(
563
                msg="Локальная настройка чатов",
564
                pid=event["message"]["from_id"],
565
                keyboard=kbs.generate_local_chat_prefs(chat),
566
            )
567
568
        elif payload["button"] == "activate_test_chat":
569
            chat = db.update_conversation(event["message"]["from_id"], 0)
570
            bot.send_message(
571
                msg="Тестовая беседа активирована",
572
                pid=event["message"]["from_id"],
573
                keyboard=kbs.generate_local_chat_prefs(chat),
574
            )
575
576
        elif payload["button"] == "activate_main_chat":
577
            chat = db.update_conversation(event["message"]["from_id"], 1)
578
            bot.send_message(
579
                msg="Основная беседа активирована",
580
                pid=event["message"]["from_id"],
581
                keyboard=kbs.generate_local_chat_prefs(chat),
582
            )
583
584
        elif payload["button"] == "global_chat":
585
            group = db.get_group_of_user(event["message"]["from_id"])
586
587
            bot.send_message(
588
                msg="Глобальная настройка чатов",
589
                pid=event["message"]["from_id"],
590
                keyboard=kbs.generate_global_chat_prefs(group),
591
            )
592
593
        elif payload["button"] == "configure_chat":
594
            chat = bot.bot_vk.messages.getConversationsById(
595
                peer_ids=payload["chat_id"], group_id=bot.gid
596
            )
597
            status = ""
598
            if not chat["items"]:
599
                status = (
600
                    "Бот не администратор в этом чате. Это может мешать "
601
                    "корректной работе"
602
                )
603
            if payload["chat_type"]:
604
                chat_type = "основного"
605
            else:
606
                chat_type = "тестового"
607
            bot.send_message(
608
                msg=f"Настройки {chat_type} чата\n{status}",
609
                pid=event["message"]["from_id"],
610
                keyboard=kbs.configure_chat(
611
                    payload["group"], payload["chat_type"], payload["chat_id"]
612
                ),
613
            )
614
615
        elif payload["button"] == "reg_chat":
616
            chats: Tuple[int] = db.get_cached_chats()
617
            chats_info: str = bot.bot_vk.messages.getConversationsById(
618
                peer_ids=",".join(map(str, chats)), group_id=bot.gid
619
            )
620
            bot.send_message(
621
                msg="Выберите чат для регистрации\n(Если вы видите кнопки в названии "
622
                "которых вопросительные знаки, значит в этом чате бот не является администратором,"
623
                "что недопустимо для нормальной работы бота. Проверьте права доступа и вернитесь)",
624
                pid=event["message"]["from_id"],
625
                keyboard=kbs.reg_chat(chats, chats_info),
626
            )
627
628
        elif payload["button"] == "add_chat":
629
            group = db.get_group_of_user(event["message"]["from_id"])
630
            bot.send_message(
631
                msg="Выберите тип регистрируемого чата",
632
                pid=event["message"]["from_id"],
633
                keyboard=kbs.generate_available_chat_types(payload["chat_id"], group),
634
            )
635
636
        elif payload["button"] == "reg_as_main":
637
            group = db.get_group_of_user(event["message"]["from_id"])
638
            db.remove_cached_chat(payload["chat_id"])
639
            db.registrate_chat(payload["chat_id"], 1, group)
640
            bot.send_message(
641
                msg="Чат зарегистрирован как основной",
642
                pid=event["message"]["from_id"],
643
                keyboard=kbs.generate_global_chat_prefs(group),
644
            )
645
646
        elif payload["button"] == "reg_as_test":
647
            group = db.get_group_of_user(event["message"]["from_id"])
648
            db.remove_cached_chat(payload["chat_id"])
649
            db.registrate_chat(payload["chat_id"], 0, group)
650
            bot.send_message(
651
                msg="Чат зарегистрирован как тестовый",
652
                pid=event["message"]["from_id"],
653
                keyboard=kbs.generate_global_chat_prefs(group),
654
            )
655
656
        elif payload["button"] == "activate_chat":
657
            if payload["chat_type"]:
658
                db.update_chat_activity(payload["group"], 1, 1)
659
                db.update_chat_activity(payload["group"], 0, 0)
660
                chat_type = "Основной"
661
            else:
662
                db.update_chat_activity(payload["group"], 1, 0)
663
                db.update_chat_activity(payload["group"], 0, 1)
664
                chat_type = "Тестовый"
665
            bot.send_message(
666
                msg=f"{chat_type} чат выбран для отправки рассылок",
667
                pid=event["message"]["from_id"],
668
                keyboard=kbs.configure_chat(
669
                    payload["group"], payload["chat_type"], payload["chat_id"]
670
                ),
671
            )
672
673
        elif payload["button"] == "unpin_chat":
674
            db.unpin_chat(payload["group"], payload["chat_type"])
675
            db.add_cached_chat(payload["chat_id"])
676
            bot.send_message(
677
                msg="Чат откреплен",
678
                pid=event["message"]["from_id"],
679
                keyboard=kbs.generate_global_chat_prefs(payload["group"]),
680
            )
681
682
        # :blockend: Параметры
683
684
        # :blockstart: Финансы
685
686
        elif payload["button"] == "finances":
687
            group = db.get_group_of_user(event["message"]["from_id"])
688
            bot.send_message(
689
                msg="Меню финансов",
690
                pid=event["message"]["from_id"],
691
                keyboard=kbs.finances_main(group),
692
            )
693
694
        elif payload["button"] == "fin_category":
695
            if "id" not in payload and "name" not in payload:
696
                e_id = db.get_active_expenses_category(event["message"]["from_id"])
697
                payload.update(
698
                    {"id": e_id, "name": db.get_expense_category_by_slug(e_id),}
699
                )
700
            db.update_active_expenses_category(
701
                event["message"]["from_id"], payload["id"]
702
            )
703
            bot.send_message(
704
                msg=f"Меню управления статьей {payload['name']}.",
705
                pid=event["message"]["from_id"],
706
                keyboard=kbs.fin_category_menu(),
707
            )
708
709
        elif payload["button"] == "balance":
710
            donates = sum(db.get_all_donates())
711
            expenses = sum(db.get_all_expenses())
712
            delta = donates - expenses
713
714
            bot.send_message(
715
                msg=f"Остаток: {delta} руб.", pid=event["message"]["from_id"]
716
            )
717
        elif payload["button"] == "add_expense_cat":
718
            db.update_session_state(
719
                user_id=event["message"]["from_id"],
720
                state="ask_for_new_expenses_cat_prefs",
721
            )
722
            bot.send_message(
723
                msg="Отправьте название статьи расхода и сумму сбора, отделенную "
724
                "запятой.\n Пример: 23 февраля, 500",
725
                pid=event["message"]["from_id"],
726
                keyboard=kbs.cancel(),
727
            )
728
        elif (
729
            db.get_session_state(event["message"]["from_id"])
730
            == "ask_for_new_expenses_cat_prefs"
731
            and payload["button"] == "cancel"
732
        ):
733
            group = db.get_group_of_user(event["message"]["from_id"])
734
            db.update_session_state(event["message"]["from_id"], "main")
735
            bot.send_message(
736
                msg="Операция отменена.",
737
                pid=event["message"]["from_id"],
738
                keyboard=kbs.finances_main(group),
739
            )
740
        elif (
741
            db.get_session_state(event["message"]["from_id"])
742
            == "ask_for_new_expenses_cat_prefs"
743
        ):
744
            if re.match(r"^.*,.*\d+$", event["message"]["text"]):
745
                parsed = event["message"]["text"].split(",")
746
                name, summ = parsed
747
                group = db.get_group_of_user(event["message"]["from_id"])
748
                db.add_expences_category(name, summ, group)
749
                bot.send_message(
750
                    msg=f'Новая статья "{name}" с суммой сборов {summ} р. успешно создана.',
751
                    pid=event["message"]["from_id"],
752
                    keyboard=kbs.finances_main(group),
753
                )
754
                db.update_session_state(event["message"]["from_id"], "main")
755
            else:
756
                group = db.get_group_of_user(event["message"]["from_id"])
757
                bot.send_message(
758
                    msg=f"Неверный формат сообщения.",
759
                    pid=event["message"]["from_id"],
760
                    keyboard=kbs.finances_main(group),
761
                )
762
763
        elif payload["button"] == "fin_prefs":
764
            cat = db.get_expense_category_by_slug(
765
                db.get_active_expenses_category(event["message"]["from_id"])
766
            )
767
            bot.send_message(
768
                msg=f"Настройки категории {cat}",
769
                pid=event["message"]["from_id"],
770
                keyboard=kbs.fin_prefs(),
771
            )
772
773
        elif payload["button"] == "update_summ":
774
            cat = db.get_expense_category_by_slug(
775
                db.get_active_expenses_category(event["message"]["from_id"])
776
            )
777
            db.update_session_state(
778
                user_id=event["message"]["from_id"], state="ask_for_expense_cat_summ",
779
            )
780
            bot.send_message(
781
                msg=f"Введите новую сумму для статьи {cat}:",
782
                pid=event["message"]["from_id"],
783
                keyboard=kbs.cancel(),
784
            )
785
786
        elif (
787
            payload["button"] == ""
788
            and db.get_session_state(event["message"]["from_id"])
789
            == "ask_for_expense_cat_summ"
790
        ):
791
            if re.match(r"^\d+$", event["message"]["text"]):
792
                db.update_expense_summ(
793
                    db.get_active_expenses_category(event["message"]["from_id"]),
794
                    event["message"]["text"],
795
                )
796
                bot.send_message(
797
                    msg="Сумма сборов обновлена.",
798
                    pid=event["message"]["from_id"],
799
                    keyboard=kbs.fin_prefs(),
800
                )
801
            else:
802
                bot.send_message(
803
                    msg="Неверный формат сообщения. Необходимо только число.",
804
                    pid=event["message"]["from_id"],
805
                )
806
807
        elif (
808
            payload["button"] == "cancel"
809
            and db.get_session_state(event["message"]["from_id"])
810
            == "ask_for_expense_cat_summ"
811
        ):
812
            db.update_session_state(event["message"]["from_id"], "main")
813
            bot.send_message(
814
                msg="Операция отменена.",
815
                pid=event["message"]["from_id"],
816
                keyboard=kbs.fin_category_menu(),
817
            )
818
819
        elif payload["button"] == "update_name":
820
            cat = db.get_expense_category_by_slug(
821
                db.get_active_expenses_category(event["message"]["from_id"])
822
            )
823
            db.update_session_state(
824
                user_id=event["message"]["from_id"], state="ask_for_expense_cat_name",
825
            )
826
            bot.send_message(
827
                msg=f"Введите новое имя для статьи {cat}:",
828
                pid=event["message"]["from_id"],
829
                keyboard=kbs.cancel(),
830
            )
831
832
        elif (
833
            payload["button"] == ""
834
            and db.get_session_state(event["message"]["from_id"])
835
            == "ask_for_expense_cat_name"
836
        ):
837
            db.update_expense_name(
838
                db.get_active_expenses_category(event["message"]["from_id"]),
839
                event["message"]["text"],
840
            )
841
            bot.send_message(
842
                msg="Название сбора обновлено.",
843
                pid=event["message"]["from_id"],
844
                keyboard=kbs.fin_prefs(),
845
            )
846
847
        elif (
848
            payload["button"] == "cancel"
849
            and db.get_session_state(event["message"]["from_id"])
850
            == "ask_for_expense_cat_name"
851
        ):
852
            db.update_session_state(event["message"]["from_id"], "main")
853
            bot.send_message(
854
                msg="Операция отменена.",
855
                pid=event["message"]["from_id"],
856
                keyboard=kbs.fin_category_menu(),
857
            )
858
        elif payload["button"] == "delete_expense":
859
            cat = db.get_expense_category_by_slug(
860
                db.get_active_expenses_category(event["message"]["from_id"])
861
            )
862
            db.update_session_state(
863
                user_id=event["message"]["from_id"], state="confirm_delete_expense",
864
            )
865
            bot.send_message(
866
                msg=f"Вы действительно хотите удалить статью {cat}?\nВсе связанные "
867
                f"записи также будут удалены.",
868
                pid=event["message"]["from_id"],
869
                keyboard=kbs.prompt(),
870
            )
871
872
        elif (
873
            payload["button"] == "confirm"
874
            and db.get_session_state(event["message"]["from_id"])
875
            == "confirm_delete_expense"
876
        ):
877
            exp_id = db.get_active_expenses_category(event["message"]["from_id"])
878
            name = db.get_expense_category_by_slug(exp_id)
879
            db.delete_expense_catgory(exp_id)
880
            db.update_active_expenses_category(event["message"]["from_id"], "none")
881
            db.update_session_state(event["message"]["from_id"], "main")
882
            group = db.get_group_of_user(event["message"]["from_id"])
883
            bot.send_message(
884
                msg=f"Категория {name} удалена.",
885
                pid=event["message"]["from_id"],
886
                keyboard=kbs.finances_main(group),
887
            )
888
889
        elif (
890
            payload["button"] == "deny"
891
            and db.get_session_state(event["message"]["from_id"])
892
            == "confirm_delete_expense"
893
        ):
894
            db.update_session_state(event["message"]["from_id"], "main")
895
            bot.send_message(
896
                msg="Операция отменена.",
897
                pid=event["message"]["from_id"],
898
                keyboard=kbs.fin_prefs(),
899
            )
900
901
        elif payload["button"] == "add_donate":
902
            try:
903
                db.update_session_state(event["message"]["from_id"], "select_donater")
904
            except ProgrammingError:
905
                pass
906
            group = db.get_group_of_user(event["message"]["from_id"])
907
            bot.send_message(
908
                msg="Выберите внесшего деньги:",
909
                pid=event["message"]["from_id"],
910
                keyboard=kbs.generate_finances_prompt(group),
911
            )
912
913
        elif (
914
            payload["button"] == "student"
915
            and db.get_session_state(event["message"]["from_id"]) == "select_donater"
916
        ):
917
            exp_id = db.get_active_expenses_category(event["message"]["from_id"])
918
            summ = db.get_expense_summ(exp_id)
919
            d_list = db.get_list_of_donaters_by_slug(exp_id)
920
            if payload["id"] in d_list:
921
                d_id = db.get_id_of_donate_record(payload["id"], exp_id)
922
                db.set_current_date_as_update(d_id)
923
            else:
924
                d_id = db.create_donate(payload["id"], exp_id)
925
            db.update_donate_id(event["message"]["from_id"], d_id)
926
            db.update_session_state(event["message"]["from_id"], "ask_for_donate_summ")
927
            bot.send_message(
928
                msg="Введите сумму взноса",
929
                pid=event["message"]["from_id"],
930
                keyboard=kbs.cancel(),
931
            )
932
933
        elif (
934
            payload["button"] == "cancel"
935
            and db.get_session_state(event["message"]["from_id"])
936
            == "ask_for_donate_summ"
937
        ):
938
            d_id = db.get_donate_id(event["message"]["from_id"])
939
            db.delete_donate(d_id)
940
            bot.send_message(
941
                msg="Операция отменена.",
942
                pid=event["message"]["from_id"],
943
                keyboard=kbs.fin_category_menu(),
944
            )
945
946
        elif (
947
            payload["button"] == ""
948
            and db.get_session_state(event["message"]["from_id"])
949
            == "ask_for_donate_summ"
950
        ):
951
            if re.match(r"^\d+$", event["message"]["text"]):
952
                d_id = db.get_donate_id(event["message"]["from_id"])
953
954
                db.append_summ_to_donate(d_id, int(event["message"]["text"]))
955
                db.update_session_state(event["message"]["from_id"], "main")
956
                bot.send_message(
957
                    "Запись успешно создана.",
958
                    pid=event["message"]["from_id"],
959
                    keyboard=kbs.fin_category_menu(),
960
                )
961
962
            else:
963
                bot.send_message(
964
                    "Неверный формат сообщения. Необходимо только число.",
965
                    pid=event["message"]["from_id"],
966
                )
967
968
        elif (
969
            payload["button"] == "back"
970
            and db.get_session_state(event["message"]["from_id"]) == "select_donater"
971
        ):
972
            group = db.get_group_of_user(event["message"]["from_id"])
973
            bot.send_message(
974
                msg="Отправка клавиатуры с алфавитом.",
975
                pid=event["message"]["from_id"],
976
                keyboard=kbs.generate_finances_prompt(group),
977
            )
978
979
        elif (
980
            payload["button"] == "cancel"
981
            and db.get_session_state(event["message"]["from_id"]) == "select_donater"
982
        ):
983
            bot.send_message(
984
                msg="Операция отменена",
985
                pid=event["message"]["from_id"],
986
                keyboard=kbs.fin_category_menu(),
987
            )
988
989
        elif payload["button"] == "fin_stat":
990
991
            bot.send_message(msg="Вычисляю...", pid=event["message"]["from_id"])
992
993
            group = db.get_group_of_user(event["message"]["from_id"])
994
            exp_id = db.get_active_expenses_category(event["message"]["from_id"])
995
            wasted = sum(db.get_all_expenses_in_category(exp_id))
996
            summ = db.get_expense_summ(exp_id)
997
            d_ids = db.get_list_of_donaters_by_slug(exp_id, summ)
998
            s_ids = db.get_active_students_ids(group)
999
            name = db.get_expense_category_by_slug(exp_id)
1000
1001
            donated = len(d_ids)
1002
            not_donated = len(s_ids) - donated
1003
            collected = sum(db.get_all_donates_in_category(exp_id))
1004
1005
            bot.send_message(
1006
                msg=f'Статистика по статье "{name}":\n'
1007
                f"Всего сдали: {donated} человек;\n"
1008
                f"Всего не сдали: {not_donated} человек;\n"
1009
                f"Всего собрано: {collected} руб.\n"
1010
                f"Всего потрачено: {wasted} руб.",
1011
                pid=event["message"]["from_id"],
1012
            )
1013
1014
        elif payload["button"] == "add_expense":
1015
            db.update_session_state(event["message"]["from_id"], "ask_for_expense_summ")
1016
            bot.send_message(
1017
                msg="Введите сумму расхода (нужно ввести только число):",
1018
                pid=event["message"]["from_id"],
1019
                keyboard=kbs.cancel(),
1020
            )
1021
1022
        elif (
1023
            payload["button"] == "cancel"
1024
            and db.get_session_state(event["message"]["from_id"])
1025
            == "ask_for_expense_summ"
1026
        ):
1027
            db.update_session_state(event["message"]["from_id"], "main")
1028
            bot.send_message(
1029
                msg="Операция отменена.",
1030
                pid=event["message"]["from_id"],
1031
                keyboard=kbs.fin_category_menu(),
1032
            )
1033
1034
        elif (
1035
            db.get_session_state(event["message"]["from_id"]) == "ask_for_expense_summ"
1036
        ):
1037
            if re.match(r"^\d+$", event["message"]["text"]):
1038
                exp_id = db.get_active_expenses_category(event["message"]["from_id"])
1039
                db.add_expense(exp_id, event["message"]["text"])
1040
                bot.send_message(
1041
                    msg="Запись создана.",
1042
                    pid=event["message"]["from_id"],
1043
                    keyboard=kbs.fin_category_menu(),
1044
                )
1045
                db.update_session_state(event["message"]["from_id"], "main")
1046
1047
            else:
1048
                bot.send_message(
1049
                    msg="Неверный формат сообщения.", pid=event["message"]["from_id"]
1050
                )
1051
1052
        elif payload["button"] == "debtors":
1053
            bot.send_message(
1054
                msg="Генерация сообщения может занять некоторое время...",
1055
                pid=event["message"]["from_id"],
1056
            )
1057
            db.update_session_state(event["message"]["from_id"], "debtors_forming")
1058
            exp_id = db.get_active_expenses_category(event["message"]["from_id"])
1059
            summ = db.get_expense_summ(exp_id)
1060
            d_s_ids = db.get_list_of_donaters_by_slug(exp_id, summ)
1061
            d_ids = set([str(db.get_vk_id(i)) for i in d_s_ids])
1062
            group = db.get_group_of_user(event["message"]["from_id"])
1063
            s_ids = set(db.get_active_students_ids(group))
1064
            debtors = ",".join(s_ids.difference(d_ids))
1065
            db.update_call_ids(event["message"]["from_id"], debtors)
1066
            send_call_confirm()
1067
1068
        # :blockend: Финансы
1069
1070
        # :blockstart: Веб-интерфейс
1071
1072
        elif payload["button"] == "web":
1073
            bot.send_message(
1074
                msg="Выберите группу для получения ссылки авторизации",
1075
                pid=event["message"]["from_id"],
1076
                keyboard=kbs.generate_administrating_groups(
1077
                    event["message"]["from_id"]
1078
                ),
1079
            )
1080
1081
        elif payload["button"] == "get_auth_link":
1082
            domain = "https://ralph-cms.herokuapp.com"
1083
            url = domain + f"/api/auth/{payload['group']}"
1084
            request = requests.get(url)
1085
            if request.status_code == 200:
1086
                arg = request.json()["result"]["link"]
1087
                bot.send_message(
1088
                    msg="Ваша одноразовая ссылка для авторизации под именем "
1089
                    f"администратора группы {payload['group']}:\n"
1090
                    f"{domain + arg}\nОна действительна в течении 5 минут.\nТак как "
1091
                    f"панель управления находится на бесплатном хостинге, "
1092
                    f"при открытии ссылки с компьютера могут возникнуть "
1093
                    f"проблемы\nПохоже, (без костылей) это никак не решается.",
1094
                    pid=event["message"]["from_id"],
1095
                    keyboard=kbs.generate_main_menu(
1096
                        bot.is_admin(event["message"]["from_id"])
1097
                    ),
1098
                )
1099
1100
        # :blockend: Веб-интерфейс
1101