From f1119a0fff920f305e8daa2c88a301dd0f74aab2 Mon Sep 17 00:00:00 2001 From: Mifarse Date: Tue, 19 Oct 2021 22:33:38 +0300 Subject: [PATCH] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=20=D0=B1=D0=B0=D0=B3=20=D1=81=20=D0=BF=D0=BE=D0=B4?= =?UTF-8?q?=D0=BF=D0=B8=D1=81=D0=BA=D0=BE=D0=B9=20=D0=BD=D0=B0=20=D0=B8?= =?UTF-8?q?=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=BE=D0=B1?= =?UTF-8?q?=20=D0=BE=D1=86=D0=B5=D0=BD=D0=BA=D0=B0=D1=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SpreadsheetsService/app.py | 10 ++++-- SpreadsheetsService/manager/manager.py | 48 ++++++++++++++------------ TelegramBot/bot.py | 21 ++++++----- 3 files changed, 44 insertions(+), 35 deletions(-) diff --git a/SpreadsheetsService/app.py b/SpreadsheetsService/app.py index d64ff76..2d4febd 100644 --- a/SpreadsheetsService/app.py +++ b/SpreadsheetsService/app.py @@ -109,13 +109,17 @@ def student(): @app.route("/students") @availability @superuser -def broadcast(*args, **kwargs): +def students(*args, **kwargs): """Выполняет рассылку студентам.""" sub_only = flask.request.args.get("sub_only", str(False)) + include_assignments = flask.request.args.get("include_assignments", str(False)) + include_assignments = include_assignments.lower() == "true" if sub_only.lower() == "true": - return flask.jsonify(app.db.get_all_groups_only_sub_students()) + return flask.jsonify( + app.db.get_all_groups_only_sub_students(include_assignments) + ) else: - return flask.jsonify(app.db.get_all_groups()) + return flask.jsonify(app.db.get_all_groups(include_assignments)) @app.route("/sub") diff --git a/SpreadsheetsService/manager/manager.py b/SpreadsheetsService/manager/manager.py index 60c4b5b..0730a30 100644 --- a/SpreadsheetsService/manager/manager.py +++ b/SpreadsheetsService/manager/manager.py @@ -47,7 +47,6 @@ def timed_lru_cache(seconds: int, maxsize: int = 128): if datetime.utcnow() >= func.expiration: func.cache_clear() func.expiration = datetime.utcnow() + func.lifetime - print(*args) return func(*args, **kwargs) return wrapped_func @@ -122,7 +121,7 @@ class Manager: else: return self._cached_get_values(range_name) - @timed_lru_cache(seconds=25*60) + @timed_lru_cache(seconds=25 * 60) def _cached_get_values(self, range_name): return self._get_values(range_name) @@ -174,43 +173,46 @@ class Manager: return group - def get_all_groups(self) -> list: + def get_all_groups(self, include_assingments: bool = False) -> list: """Получить список всех групп.""" values = self.get_values() groups = defaultdict(lambda: Group("0")) for row in values: groups[row[GROUP_IDS]].group_id = row[GROUP_IDS] - groups[row[GROUP_IDS]].add_student( - Student( - number=int(row[STUDENT_NUMBERS]), - name=row[STUDENT_NAMES], - group_id=row[GROUP_IDS], - tg_id=row[STUDENT_TELEGRAM_IDS], - subjects=row[STUDENT_SUBJECTS].split(","), - is_subbed=bool(int(row[STUDENT_SUBSCRIPTION])), - ) + student = Student( + number=int(row[STUDENT_NUMBERS]), + name=row[STUDENT_NAMES], + group_id=row[GROUP_IDS], + tg_id=row[STUDENT_TELEGRAM_IDS], + subjects=row[STUDENT_SUBJECTS].split(","), + is_subbed=bool(int(row[STUDENT_SUBSCRIPTION])), ) + if include_assingments: + self.set_assignments_for_student(student) + groups[row[GROUP_IDS]].add_student(student) return groups - def get_all_groups_only_sub_students(self) -> list: + def get_all_groups_only_sub_students( + self, include_assingments: bool = False + ) -> list: """Получить список всех групп.""" values = self.get_values() groups = defaultdict(lambda: Group("0")) f = lambda row: row[STUDENT_SUBSCRIPTION] == "1" for row in filter(f, values): groups[row[GROUP_IDS]].group_id = row[GROUP_IDS] - groups[row[GROUP_IDS]].add_student( - Student( - number=int(row[STUDENT_NUMBERS]), - name=row[STUDENT_NAMES], - group_id=row[GROUP_IDS], - tg_id=row[STUDENT_TELEGRAM_IDS], - subjects=row[STUDENT_SUBJECTS].split(","), - is_subbed=bool(int(row[STUDENT_SUBSCRIPTION])), - ) + student = Student( + number=int(row[STUDENT_NUMBERS]), + name=row[STUDENT_NAMES], + group_id=row[GROUP_IDS], + tg_id=row[STUDENT_TELEGRAM_IDS], + subjects=row[STUDENT_SUBJECTS].split(","), + is_subbed=bool(int(row[STUDENT_SUBSCRIPTION])), ) - + if include_assingments: + self.set_assignments_for_student(student) + groups[row[GROUP_IDS]].add_student(student) return groups def get_student_by_name(self, name: str) -> Student: diff --git a/TelegramBot/bot.py b/TelegramBot/bot.py index 42c7b4f..fa03b97 100644 --- a/TelegramBot/bot.py +++ b/TelegramBot/bot.py @@ -396,7 +396,8 @@ def variant(update: Update, context: CallbackContext): def error(update: Update, context: CallbackContext): LOG.error(msg="Exception while handling an update:", exc_info=context.error) - update.message.reply_text("Ой, кажется у меня %s" % repr(context.error)) + if context.error is not None: + update.message.reply_text("Ой, кажется у меня %s" % repr(context.error)) update.message.reply_sticker(MESSAGES.Stickers.DEAD) return ConversationHandler.END @@ -407,18 +408,21 @@ def error(update: Update, context: CallbackContext): def grades_checker(context: CallbackContext): """Задача по проверке оценок. - Пробегает по списку подписавшихся и для каждого студента запрашивает - `/grades/fingerprint`. Отпечаток (fingerprint) - текстовая строка - захешированных оценок. При изменении оценок, меняется и их хеш. Бот с каждым - вызовом задачи запоминает эти хеши всех студентов и сверяет их. Если вдруг - несовпадение, то значит, что данные об оценках были изменены. + Запрашивает список подписавшихся вместе с подключенными домашками. У + каждого студента проверяет отпечаток. Отпечаток (fingerprint) - текстовая + строка захешированных оценок. При изменении оценок, меняется и их хеш. Бот с + каждым вызовом задачи запоминает эти хеши всех студентов и сверяет их. Если + вдруг несовпадение, то значит, что данные об оценках были изменены. Это простой и универсальный способ смотреть изменения, но он не дает инфы о том, в каком задании появилась новая оценка. """ - r = requests.get(f"{HOST}/students", params={"god_mode": True, "sub_only": True}) + r = requests.get( + f"{HOST}/students", + params={"god_mode": True, "sub_only": True, "include_assignments": True}, + ) data = r.json() context.bot_data["groups"] = data @@ -429,8 +433,7 @@ def grades_checker(context: CallbackContext): for group in data.values(): for student in group["students"]: tg_id = student["tg_id"] - r = requests.get(f"{HOST}/grades/fingerprint", params={"tg_id": tg_id}) - fingerprint = r.json().get("fingerprint", "") + fingerprint = student.get("fingerprint", "") old_fingerprint = context.bot_data["fingerprints"][tg_id] # При инициализации у старого отпечатка ещё не установлено значение. # Там находится пустая строка, поэтому нужна дополн. проверка.