From 7c24a7ec71afb469aa63c634a70007822ff69b1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Setni=C4=8Dka?= <setnicka@seznam.cz> Date: Sun, 7 Mar 2021 20:30:27 +0100 Subject: [PATCH] =?UTF-8?q?V=C3=BDsledkov=C3=A1=20listina=20upravena=20pro?= =?UTF-8?q?=20d=C4=9Blen=C3=A1=20kola?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pro dělená kola výsledkovka agreguje všechny úlohy z kol ve skupině. Při zobrazení na webu je potřeba správně odkazovat na patřičné contesty: * Proklik na účastníky zůstává ve stejném kole * Proklik na záhlaví úlohy může vést i do jiného kola skupiny * Proklik na submit může vést i do jiného kola skupiny Issue #178 --- mo/score.py | 16 +++++++++------- mo/web/org_score.py | 23 ++++++++++++++++++----- 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/mo/score.py b/mo/score.py index b7f4ed5d..aba2ffe7 100644 --- a/mo/score.py +++ b/mo/score.py @@ -105,12 +105,12 @@ class Score: self.contest = contest self.part_states = part_states - # Příprava subquery na účastníky + # Příprava subquery na účastníky (contest_subq obsahuje master_contest_id) sess = db.get_session() if contest: - contest_subq = [contest.contest_id] + contest_subq = [contest.master_contest_id] else: - contest_subq = sess.query(db.Contest.contest_id).filter_by(round=round) + contest_subq = sess.query(db.Contest.master_contest_id).filter_by(round=round) # Načtení účastníků data: List[Tuple[db.User, db.Participation, db.Participant]] = ( @@ -164,7 +164,9 @@ class Score: num_participants = db.get_count(user_id_subq) # Načtení úloh - tasks: List[db.Task] = sess.query(db.Task).filter_by(round=round).all() + tasks: List[db.Task] = sess.query(db.Task).filter(db.Task.round_id.in_( + sess.query(db.Round.round_id).filter_by(master_round_id=round.master_round_id) + )).all() for task in tasks: self._tasks[step][task.task_id] = ScoreTask(task) self._tasks[step][task.task_id].num_solutions = num_participants @@ -202,7 +204,7 @@ class Score: # Zkusíme nalézt kolo o `step` kroků zpět prev_round = sess.query(db.Round).filter_by( year=self.round.year, category=self.round.category, seq=self.round.seq - step - ).one_or_none() + ).filter(db.Round.master_round_id == db.Round.round_id).one_or_none() if prev_round is None: return False self._prev_rounds[step] = prev_round @@ -211,13 +213,13 @@ class Score: # Pokud tvoříme výsledkovku pro contest, tak nás zajímají jen řešení # z podoblastí contestu spadajícího pod hlavní desc_cte = db.place_descendant_cte(self.contest.place, max_level=prev_round.level) - contest_subq = sess.query(db.Contest.contest_id).filter( + contest_subq = sess.query(db.Contest.master_contest_id).filter( db.Contest.round == prev_round, db.Contest.place_id.in_(select([desc_cte])) ) else: # Pokud vytváříme výsledkovku pro celé kolo, bereme vše - contest_subq = sess.query(db.Contest.contest_id).filter_by(round=prev_round) + contest_subq = sess.query(db.Contest.master_contest_id).filter_by(round=prev_round) self._load_tasks_and_sols(step, prev_round, contest_subq) return True diff --git a/mo/web/org_score.py b/mo/web/org_score.py index 4925de52..34043704 100644 --- a/mo/web/org_score.py +++ b/mo/web/org_score.py @@ -1,6 +1,6 @@ from flask import render_template, request, g from flask.helpers import url_for -from typing import Optional +from typing import List, Optional import werkzeug.exceptions import mo @@ -102,6 +102,16 @@ def org_score(round_id: Optional[int] = None, contest_id: Optional[int] = None): results = score.get_sorted_results() messages = score.get_messages() + # Pro tvorbu odkazů na správné contesty ve výsledkovkách dělených kol + all_subcontests: List[db.Contest] = sess.query(db.Contest).filter( + db.Contest.round_id.in_( + sess.query(db.Round.round_id).filter_by(master_round_id=round.master_round_id) + ) + ).all() + subcontest_id_map = {} + for subcontest in all_subcontests: + subcontest_id_map[(subcontest.round_id, subcontest.master_contest_id)] = subcontest.contest_id + # Construct columns is_export = (format != "") columns = [] @@ -123,13 +133,14 @@ def org_score(round_id: Optional[int] = None, contest_id: Optional[int] = None): for task in tasks: title = task.code if contest_id: + local_ct_id = subcontest_id_map[(task.round_id, contest.master_contest_id)] title = '<a href="{}">{}</a>'.format( - url_for('org_contest_task', contest_id=contest_id, task_id=task.task_id), + url_for('org_contest_task', contest_id=local_ct_id, task_id=task.task_id), task.code ) if rr.can_edit_points(round): title += ' <a href="{}" title="Editovat body" class="icon">✎</a>'.format( - url_for('org_contest_task_points', contest_id=contest_id, task_id=task.task_id), + url_for('org_contest_task_points', contest_id=local_ct_id, task_id=task.task_id), ) columns.append(Column(key=f'task_{task.task_id}', name=task.code, title=title)) columns.append(Column(key='total_points', name='celkove_body', title='Celkové body')) @@ -140,13 +151,14 @@ def org_score(round_id: Optional[int] = None, contest_id: Optional[int] = None): for result in results: user, pant, pion = result.user, result.pant, result.pion school = pant.school_place + local_pion_ct_id = subcontest_id_map[(round.round_id, pion.contest_id)] row = Row(keys={ 'order': OrderCell(result.order.place, result.order.span, result.order.continuation), 'winner': 'ano' if result.winner else '', 'successful': 'ano' if result.successful else '', 'user': user, 'email': user.email, - 'participant': cell_pion_link(user, pion.contest_id, user.full_name()), + 'participant': cell_pion_link(user, local_pion_ct_id, user.full_name()), 'contest': CellLink(pion.contest.place.name, url_for('org_contest', id=pion.contest_id)), 'pion_place': pion.place.name, 'school': CellLink(school.name, url_for('org_place', id=school.place_id)), @@ -157,8 +169,9 @@ def org_score(round_id: Optional[int] = None, contest_id: Optional[int] = None): }) sols = result.get_sols_map() for task in tasks: + local_sol_ct_id = subcontest_id_map[(task.round_id, pion.contest_id)] row.keys[f'task_{task.task_id}'] = SolPointsCell( - contest_id=pion.contest_id, user=user, sol=sols.get(task.task_id) + contest_id=local_sol_ct_id, user=user, sol=sols.get(task.task_id) ) if result.winner: row.html_attr = {"class": "winner", "title": "Vítěz"} -- GitLab