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