Исправлен баг с подпиской на изменения об оценках

This commit is contained in:
Serafim Urukov 2021-10-19 22:33:38 +03:00
parent 4a326c13f0
commit f1119a0fff
3 changed files with 44 additions and 35 deletions

View File

@ -109,13 +109,17 @@ def student():
@app.route("/students") @app.route("/students")
@availability @availability
@superuser @superuser
def broadcast(*args, **kwargs): def students(*args, **kwargs):
"""Выполняет рассылку студентам.""" """Выполняет рассылку студентам."""
sub_only = flask.request.args.get("sub_only", str(False)) 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": 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: else:
return flask.jsonify(app.db.get_all_groups()) return flask.jsonify(app.db.get_all_groups(include_assignments))
@app.route("/sub") @app.route("/sub")

View File

@ -47,7 +47,6 @@ def timed_lru_cache(seconds: int, maxsize: int = 128):
if datetime.utcnow() >= func.expiration: if datetime.utcnow() >= func.expiration:
func.cache_clear() func.cache_clear()
func.expiration = datetime.utcnow() + func.lifetime func.expiration = datetime.utcnow() + func.lifetime
print(*args)
return func(*args, **kwargs) return func(*args, **kwargs)
return wrapped_func return wrapped_func
@ -122,7 +121,7 @@ class Manager:
else: else:
return self._cached_get_values(range_name) 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): def _cached_get_values(self, range_name):
return self._get_values(range_name) return self._get_values(range_name)
@ -174,43 +173,46 @@ class Manager:
return group return group
def get_all_groups(self) -> list: def get_all_groups(self, include_assingments: bool = False) -> list:
"""Получить список всех групп.""" """Получить список всех групп."""
values = self.get_values() values = self.get_values()
groups = defaultdict(lambda: Group("0")) groups = defaultdict(lambda: Group("0"))
for row in values: for row in values:
groups[row[GROUP_IDS]].group_id = row[GROUP_IDS] groups[row[GROUP_IDS]].group_id = row[GROUP_IDS]
groups[row[GROUP_IDS]].add_student( student = Student(
Student( number=int(row[STUDENT_NUMBERS]),
number=int(row[STUDENT_NUMBERS]), name=row[STUDENT_NAMES],
name=row[STUDENT_NAMES], group_id=row[GROUP_IDS],
group_id=row[GROUP_IDS], tg_id=row[STUDENT_TELEGRAM_IDS],
tg_id=row[STUDENT_TELEGRAM_IDS], subjects=row[STUDENT_SUBJECTS].split(","),
subjects=row[STUDENT_SUBJECTS].split(","), is_subbed=bool(int(row[STUDENT_SUBSCRIPTION])),
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 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() values = self.get_values()
groups = defaultdict(lambda: Group("0")) groups = defaultdict(lambda: Group("0"))
f = lambda row: row[STUDENT_SUBSCRIPTION] == "1" f = lambda row: row[STUDENT_SUBSCRIPTION] == "1"
for row in filter(f, values): for row in filter(f, values):
groups[row[GROUP_IDS]].group_id = row[GROUP_IDS] groups[row[GROUP_IDS]].group_id = row[GROUP_IDS]
groups[row[GROUP_IDS]].add_student( student = Student(
Student( number=int(row[STUDENT_NUMBERS]),
number=int(row[STUDENT_NUMBERS]), name=row[STUDENT_NAMES],
name=row[STUDENT_NAMES], group_id=row[GROUP_IDS],
group_id=row[GROUP_IDS], tg_id=row[STUDENT_TELEGRAM_IDS],
tg_id=row[STUDENT_TELEGRAM_IDS], subjects=row[STUDENT_SUBJECTS].split(","),
subjects=row[STUDENT_SUBJECTS].split(","), is_subbed=bool(int(row[STUDENT_SUBSCRIPTION])),
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 return groups
def get_student_by_name(self, name: str) -> Student: def get_student_by_name(self, name: str) -> Student:

View File

@ -396,7 +396,8 @@ def variant(update: Update, context: CallbackContext):
def error(update: Update, context: CallbackContext): def error(update: Update, context: CallbackContext):
LOG.error(msg="Exception while handling an update:", exc_info=context.error) 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) update.message.reply_sticker(MESSAGES.Stickers.DEAD)
return ConversationHandler.END return ConversationHandler.END
@ -407,18 +408,21 @@ def error(update: Update, context: CallbackContext):
def grades_checker(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() data = r.json()
context.bot_data["groups"] = data context.bot_data["groups"] = data
@ -429,8 +433,7 @@ def grades_checker(context: CallbackContext):
for group in data.values(): for group in data.values():
for student in group["students"]: for student in group["students"]:
tg_id = student["tg_id"] tg_id = student["tg_id"]
r = requests.get(f"{HOST}/grades/fingerprint", params={"tg_id": tg_id}) fingerprint = student.get("fingerprint", "")
fingerprint = r.json().get("fingerprint", "")
old_fingerprint = context.bot_data["fingerprints"][tg_id] old_fingerprint = context.bot_data["fingerprints"][tg_id]
# При инициализации у старого отпечатка ещё не установлено значение. # При инициализации у старого отпечатка ещё не установлено значение.
# Там находится пустая строка, поэтому нужна дополн. проверка. # Там находится пустая строка, поэтому нужна дополн. проверка.