Skip to content
Snippets Groups Projects
Commit d10072e4 authored by Jan Prachař's avatar Jan Prachař
Browse files

Tabulka Moje soutěže

parent 579089c7
No related branches found
No related tags found
No related merge requests found
This commit is part of merge request !65. Comments created here will be created in the context of that merge request.
...@@ -200,28 +200,34 @@ class Rights: ...@@ -200,28 +200,34 @@ class Rights:
# Interní rozhodovaní o dostupnosti zadání # Interní rozhodovaní o dostupnosti zadání
def _check_view_statement(self, round: db.Round): def _check_view_statement(self, round: db.Round) -> tuple[bool, str]:
if round.tasks_file is None: if round.tasks_file is None:
return False return False, "zatím chybí"
if self.have_right(Right.manage_round): if self.have_right(Right.manage_round):
# Správce kola může vždy všechno # Správce kola může vždy všechno
return True return True, ""
# Pokud už soutěž skončila, přístup k zadání má každý org. # Pokud už soutěž skončila, přístup k zadání má každý org.
# XXX: Rozhodujeme podle stavu kola, nikoliv soutěže! # XXX: Rozhodujeme podle stavu kola, nikoliv soutěže!
if round.state in [db.RoundState.grading, db.RoundState.closed]: if round.state in [db.RoundState.grading, db.RoundState.closed]:
return True return True, ""
# Od stanoveného času vidí zadání orgové s právem view_statement. # Od stanoveného času vidí zadání orgové s právem view_statement.
if (self.have_right(Right.view_statement) if (self.have_right(Right.view_statement)):
and round.state != db.RoundState.preparing
and round.pr_tasks_start is not None
and mo.now >= round.pr_tasks_start):
return True
# Ve zbylých případech jsme konzervativní a zadání neukazujeme # Ve zbylých případech jsme konzervativní a zadání neukazujeme
return False if (round.state == db.RoundState.preparing
or round.pr_tasks_start is None):
return False, "až začne soutěž"
if mo.now < round.pr_tasks_start:
return False, mo.util_format.timedelta(round.pr_tasks_start)
return True, ""
if round.state not in [db.RoundState.grading, db.RoundState.closed]:
return False, "až začnou opravy"
return True, ""
class RoundRights(Rights): class RoundRights(Rights):
...@@ -279,6 +285,10 @@ class ContestRights(Rights): ...@@ -279,6 +285,10 @@ class ContestRights(Rights):
or self.have_right(Right.manage_contest)) or self.have_right(Right.manage_contest))
def can_view_statement(self) -> bool: def can_view_statement(self) -> bool:
can, _ = self._check_view_statement(self.contest.round)
return can
def can_view_statement_with_reason(self) -> (bool, str):
return self._check_view_statement(self.contest.round) return self._check_view_statement(self.contest.round)
def cannot_view_statement_reason(self) -> str: def cannot_view_statement_reason(self) -> str:
......
...@@ -30,30 +30,38 @@ def org_index(): ...@@ -30,30 +30,38 @@ def org_index():
flash('ID uživatele musí být číslo', 'danger') flash('ID uživatele musí být číslo', 'danger')
sess = db.get_session() sess = db.get_session()
contests_with_role = sess.execute("""
SELECT contest_id, MIN(role) as role
FROM contests
JOIN user_roles ur USING(place_id)
JOIN rounds r USING(round_id)
JOIN users USING(user_id)
WHERE
user_id = :user_id
AND r.year = :current_year
AND (ur.year IS NULL OR ur.year = r.year)
AND (ur.category IS NULL OR ur.category = r.category)
AND (ur.seq IS NULL OR ur.seq = r.seq)
GROUP BY contest_id, r.level, r.category, place_id, r.seq, r.part
ORDER BY r.level, r.category, place_id, r.seq, r.part
""", {'user_id': g.user.user_id, 'current_year': mo.current_year})
roles = (sess.query(db.UserRole) contest_ids = []
.filter_by(user_id=g.user.user_id) roles = []
.options(joinedload(db.UserRole.place)) for row in contests_with_role:
.all()) contest_ids.append(row['contest_id'])
roles.append(row['role'])
contests = [] contests = (sess.query(db.Contest)
for role in roles:
q = (sess.query(db.Contest, db.UserRole.role, db.Round)
.select_from(db.Contest) .select_from(db.Contest)
.filter_by(place_id=role.place_id) .join(db.Round)
.join(db.UserRole, db.UserRole.user_role_id == role.user_role_id) .filter(db.Contest.contest_id.in_(contest_ids))
.join(db.Round)) .options(joinedload(db.Contest.place))
if role.year: .order_by(db.Round.level, db.Round.category, db.Contest.place_id,
q = q.filter(db.Round.year == role.year) db.Round.seq, db.Round.part)
if role.category: .all())
q = q.filter(db.Round.category == role.category)
if role.seq:
q = q.filter(db.Round.seq == role.seq)
contests += q.options(joinedload(db.Contest.place)).all()
contests.sort(key=lambda r: (r[2].year, r[2].category, r[2].seq, r[2].part))
return render_template('org_index.html', contests=contests, Right=Right, return render_template('org_index.html', contests=zip(contests, roles), Right=Right,
role_names=db.role_type_names, gatekeeper=g.gatekeeper) role_names=db.role_type_names, gatekeeper=g.gatekeeper)
......
...@@ -6,46 +6,44 @@ ...@@ -6,46 +6,44 @@
<h3>Moje soutěže</h3> <h3>Moje soutěže</h3>
<table class="table table-bordered"> <table class="table table-bordered">
{% set curr = namespace(level = -1) %}
{% for c, role in contests %}
{% set cr = gatekeeper.rights_for_contest(c) %}
{% if curr.level != c.round.level %}
<thead><tr> <thead><tr>
<th>Kategorie <th>Kategorie
<th>Kolo <th>Kolo
<th>{{ c.round.get_level().name|capitalize }}
<th>Stav <th>Stav
<th>Zadání <th>Zadání
<th>Moje role <th>Moje role
<th>Odkazy <th>Odkazy
</thead> </thead>
{% for c,role,r in contests %} {% set curr.level = c.round.level %}
{% set rr = gatekeeper.rights_for_contest(c) %}
{% if c.state == RoundState.preparing %}
<tr class="warning">
{% elif c.state == RoundState.running %}
<tr class="success">
{% elif c.state == RoundState.grading %}
<tr class="info">
{% else %}
<tr>
{% endif %} {% endif %}
<td class="text-center" style="font-size: 1.2em"><b>{{ r.category }}</b> <tr class="rstate-{{c.state.name}}">
<td>{{ r.name }} {{ c.place.name_locativ() if c.place.level > 0 else '' }} <td class="text-center"><b>{{ c.round.category }}</b>
<td>{{ c.round.name }}
<td>{{ c.place.name }}
<td>{{ c.state.friendly_name() }} <td>{{ c.state.friendly_name() }}
<td> <td>
{% if rr.can_view_statement() %} {% set can, reason = cr.can_view_statement_with_reason() %}
<a href='{{ url_for('org_task_statement', id=r.round_id) }}'>stáhnout</a> {% if can %}
<a href='{{ url_for('org_task_statement', id=c.round_id) }}'>stáhnout</a>
{% else %} {% else %}
{{ rr.cannot_view_statement_reason() }} {{ reason }}
{% endif %} {% endif %}
<td>{{ role_names[role] }} <td>{{ role_names[role] }}
<td> <td>
<a class="btn btn-xs btn-primary" href='{{ url_for('org_contest', id=c.contest_id) }}'>Detail</a> <a class="btn btn-xs btn-primary" href='{{ url_for('org_contest', id=c.contest_id) }}'>Detail</a>
<a class="btn btn-xs btn-default" href='{{ url_for('org_contest_list', id=c.contest_id) }}'>Účastníci</a> <a class="btn btn-xs btn-default" href='{{ url_for('org_contest_list', id=c.contest_id) }}'>Účastníci</a>
{% if rr.can_view_submits() and c.state != RoundState.preparing %} {% if cr.have_right(Right.view_submits) and c.state != RoundState.preparing %}
<a class="btn btn-xs btn-success" href='{{ url_for('org_contest_solutions', id=c.contest_id) }}'>Odevzdaná řešení</a> <a class="btn btn-xs btn-success" href='{{ url_for('org_contest_solutions', id=c.contest_id) }}'>Odevzdaná řešení</a>
{% endif %} {% endif %}
{% if (c.state == RoundState.grading and rr.can_view_submits()) or c.state == RoundState.closed %} {% if (c.state == RoundState.grading and cr.have_right(Right.view_submits)) or c.state == RoundState.closed %}
<a class="btn btn-xs btn-warning" href='{{ url_for('org_score', contest_id=c.contest_id) }}'>Výsledky</a> <a class="btn btn-xs btn-warning" href='{{ url_for('org_score', contest_id=c.contest_id) }}'>Výsledky</a>
{% endif %} {% endif %}
{% if rr.have_right(Right.manage_contest) and c.state != RoundState.closed %} {% if cr.have_right(Right.manage_contest) and c.state == RoundState.preparing %}
<a class="btn btn-xs btn-primary" href='{{ url_for('org_contest_add_user', id=c.contest_id) }}'>+ Přidat účastníka</a>
<a class="btn btn-xs btn-default" href='{{ url_for('org_contest_import', id=c.contest_id) }}'>Import</a> <a class="btn btn-xs btn-default" href='{{ url_for('org_contest_import', id=c.contest_id) }}'>Import</a>
{% endif %} {% endif %}
</td> </td>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment