Passed
Push — master ( 1663f9...461fea )
by Daniil
02:28 queued 12s
created

main.load_attachs()   C

Complexity

Conditions 10

Size

Total Lines 29
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 28
dl 0
loc 29
rs 5.9999
c 0
b 0
f 0
cc 10
nop 0

How to fix   Complexity   

Complexity

Complex classes like main.load_attachs() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
import datetime
2
import json
3
import os
4
import re
5
from enum import Enum
6
7
import requests
8
from vk_api.bot_longpoll import VkBotEventType
9
10
from bot import Bot
11
from database import Database
12
from keyboard import Keyboards
13
from scheduler import Date
14
from scheduler import Schedule
15
16
db = Database(os.environ["DATABASE_URL"])
17
bot = Bot()
18
kbs = Keyboards()
19
20
bot.auth()
21
bot.update_version()
22
23
24
class EventTypes(Enum):
25
    NEW_MESSAGE = VkBotEventType.MESSAGE_NEW
26
27
28
def generate_call_message():
29
    f = db.get_names_using_status(event["message"]["from_id"])
30
    students_ids = db.get_call_ids(event["message"]["from_id"])
31
    if students_ids:
32
        mentions = bot.generate_mentions(ids=students_ids, names=f)
33
    else:
34
        mentions = ""
35
    message = db.get_call_message(event["message"]["from_id"]) or ""
36
    message = f"{mentions}\n{message}"
37
    return message
38
39
40
def send_call_confirm():
41
    chat_id = int(str(db.get_conversation(event["message"]["from_id"]))[-1])
42
    message = generate_call_message()
43
    atch = db.get_call_attaches(event["message"]["from_id"])
44
    if atch is None:
45
        atch = ""
46
    if message != "\n":
47
        bot.send_message(
48
            msg=f"В {'тестовую ' if chat_id == 1 else 'основную '}"
49
            f"беседу будет отправлено сообщение:",
50
            pid=event["message"]["from_id"],
51
            keyboard=kbs.prompt(event["message"]["from_id"]),
52
        )
53
        bot.send_message(msg=message, pid=event["message"]["from_id"], attachment=atch)
54
    else:
55
        db.empty_call_storage(event["message"]["from_id"])
56
        bot.send_gui(
57
            pid=event["message"]["from_id"],
58
            text="Сообщение не может быть пустым. Отмена...",
59
        )
60
61
62
def load_attachs():
63
    attachments = []
64
    for i, v in enumerate(event["message"]["attachments"]):
65
        m = -1
66
        m_url = ""
67
        for ind, val in enumerate(event["message"]["attachments"][i]["photo"]["sizes"]):
68
            if val["height"] > m:
69
                m_url = val["url"]
70
        if ".jpeg" or ".jpg" in m_url:
71
            ext = ".jpg"
72
        elif ".png" in m_url:
73
            ext = ".png"
74
        else:
75
            ext = ""
76
        req = requests.get(m_url)
77
        server = bot.bot_vk.photos.getMessagesUploadServer()
78
        with open(f"photo{ext}", "wb") as f:
79
            f.write(req.content)
80
        file = open(f"photo{ext}", "rb")
81
        upload = requests.post(server["upload_url"], files={"photo": file},).json()
82
        save = bot.bot_vk.photos.saveMessagesPhoto(**upload)
83
        photo = f"photo{save[0]['owner_id']}_{save[0]['id']}"
84
        attachments.append(photo)
85
    atch = ",".join(attachments)
86
    state = db.get_session_state(event["message"]["from_id"])
87
    if state == "ask_for_mailing_message":
88
        db.update_mailing_attaches(event["message"]["from_id"], atch)
89
    elif state == "ask_for_call_message":
90
        db.update_call_attaches(event["message"]["from_id"], atch)
91
92
93
for event in bot.longpoll.listen():
94
    event = {
95
        "type": event.type,
96
        "client_info": event.object.client_info,
97
        "message": event.object.message,
98
    }
99
    if (
100
        event["type"] == EventTypes.NEW_MESSAGE.value
101
        and (event["message"]["text"] or event["message"]["attachments"])
102
        and event["message"]["out"] == 0
103
        and event["message"]["from_id"] == event["message"]["peer_id"]
104
    ):
105
        try:
106
            payload = json.loads(event["message"]["payload"])
107
        except KeyError:
108
            payload = {"button": ""}
109
        text = event["message"]["text"].lower()
110
111
        # :blockstart: Запуск интерфейса
112
        if text in ["начать", "старт", "r"]:
