diff --git a/mo/web/org_round.py b/mo/web/org_round.py index 5de37170833f01334ee05a88014203117fa7282d..e6fa946d32ebd1382b2857cb1a47961035a241bf 100644 --- a/mo/web/org_round.py +++ b/mo/web/org_round.py @@ -8,13 +8,11 @@ import bleach from bleach.sanitizer import ALLOWED_TAGS import markdown import os -from sqlalchemy import func -from sqlalchemy.orm import joinedload, aliased -from sqlalchemy.sql.functions import coalesce +from sqlalchemy.orm import joinedload from typing import Optional, List, Dict, Tuple, Set import werkzeug.exceptions import wtforms -from wtforms import validators, ValidationError +from wtforms import validators from wtforms.widgets.html5 import NumberInput import mo.config as config diff --git a/mo/web/templates/org_contest.html b/mo/web/templates/org_contest.html index 6f1368e3279030f0c9a58cadc0af97d281fadf00..26b89926611180c01e836d31a0b58e21bd7e4358 100644 --- a/mo/web/templates/org_contest.html +++ b/mo/web/templates/org_contest.html @@ -49,7 +49,7 @@ {% else %} – {% endif %} -{% if state in [RoundState.grading, RoundState.closed] %} +{% if state in [RoundState.grading, RoundState.graded, RoundState.closed] %} <tr><td>Oficiální výsledková listina<td> {% if contest.scoretable %}<a href="{{ ctx.url_for('org_score_snapshot', scoretable_id=contest.scoretable_id) }}">Zveřejněna</a> {% else %}<i>zatím není</i>{% endif %} @@ -67,7 +67,7 @@ {% if not site and can_manage %} <a class="btn btn-default" href="{{ ctx.url_for('org_contest_add_user') }}">Přidat účastníka</a> {% endif %} - {% if not site and can_view_contestants and state in [RoundState.grading, RoundState.closed] %} + {% if not site and can_view_contestants and state in [RoundState.grading, RoundState.graded, RoundState.closed] %} <a class="btn btn-primary" href='{{ ctx.url_for('org_score') }}'>Výsledky</a> {% endif %} {% if can_upload_anything %} diff --git a/mo/web/templates/org_contest_solutions.html b/mo/web/templates/org_contest_solutions.html index 1a6260d7e54435c6190deb19dfbf1ac4c9a15274..0a39751c69450c01338faa4f6a997a27cfe5bdf9 100644 --- a/mo/web/templates/org_contest_solutions.html +++ b/mo/web/templates/org_contest_solutions.html @@ -14,7 +14,7 @@ {% endblock %} {% block pretitle %} -{% if contest.state in [RoundState.grading, RoundState.closed] %} +{% if contest.state in [RoundState.grading, RoundState.graded, RoundState.closed] %} <div class="btn-group pull-right"> <a class="btn btn-default" href="{{ ctx.url_for('org_score') }}">Výsledky {{ round.get_level().name_genitive() }}</a> <a class="btn btn-default" href="{{ ctx.url_for('org_score', ct_id=None) }}">Výsledky kola</a> diff --git a/mo/web/templates/org_contest_task.html b/mo/web/templates/org_contest_task.html index 250f095c5114b3c4408fac7d2e7b991c961bf1ee..31b2bafd8d151fe59ca2f11330c495416cf6a8cc 100644 --- a/mo/web/templates/org_contest_task.html +++ b/mo/web/templates/org_contest_task.html @@ -14,7 +14,7 @@ {% block pretitle %} <div class="btn-group pull-right"> <a class="btn btn-default" href="{{ ctx.url_for('org_contest_solutions', task_id=None) }}">Všechny úlohy</a> - {% if ctx.contest.state in [RoundState.grading, RoundState.closed] %} + {% if ctx.contest.state in [RoundState.grading, RoundState.graded, RoundState.closed] %} <a class="btn btn-default" href="{{ ctx.url_for('org_score', task_id=None) }}">Výsledky {{ ctx.round.get_level().name_genitive() }}</a> <a class="btn btn-default" href="{{ ctx.url_for('org_score', ct_id=None, task_id=None) }}">Výsledky kola</a> {% endif %} diff --git a/mo/web/templates/org_round.html b/mo/web/templates/org_round.html index 13c3934eff0c1e65b7cfde135f980db7f4bdcc99..27106ce098b8a98428e3945941020ab91aa6eb2d 100644 --- a/mo/web/templates/org_round.html +++ b/mo/web/templates/org_round.html @@ -88,7 +88,7 @@ {% if can_view_contestants %} <a class="btn btn-primary" href='{{ ctx.url_for('org_generic_list') }}'>Seznam účastníků</a> {% endif %} - {% if can_view_contestants and round.state in [RoundState.grading, RoundState.closed, RoundState.delegate] %} + {% if can_view_contestants and round.state in [RoundState.grading, RoundState.graded, RoundState.closed, RoundState.delegate] %} <a class="btn btn-primary" href='{{ ctx.url_for('org_score') }}'>Výsledky</a> {% endif %} {% if can_manage_contest %} diff --git a/mo/web/templates/user_contest.html b/mo/web/templates/user_contest.html index 805ce489af24046c76510183724317db01f144cd..4157c5107ab8c9829715e532e234e69974a5d768 100644 --- a/mo/web/templates/user_contest.html +++ b/mo/web/templates/user_contest.html @@ -4,7 +4,7 @@ {% set state = contest.ct_state() %} {% block head %} -{% if contest.round.has_messages %} +{% if round.has_messages %} <script src="{{ asset_url('js/news-reloader.js') }}" type="text/javascript"></script> {% endif %} {% endblock %} @@ -69,29 +69,33 @@ Pokud si s tvorbou PDF nevíte rady, zkuste se podívat do <a href='https://docs {% elif state == RoundState.grading %} <p>Odevzdávání bylo ukončeno. Vyčkejte prosím, až úlohy opravíme. -{% elif state == RoundState.closed %} +{% elif state in [RoundState.graded, RoundState.closed] %} <p>Soutěžní kolo bylo ukončeno, níže si můžete prohlédnout svá ohodnocená a okomentovaná řešení. -{% if contest.ct_state() == RoundState.closed and contest.scoretable_id %} +{% if contest.scoretable_id %} Také je již zveřejněna <strong><a href="{{ url_for('user_contest_score', id=contest.contest_id) }}">výsledková listina</a></strong>. {% endif %} +<p>Během několika dnů očekávejte uzavření kola{% if not contest.scoretable_id %}a zveřejnění oficiálních výsledkových listin{% endif %}. +{% if state == RoundState.graded %} +<p>Pokud máte k opravě úloh připomínky, ozvěte se prosím organizátorům tohoto kola. +{% endif %} {% else %} <p>Soutěž se nachází v neznámém stavu. To by se nemělo stát :) {% endif %} {% if state != RoundState.preparing %} +<h3>Úlohy</h3> + {% if contest.ct_task_statement_available() %} <p>Můžete si stáhnout <a href='{{ url_for('user_task_statement', id=contest.contest_id) }}'>zadání úloh</a>. {% endif %} -<h3>Úlohy</h3> - <table class="table table-bordered table-hover"> <thead> <tr> <th>Úloha <th>Odevzdáno - {% if state == RoundState.closed %} + {% if state in [RoundState.graded, RoundState.closed] %} <th>Opraveno <th>Body {% endif %} @@ -112,7 +116,7 @@ Také je již zveřejněna <strong><a href="{{ url_for('user_contest_score', id= {% else %} <td> {% endif %} - {% if state == RoundState.closed %} + {% if state in [RoundState.graded, RoundState.closed] %} <td> {% if sol.final_feedback_obj %} <a href='{{ url_for('user_paper', contest_id=contest.contest_id, paper_id=sol.final_feedback_obj.paper_id) }}'> diff --git a/mo/web/templates/user_contest_task.html b/mo/web/templates/user_contest_task.html index dfb63792cc85ff5f0de2648a75644d3ac892b339..1d4676a1f34ec1e5bc9dc77841b0a159b79c521b 100644 --- a/mo/web/templates/user_contest_task.html +++ b/mo/web/templates/user_contest_task.html @@ -58,7 +58,7 @@ <p>Žádné řešení k této úloze nebylo odevzdáno.</p> {% elif state == RoundState.grading %} <p>Odevzdávání bylo ukončeno. Vyčkejte prosím, až úlohu opravíme. -{% elif state == RoundState.closed %} +{% elif state in [RoundState.graded, RoundState.closed] %} <h3>Výsledky</h3> <p>Soutěžní kolo bylo ukončeno a úloha opravena a ohodnocena. @@ -80,7 +80,7 @@ <h3>Historie vašich řešení</h3> {% if papers %} - {% if state == RoundState.closed and papers|length > 1 %} + {% if state in [RoundState.graded, RoundState.closed] and papers|length > 1 %} <p>Podbarvením je zvýrazněno řešení, podle kterého vám byly přiděleny body.</p> {% endif %} @@ -95,7 +95,7 @@ <th>Akce <tbody> {% for p in papers %} - <tr{% if state == RoundState.closed and papers|length > 1 and p.paper_id == sol.final_submit %} class="sol-active"{% endif %}> + <tr{% if state in [RoundState.graded, RoundState.closed] and papers|length > 1 and p.paper_id == sol.final_submit %} class="sol-active"{% endif %}> <td>{{ p.uploaded_at|timeformat }} <td>{% if p.is_broken() %}nekorektní PDF{% else %}{{ p.pages|or_dash }}{% endif %} <td>{{ p.bytes|or_dash }} diff --git a/mo/web/templates/user_index.html b/mo/web/templates/user_index.html index fb74e4d25a2f8e8aef69c16fa042efa3b5a74d65..997b4302c07fbea71dde6201c169c38a238757ff 100644 --- a/mo/web/templates/user_index.html +++ b/mo/web/templates/user_index.html @@ -30,13 +30,13 @@ Odevzdat řešení {% elif state == RoundState.grading %} Odevzdaná řešení - {% elif state == RoundState.closed %} + {% elif state in [RoundState.graded, RoundState.closed] %} Prohlédnout opravy {% else %} Detail kola {% endif %} </a> - {% if contest.ct_state() == RoundState.closed and contest.scoretable_id %} + {% if contest.ct_state() in [RoundState.graded, RoundState.closed] and contest.scoretable_id %} <a class='btn btn-xs btn-success' href="{{ url_for('user_contest_score', id=contest.contest_id) }}">Výsledková listina</a> {% endif %} {% endfor %} diff --git a/mo/web/user.py b/mo/web/user.py index 62a88d5cfcca82ab32ac5e0b5e951fbddf28be09..93a21b40311aeee80e6907b26473885636835e00 100644 --- a/mo/web/user.py +++ b/mo/web/user.py @@ -479,9 +479,9 @@ def user_paper(contest_id: int, paper_id: int): raise werkzeug.exceptions.Forbidden() if paper.type == db.PaperType.solution: - allowed_states = [db.RoundState.running, db.RoundState.grading, db.RoundState.closed] + allowed_states = [db.RoundState.running, db.RoundState.grading, db.RoundState.graded, db.RoundState.closed] elif paper.type == db.PaperType.feedback: - allowed_states = [db.RoundState.closed] + allowed_states = [db.RoundState.graded, db.RoundState.closed] else: assert False @@ -541,7 +541,7 @@ def user_contest_score(id: int): # Výsledkovku zobrazíme jen pokud je soutěž již ukončená state = contest.ct_state() - if not contest.scoretable or state != db.RoundState.closed: + if not contest.scoretable or state not in [db.RoundState.graded, db.RoundState.closed]: raise werkzeug.exceptions.NotFound() columns, table_rows = scoretable_construct(contest.scoretable, format != "")