From 35aee9412806044554c1a0f11ec5b9c2e3fc3f90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Setni=C4=8Dka?= <setnicka@seznam.cz> Date: Sat, 9 Jan 2021 04:01:37 +0100 Subject: [PATCH] =?UTF-8?q?=C3=9A=C4=8Dastnick=C3=A1=20=C4=8D=C3=A1st=20we?= =?UTF-8?q?bu=20-=20ukazujeme=20kola=20a=20=C3=BAlohy=20ve=20v=C5=A1ech=20?= =?UTF-8?q?st=C3=A1di=C3=ADch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * připravuje se: Je vidět jen informace o tom, že kolo bude (případně i s datem zveřejnění zadání, pokud je zadané. * běží: Pokud ještě nenastal čas zveřejnění zadání, tak je podobné jako 'připravuje se' jen s jinou zprávou. Jinak zobrazuje vše a umožňuje odevzdávat (a pokud už je po termínu, zobrazuje varování). * opravuje se: Jsou vidět všechny odevzdané úlohy, ale nelze odevzdávat další. * ukončeno: Jako opravuje se, ale v tabulce jsou vidět i body a opravená řešení. Obsahuje FIXME: výsledkovka. --- mo/web/templates/user_contest.html | 59 +++++++++++++++++-------- mo/web/templates/user_contest_task.html | 10 +++-- mo/web/templates/user_index.html | 8 ++-- mo/web/user.py | 18 ++++---- 4 files changed, 59 insertions(+), 36 deletions(-) diff --git a/mo/web/templates/user_contest.html b/mo/web/templates/user_contest.html index b46abb3f..b1412201 100644 --- a/mo/web/templates/user_contest.html +++ b/mo/web/templates/user_contest.html @@ -6,28 +6,52 @@ <h2>{{ round.name }} {{ round.year }}. ročníku kategorie {{ round.category }}: {{ contest.place.name }}</h2> +{% if state == db.RoundState.preparing %} +<p> + Soutěžní kolo se <b>připravuje</b>{% if round.ct_tasks_start and round.ct_tasks_start > g.now %}, + začne <b>{{ round.ct_tasks_start|timeformat }} ({{ human_timedelta(round.ct_tasks_start, g.now) }})</b>{% endif %}. + Až začne, budete mít na této stránce {% if round.has_tasks() %}k dispozici text zadání,{% endif %} + přehled úloh a budete zde moci odevzdat svá řešení k jednotlivým úlohám. + Do té doby zde nenajdete nic jiného. +</p> +{% elif state == db.RoundState.running and not round.can_submit() %} +<p> + Soutěžní kolo <b>je připraveno</b>, ale zatím nelze odevzdávat. Odevzdávání začne + <b>{{ round.ct_tasks_start|timeformat }} ({{ human_timedelta(round.ct_tasks_start, g.now) }})</b>. + Až začne, budete mít na této stránce {% if round.has_tasks() %}k dispozici text zadání,{% endif %} + přehled úloh a budete zde moci odevzdat svá řešení k jednotlivým úlohám. + Do té doby zde nenajdete nic jiného. +</p> +{% else %} {% if state == db.RoundState.running %} -<p>Soutěž běží. - {% if round.ct_submit_end == None %} - Můžete odevzdávat svá řešení. - {% else %} - Svá řešení odevzdávejte do {{ round.ct_submit_end|timeformat }}. - V případě technických problémů můžete odevzdat i později, - ale není zaručeno, že řešení budou hodnocena. - {% endif %} - +<p> +{% if round.ct_submit_end == None %} + Soutěžní kolo běží, <b>můžete odevzdávat svá řešení.</b> +{% elif round.ct_submit_end > g.now %} + Soutěžní kolo běží, <b>svá řešení odevzdávejte do {{ round.ct_submit_end|timeformat }} ({{ human_timedelta(round.ct_submit_end, g.now) }})</b>. + V případě technických problémů můžete odevzdat i později, ale není zaručeno, že řešení budou hodnocena. +{% else %} + Řádný termín soutěžního kola <b>již skončil</b> (v {{ round.ct_submit_end|timeformat }}, {{ human_timedelta(round.ct_submit_end, g.now) }}), + ale stále můžete odevzdat svá řešení, která se vám nepovedla odevzdat kvůli + technickým problémům. Není však zaručeno, že řešení budou hodnocena. +{% endif %} +</p> +{% if round.can_submit() %} <p>Řešení odevzdávejte ve formátu PDF jako soubor o velikosti maximálně {{ max_submit_size // 1048576 }} MB. +{% endif %} {% elif state == db.RoundState.grading %} <p>Odevzdávání bylo ukončeno. Vyčkejte prosím, až úlohy opravíme. {% elif state == db.RoundState.closed %} -<p>FIXME +<p>Soutěžní kolo bylo ukončeno, níže si můžete prohlédnout svá ohodnocená a okomentovaná řešení. + +<p>FIXME výsledkovka {% else %} <p>Soutěž se nachází v neznámém stavu. To by se nemělo stát :) {% endif %} -{% if statement_visible %} +{% if round.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 %} @@ -41,9 +65,8 @@ {% if round.state == db.RoundState.closed %} <th>Opraveno <th>Body - {% else %} - <th>Akce {% endif %} + <th>Akce <tbody> {% for task, sol in task_sols %} <tr> @@ -60,13 +83,13 @@ <td> {% endif %} <td>{{ sol.points if sol.points != None else '–' }} - {% else %} - <td> - {% if round.state == db.RoundState.running %} - <a class='btn btn-xs btn-primary' href='{{ url_for('user_contest_task', contest_id=contest.contest_id, task_id=task.task_id) }}'>Odevzdat</a> - {% endif %} {% endif %} + <td> + <a class='btn btn-xs btn-primary' href='{{ url_for('user_contest_task', contest_id=contest.contest_id, task_id=task.task_id) }}'> + {% if round.can_submit() %}Odevzdat{% else %}Detail úlohy{% endif %} + </a> {% endfor %} </table> +{% endif %} {% endblock %} diff --git a/mo/web/templates/user_contest_task.html b/mo/web/templates/user_contest_task.html index 819f7a11..400ee0e3 100644 --- a/mo/web/templates/user_contest_task.html +++ b/mo/web/templates/user_contest_task.html @@ -7,14 +7,18 @@ <p><a href='{{ url_for('user_contest', id=contest.contest_id) }}'>Zpět na seznam úloh</a> +{% if round.can_submit() %} <h3>Odevzdat řešení</h3> -{% if round.ct_submit_end != None and g.now > round.ct_submit_end %} -<p class="alert alert-danger">Pozor, odevzdáváte po termínu. Vaše řešení nemusí být hodnoceno. -Doporučujeme využít políčko pro komentář a vysvětlit situaci. +{% if round.ct_submit_end and g.now > round.ct_submit_end %} +<p class="alert alert-danger">Pozor, odevzdáváte po termínu (uplynul {{ round.ct_submit_end|timeformat }}, +{{ human_timedelta(round.ct_submit_end) }}). Vaše řešení nemusí být hodnoceno. Doporučujeme využít políčko pro komentář a vysvětlit situaci. {% endif %} {{ wtf.quick_form(form, form_type='basic', button_map={'submit': 'primary'}) }} +{% else %} +<p><i>Soutěžní kolo neběží, již není možné odevzdat nové řešení.</i></p> +{% endif %} <h3>Historie vašich řešení</h3> diff --git a/mo/web/templates/user_index.html b/mo/web/templates/user_index.html index c55c8fa4..be8b2d4b 100644 --- a/mo/web/templates/user_index.html +++ b/mo/web/templates/user_index.html @@ -5,7 +5,7 @@ {% if pions %} <p>Účastníte se následujících kol MO: - <table class=data> + <table class="table"> <thead> <tr> <th title='ročník MO'>Roč. @@ -21,11 +21,9 @@ <td>{{ round.category }} <td>{{ round.name }} <td>{{ contest.place.name }} - <td>{{ round.state.friendly_name() }} + <td>{{ round.long_state() }} <td><div class="btn-group"> - {% if round.state == db.RoundState.running %} - <a class='btn btn-xs btn-primary' href='{{ url_for('user_contest', id=contest.contest_id) }}'>Odevzdávat</a> - {% endif %} + <a class='btn btn-xs btn-primary' href='{{ url_for('user_contest', id=contest.contest_id) }}'>Detail kola</a> </div> {% endfor %} </table> diff --git a/mo/web/user.py b/mo/web/user.py index e1cc7cda..761d1114 100644 --- a/mo/web/user.py +++ b/mo/web/user.py @@ -29,7 +29,6 @@ def user_index(): .join(db.Contest) .join(db.Round) .filter(db.Participation.user == g.user) - .filter(db.Round.state != db.RoundState.preparing) .options(joinedload(db.Contest.place)) .order_by(db.Round.year.desc(), db.Round.category, db.Round.seq) .all()) @@ -50,12 +49,6 @@ def get_contest(id: int) -> db.Contest: if not contest: raise werkzeug.exceptions.NotFound() - # FIXME: Časem chceme účastníky pustit i v jiných stavech - # FIXME: A také místo generického Forbidden říci něco konkrétnějšího - # (je možné, že se sem účastník dostal reloadem stránky po konci contestu) - if contest.round.state != db.RoundState.running: - raise werkzeug.exceptions.Forbidden() - # FIXME: Kontrolovat nějak pion.state? pion = (db.get_session().query(db.Participation) .filter_by(user=g.user, contest=contest) @@ -94,7 +87,6 @@ def user_contest(id: int): 'user_contest.html', contest=contest, task_sols=task_sols, - statement_visible=contest.round.task_statement_available(), max_submit_size=config.MAX_CONTENT_LENGTH, db=db, # kvůli hodnotám enumů ) @@ -104,7 +96,7 @@ def user_contest(id: int): def user_task_statement(id: int): contest = get_contest(id) - if not contest.round.task_statement_available(): + if not contest.round.task_statement_available(mo.now): logger.warn(f'Účastník #{g.user.user_id} chce zadání, na které nemá právo') raise werkzeug.exceptions.Forbidden() @@ -123,8 +115,14 @@ def user_contest_task(contest_id: int, task_id: int): task = get_task(contest, task_id) sess = db.get_session() + round = contest.round + if round.state == db.RoundState.preparing or (round.state == db.RoundState.running and not round.can_submit(mo.now)): + # Dokud se kolo připravuje nebo čeká na zveřejnění zadání, tak ani nezobrazujeme + # stránku, abychom něco neprozradili jménem úlohy + raise werkzeug.exceptions.Forbidden() + form = SubmitForm() - if form.validate_on_submit(): + if round.can_submit(now) and form.validate_on_submit(): # FIXME: Tohle je pomalé, dělá se tu zbytečná další kopie dat. # Nicméně werkzeugu by měla jít podstrčit stream factory, # která bude vyrábět streamy rovnou uložené v našem tmp. -- GitLab