113
            if not db.is_user_exist(event["message"]["from_id"]):
114
                db.create_user(event["message"]["from_id"])
115
            if not db.is_session_exist(event["message"]["from_id"]):
116
                db.create_session(event["message"]["from_id"])
117
            bot.send_gui(pid=event["message"]["from_id"])
118
        # :blockend: Запуск интерфейса
119
120
        # :blockstart: Возврат на главный экран
121
        elif payload["button"] == "home":
122
            bot.send_gui(text="Главный экран", pid=event["message"]["from_id"])
123
        # :blockend: Возврат на главный экран
124
125
        # :blockstart: Призыв
126
        elif payload["button"] == "call":
127
            db.update_session_state(event["message"]["from_id"], "ask_for_call_message")
128
            if not db.call_session_exist(event["message"]["from_id"]):
129
                db.create_call_session(event["message"]["from_id"])
130
            bot.send_message(
131
                msg="Отправьте сообщение к призыву (есть поддержка изображений)",
132
                pid=event["message"]["from_id"],
133
                keyboard=kbs.skip(),
134
            )
135
        elif payload["button"] == "letter":
136
            bot.send_message(
137
                msg=f"Отправка клавиатуры с фамилиями на букву \"{payload['letter']}\"",
138
                pid=event["message"]["from_id"],
139
                keyboard=kbs.generate_names_keyboard(payload["letter"]),
140
            )
141
        elif payload["button"] == "student":
142
            ids = db.get_call_ids(event["message"]["from_id"])
143
            if ids:
144
                students = ids.split(",")
145
            else:
146
                students = [ids]
147
            if str(db.get_vk_id(payload["id"])) in students:
148
                bot.send_message(
149
                    msg=f"{payload['name']} уже был выбран для призыва. Пропуск.",
150
                    pid=event["message"]["from_id"],
151
                )
152
            else:
153
                db.append_to_call_ids(
154
                    event["message"]["from_id"], db.get_vk_id(payload["id"])
155
                )
156
                bot.send_message(
157
                    msg=f"{payload['name']} добавлен к списку призыва.",
158
                    pid=event["message"]["from_id"],
159
                )
160
        elif payload["button"] == "back":
161
            bot.send_message(
162
                msg="Отправка клавиатуры с алфавитом.",
163
                pid=event["message"]["from_id"],
164
                keyboard=kbs.generate_call_prompt(),
165
            )
166
        elif payload["button"] == "skip":
167
            db.update_session_state(event["message"]["from_id"], "call_configuring")
168
            bot.send_message(
169
                msg="Отправка клавиатуры с алфавитом.",
170
                pid=event["message"]["from_id"],
171
                keyboard=kbs.generate_call_prompt(),
172
            )
173
        elif (
174
            db.get_session_state(event["message"]["from_id"]) == "ask_for_call_message"
175
        ):
176
            db.update_call_message(
177
                event["message"]["from_id"], event["message"]["text"]
178
            )
179
            if event["message"]["attachments"]:
180
                load_attachs()
181
            bot.send_message(
182
                msg="Отправка клавиатуры призыва",
183
                pid=event["message"]["from_id"],
184
                keyboard=kbs.generate_call_prompt(),
185
            )
186
            db.update_session_state(event["message"]["from_id"], "call_configuring")
187
        elif payload["button"] == "send_to_all":
188
            ids = ",".join(db.get_active_students_ids())
189
            db.update_call_ids(event["message"]["from_id"], ids)
190
            bot.send_message(
191
                msg="Все студенты отмечены как получатели уведомления",
192
                pid=event["message"]["from_id"],
193
            )
194
            send_call_confirm()
195
        elif payload["button"] == "save":
196
            send_call_confirm()
197
        elif (
198
            payload["button"] == "cancel"
199
            and db.get_session_state(event["message"]["from_id"]) == "call_configuring"
200
        ):
201
            db.empty_call_storage(event["message"]["from_id"])
202
            db.update_session_state(event["message"]["from_id"], "main")
203
            bot.send_gui(
204
                text="Выполнение команды отменено.", pid=event["message"]["from_id"]
205
            )
206
        elif (
207
            payload["button"] == "confirm"
208
            and db.get_session_state(event["message"]["from_id"]) == "call_configuring"
209
        ):
210
            bot.log.info("Отправка призыва...")
211
            cid = db.get_conversation(event["message"]["from_id"])
212
            text = generate_call_message()
213
            attachment = db.get_call_attaches(event["message"]["from_id"])
214
            if attachment is None:
215
                attachment = ""
216
            bot.send_message(pid=cid, msg=text, attachment=attachment)
217
            db.empty_call_storage(event["message"]["from_id"])
218
            db.update_session_state(event["message"]["from_id"], "main")
219
            bot.send_gui(text="Сообщение отправлено.", pid=event["message"]["from_id"])
220
        elif (
221
            payload["button"] == "deny"
222
            and db.get_session_state(event["message"]["from_id"]) == "call_configuring"
223
        ):
224
            db.update_call_message(event["message"]["from_id"], " ")
225
            db.update_call_ids(event["message"]["from_id"], " ")
226
            db.update_session_state(event["message"]["from_id"], "main")
227
            bot.send_gui(
228
                text="Выполнение команды отменено.", pid=event["message"]["from_id"]
229
            )
230
        elif payload["button"] == "chconv_call":
231
            conv = db.get_conversation(event["message"]["from_id"])
232
            chat = int(str(conv)[-1])
233
            if chat == 1:
234
                db.update_conversation(event["message"]["from_id"], 2000000002)
235
                chat = 2
236
            elif chat == 2:
237
                db.update_conversation(event["message"]["from_id"], 2000000001)
238
                chat = 1
239
            msg = db.get_call_message(event["message"]["from_id"])
240
            bot.send_message(
241
                msg=f"Теперь это сообщение будет отправлено в "
242
                f"{'тестовую' if chat == 1 else 'основную'} беседу:",
243
                pid=event["message"]["from_id"],
244
            )
245
        elif payload["button"] == "chnames_call":
246
            if db.get_names_using_status(event["message"]["from_id"]):
247
                status = 0
248
            else:
249
                status = 1
250
            db.update_names_using_status(event["message"]["from_id"], status)
251
            send_call_confirm()
252
        # :blockend: Призыв
253
254
        # :blockstart: Расписание
255
        elif payload["button"] == "schedule":
256
            bot.send_message(
257
                msg="Отправка клавиатуры с расписанием.",
258
                pid=event["message"]["from_id"],
259
                keyboard=kbs.generate_schedule_keyboard(),
260
            )
261
        elif payload["button"] == "today":
262
            d = Date()
263
            s = Schedule(d.today)
264
            s.get_raw()
265
            if s.is_exist():
266
                schedule = s.generate()
267
                bot.send_message(msg=schedule, pid=event["message"]["from_id"])
268
            else:
269
                bot.send_message(
270
                    msg="Расписание отсутствует.", pid=event["message"]["from_id"]
271
                )
272
        elif payload["button"] == "tomorrow":
273
            d = Date()
274
            s = Schedule(d.tomorrow)
275
            s.get_raw()
276
            if s.is_exist():
277
                schedule = s.generate()
278
                bot.send_message(msg=schedule, pid=event["message"]["from_id"])
279
            else:
280
                bot.send_message(
281
                    msg="Расписание отсутствует.", pid=event["message"]["from_id"]
282
                )
283
        elif payload["button"] == "day_after_tomorrow":
284
            d = Date()
285
            s = Schedule(d.day_after_tomorrow)
286
            s.get_raw()
287
            if s.is_exist():
288
                schedule = s.generate()
289
                bot.send_message(msg=schedule, pid=event["message"]["from_id"])
290
            else:
291
                bot.send_message(
292
                    msg="Расписание отсутствует.", pid=event["message"]["from_id"]
293
                )
294
        elif payload["button"] == "arbitrary":
295
            bot.send_message(
296
                msg="Напишите дату в формате ДД-ММ-ГГГГ.",
297
                pid=event["message"]["from_id"],
298
                keyboard=kbs.cancel(),
299
            )
300
            db.update_session_state(
301
                event["message"]["from_id"], "ask_for_schedule_date"
302
            )
303
        elif (
304
            payload["button"] == "cancel"
305
            and db.get_session_state(event["message"]["from_id"])
306
            == "ask_for_schedule_date"
307
        ):
308
            db.update_session_state(event["message"]["from_id"], "main")
309
            bot.send_message(
310
                msg="Выполнение команды отменено.",
311
                pid=event["message"]["from_id"],
312
                keyboard=kbs.generate_schedule_keyboard(),
313
            )
314
        elif (
315
            db.get_session_state(event["message"]["from_id"]) == "ask_for_schedule_date"
316
        ):
317
            if re.match(r"^\d\d(.|-|/)\d\d(.|-|/)20\d\d$", event["message"]["text"]):
318
                try:
319
                    d = datetime.datetime.strptime(
320
                        event["message"]["text"], "%d-%m-%Y"
321
                    ).strftime("%Y-%m-%d")
322
                except ValueError:
323
                    bot.send_message(
324
                        msg="Неверный формат даты. Попробуйте еще раз.",
325
                        pid=event["message"]["from_id"],
326
                    )
327
                else:
328
                    s = Schedule(d)
329
                    s.get_raw()
330
                    if s.is_exist():
331
                        schedule = s.generate()
332
                        bot.send_message(
333
                            msg=schedule,
334
                            pid=event["message"]["from_id"],
335
                            keyboard=kbs.generate_schedule_keyboard(),
336
                        )
337
                        db.update_session_state(event["message"]["from_id"], "main")
338
                    else:
339
                        bot.send_message(
340
                            msg="Расписание отсутствует.\nПопробуй указать другую "
341
                            "дату.",
342
                            pid=event["message"]["from_id"],
343
                        )
344
                        db.update_session_state(
345
                            event["message"]["from_id"], "ask_for_schedule_date"
346
                        )
347
            else:
348
                bot.send_message(
349
                    msg="Неверный формат даты. Попробуйте еще раз.",
350
                    pid=event["message"]["from_id"],
351
                )
352
        # :blockend: Расписание
353
354
        # :blockstart: Рассылки
355
        elif payload["button"] == "mailings":
356
            bot.send_message(
357
                msg="Отправка клавиатуры со списком рассылок.",
358
                pid=event["message"]["from_id"],
359
                keyboard=kbs.generate_mailings_keyboard(),
360
            )
361
        elif payload["button"] == "mailing":
362
            if not db.mailing_session_exist(event["message"]["from_id"]):
363
                db.create_mailing_session(event["message"]["from_id"])
364
            db.update_mailing_session(event["message"]["from_id"], payload["slug"])
365
            bot.send_message(
366
                msg=f"Меню управления рассылкой \"{payload['name']}\":",
367
                pid=event["message"]["from_id"],
368
                keyboard=kbs.generate_mailing_mgmt(
369
                    is_admin=bot.is_admin(event["message"]["from_id"]),
370
                    slug=payload["slug"],
371
                    user_id=event["message"]["from_id"],
372
                ),
373
            )
374
        elif payload["button"] == "subscribe":
375
            db.query(
376
                f"UPDATE vk_subscriptions SET {payload['slug']}=1 WHERE "
377
                f"user_id={payload['user_id']}"
378
            )
379
            bot.send_message(
380
                msg="Вы были успешно подписаны на рассылку.",
381
                pid=event["message"]["from_id"],
382
                keyboard=kbs.generate_mailing_mgmt(
383
                    is_admin=bot.is_admin(event["message"]["from_id"]),
384
                    slug=payload["slug"],
385
                    user_id=event["message"]["from_id"],
386
                ),
387
            )
388
        elif payload["button"] == "unsubscribe":
389
            db.query(
390
                f"UPDATE vk_subscriptions SET {payload['slug']}=0 WHERE "
391
                f"user_id={payload['user_id']}"
392
            )
393
            bot.send_message(
394
                msg="Вы были успешно отписаны от рассылки.",
395
                pid=event["message"]["from_id"],
396
                keyboard=kbs.generate_mailing_mgmt(
397
                    is_admin=bot.is_admin(event["message"]["from_id"]),
398
                    slug=payload["slug"],
399
                    user_id=event["message"]["from_id"],
400
                ),
401
            )
402
        elif payload["button"] == "send_mailing":
403
            db.update_session_state(
404
                event["message"]["from_id"], "ask_for_mailing_message"
405
            )
406
            bot.send_message(
407
                msg="Отправьте текст рассылки (есть поддержка изображений)",
408
                pid=event["message"]["from_id"],
409
                keyboard=kbs.cancel(),
410
            )
411
        elif (
412
            payload["button"] == "cancel"
413
            and db.get_session_state(event["message"]["from_id"])
414
            == "ask_for_mailing_message"
415
        ):
416
            bot.send_message(
417
                msg="Выполнение команды отменено. Возвращаюсь на экран управления "
418
                "рассылкой.",
419
                pid=event["message"]["from_id"],
420
                keyboard=kbs.generate_mailing_mgmt(
421
                    is_admin=bot.is_admin(event["message"]["from_id"]),
422
                    slug=db.get_mailing_session(event["message"]["from_id"]),
423
                    user_id=event["message"]["from_id"],
424
                ),
425
            )
426
            db.update_session_state(event["message"]["from_id"], "main")
427
        elif (
428
            db.get_session_state(event["message"]["from_id"])
429
            == "ask_for_mailing_message"
430
        ):
431
            db.update_mailing_message(
432
                event["message"]["from_id"], event["message"]["text"]
433
            )
434
            if event["message"]["attachments"]:
435
                load_attachs()
436
            bot.send_message(
437
                msg="Всем подписчикам рассылки будет отправлено сообщение с указанным вами текстом",
438
                pid=event["message"]["from_id"],
439
                keyboard=kbs.prompt(),
440
                forward=f"{event['message']['id']}",
441
            )
442
            db.update_session_state(event["message"]["from_id"], "prompt_mailing")
443
        elif (
444
            payload["button"] == "confirm"
445
            and db.get_session_state(event["message"]["from_id"]) == "prompt_mailing"
446
        ):
447
            attach = db.get_mailing_attaches(event["message"]["from_id"])
448
            if attach is None:
449
                attach = ""
450
            bot.send_mailing(
451
                slug=db.get_mailing_session(event["message"]["from_id"]),
452
                text=db.get_mailing_message(event["message"]["from_id"]),
453
                attach=attach,
454
            )
455
            bot.send_message(
456
                msg="Рассылка отправлена.",
457
                pid=event["message"]["from_id"],
458
                keyboard=kbs.generate_mailings_keyboard(),
459
            )
460
        elif (
461
            payload["button"] == "deny"
462
            and db.get_session_state(event["message"]["from_id"]) == "prompt_mailing"
463
        ):
464
            db.empty_mailing_storage(event["message"]["from_id"])
465
            bot.send_message(
466
                msg="Отправка рассылки отменена.",
467
                pid=event["message"]["from_id"],
468
                keyboard=kbs.generate_mailings_keyboard(),
469
            )
470
        # :blockend: Рассылки
471
472
        # :blockstart: Параметры
473
        elif payload["button"] == "prefs":
474
            bot.send_message(
475
                msg="Параметры",
476
                pid=event["message"]["from_id"],
477
                keyboard=kbs.generate_prefs_keyboard(),
478
            )
479
480
        elif payload["button"] == "chconv":
481
            chat = db.get_conversation(event["message"]["from_id"])
482
            if chat == 2000000001:
483
                bot.send_message(
484
                    msg="Тестовая беседа сейчас активна",
485
                    pid=event["message"]["from_id"],
486
                    keyboard=kbs.generate_conv_selector(chat),
487
                )
488
            elif chat == 2000000002:
489
                bot.send_message(
490
                    msg="Основная беседа сейчас активна",
491
                    pid=event["message"]["from_id"],
492
                    keyboard=kbs.generate_conv_selector(chat),
493
                )
494
495
        elif payload["button"] == "select_main_conv":
496
            chat = 2000000002
497
            db.update_conversation(event["message"]["from_id"], chat)
498
            bot.send_message(
499
                msg="Основная беседа активна.",
500
                pid=event["message"]["from_id"],
501
                keyboard=kbs.generate_conv_selector(chat),
502
            )
503
        elif payload["button"] == "select_test_conv":
504
            chat = 2000000001
505
            db.update_conversation(event["message"]["from_id"], chat)
506
            bot.send_message(
507
                msg="Тестовая беседа активна.",
508
                pid=event["message"]["from_id"],
509
                keyboard=kbs.generate_conv_selector(chat),
510
            )
511
512
        elif payload["button"] == "names":
513
            status = db.get_names_using_status(event["message"]["from_id"])
514
            msg = (
515
                f"Использование имён в призыве "
516
                f"{'активно' if status else 'неактивно'}."
517
            )
518
            bot.send_message(
519
                msg=msg,
520
                pid=event["message"]["from_id"],
521
                keyboard=kbs.generate_names_selector(status),
522
            )
523
524
        elif payload["button"] == "off_using_names":
525
            status = 0
526
            db.update_names_using_status(event["message"]["from_id"], status)
527
            bot.send_message(
528
                msg="Использование имён в призыве отключено.",
529
                pid=event["message"]["from_id"],
530
                keyboard=kbs.generate_names_selector(bool(status)),
531
            )
532
        elif payload["button"] == "on_using_names":
533
            status = 1
534
            db.update_names_using_status(event["message"]["from_id"], status)
535
            bot.send_message(
536
                msg="Использование имён в призыве включено.",
537
                pid=event["message"]["from_id"],
538
                keyboard=kbs.generate_names_selector(bool(status)),
539
            )
540
        # :blockend: Параметры
541