Skip to content
Snippets Groups Projects
Commit 889f70fa authored by Jiří Setnička's avatar Jiří Setnička
Browse files

Drobné změny v org části webu související se zavedení částí kol

* importy kontrolují práva podle stavu u RoundPart namísto Round
* job na upload feedbacku bere stav pro kontrolu práv podle round_part_id
  dané úlohy
* soubory se zadáním jsou určeny kombinací Round + RoundPart
parent 09f84305
No related branches found
No related tags found
1 merge request!41Implementace dělených kol pomocí RoundPart
This commit is part of merge request !41. Comments created here will be created in the context of that merge request.
...@@ -670,7 +670,7 @@ class PointsImport(Import): ...@@ -670,7 +670,7 @@ class PointsImport(Import):
return self.error('Soutěžící nesoutěží v této oblasti') return self.error('Soutěžící nesoutěží v této oblasti')
rights = self.gatekeeper.rights_for_contest(pion.contest) rights = self.gatekeeper.rights_for_contest(pion.contest)
if not rights.can_edit_points(self.round): if not rights.can_edit_points(self.task.round_part):
return self.error('Nemáte právo na úpravu bodů') return self.error('Nemáte právo na úpravu bodů')
user = pion.user user = pion.user
...@@ -682,7 +682,7 @@ class PointsImport(Import): ...@@ -682,7 +682,7 @@ class PointsImport(Import):
return return
if not self.allow_add_del: if not self.allow_add_del:
return self.error('Tento soutěžící úlohu neodevzdal') return self.error('Tento soutěžící úlohu neodevzdal')
if not rights.can_upload_solutions(round): if not rights.can_upload_solutions(self.task.round_part):
return self.error('Nemáte právo na zakládání nových řešení') return self.error('Nemáte právo na zakládání nových řešení')
sol = db.Solution(user_id=user_id, task_id=task_id) sol = db.Solution(user_id=user_id, task_id=task_id)
sess.add(sol) sess.add(sol)
...@@ -698,7 +698,7 @@ class PointsImport(Import): ...@@ -698,7 +698,7 @@ class PointsImport(Import):
return self.error('Tento soutěžící úlohu odevzdal') return self.error('Tento soutěžící úlohu odevzdal')
if sol.final_submit is not None or sol.final_feedback is not None: if sol.final_submit is not None or sol.final_feedback is not None:
return self.error('Nelze smazat řešení, ke kterému existují odevzdané soubory') return self.error('Nelze smazat řešení, ke kterému existují odevzdané soubory')
if not rights.can_upload_solutions(round): if not rights.can_upload_solutions(self.task.round_part):
return self.error('Nemáte právo na mazání řešení') return self.error('Nemáte právo na mazání řešení')
logger.info(f'Import: Smazáno řešení user=#{user_id} task=#{task_id}') logger.info(f'Import: Smazáno řešení user=#{user_id} task=#{task_id}')
mo.util.log( mo.util.log(
......
...@@ -227,7 +227,9 @@ def handle_upload_feedback(the_job: TheJob): ...@@ -227,7 +227,9 @@ def handle_upload_feedback(the_job: TheJob):
contest_dict[user.user_id] = contest contest_dict[user.user_id] = contest
site_id_dict[user.user_id] = pion.place_id site_id_dict[user.user_id] = pion.place_id
rr = the_job.gatekeeper.rights_for_contest(contest) rr = the_job.gatekeeper.rights_for_contest(contest)
user_rights[user.user_id] = rr.can_upload_feedback(round) user_rights[user.user_id] = {
part.round_part_id: rr.can_upload_feedback(part) for part in round.parts
}
for f in files: for f in files:
f.user = user_dict[f.user_id] f.user = user_dict[f.user_id]
...@@ -237,8 +239,8 @@ def handle_upload_feedback(the_job: TheJob): ...@@ -237,8 +239,8 @@ def handle_upload_feedback(the_job: TheJob):
the_job.error(f'{f.file_name}: Účastník leží mimo vybranou soutěž') the_job.error(f'{f.file_name}: Účastník leží mimo vybranou soutěž')
elif only_site_id is not None and site_id_dict[f.user_id] != only_site_id: elif only_site_id is not None and site_id_dict[f.user_id] != only_site_id:
the_job.error(f'{f.file_name}: Účastník leží mimo vybrané soutěžní místo') the_job.error(f'{f.file_name}: Účastník leží mimo vybrané soutěžní místo')
elif not user_rights[f.user_id]: elif not user_rights[f.user_id][f.task.round_part_id]:
the_job.error(f'{f.file_name}: K tomuto účastníkovi nemáte dostatečná oprávnění') the_job.error(f'{f.file_name}: K tomuto účastníkovi a úloze nemáte dostatečná oprávnění')
def process_file(fb: UploadFeedback) -> bool: def process_file(fb: UploadFeedback) -> bool:
assert fb.user and fb.task assert fb.user and fb.task
......
...@@ -127,7 +127,7 @@ def org_score(round_id: Optional[int] = None, contest_id: Optional[int] = None): ...@@ -127,7 +127,7 @@ def org_score(round_id: Optional[int] = None, contest_id: Optional[int] = None):
url_for('org_contest_task', contest_id=contest_id, task_id=task.task_id), url_for('org_contest_task', contest_id=contest_id, task_id=task.task_id),
task.code task.code
) )
if rr.can_edit_points(round): if rr.can_edit_points(task.round_part):
title += ' <a href="{}" title="Editovat body" class="icon">✎</a>'.format( 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=contest_id, task_id=task.task_id),
) )
......
...@@ -69,7 +69,7 @@ konkrétní úlohu. Symbol <span class="icon">🗐</span> značí, že existuje ...@@ -69,7 +69,7 @@ konkrétní úlohu. Symbol <span class="icon">🗐</span> značí, že existuje
{% set sol = tasks_sols[task.task_id][u.user_id] %} {% set sol = tasks_sols[task.task_id][u.user_id] %}
{% if sol.final_submit_obj %} {% if sol.final_submit_obj %}
{% set p = sol.final_submit_obj %} {% set p = sol.final_submit_obj %}
{% set late = p.check_deadline(round) %} {% set late = p.check_deadline(task.round_part) %}
<td class="sol{% if late or p.broken %} sol-warn{% endif %}"> <td class="sol{% if late or p.broken %} sol-warn{% endif %}">
<a href="{{ paper_link(u, p) }}" title="{{ p.uploaded_at|timeformat }}{% if p.broken %} - nekorektní PDF{% endif %}{% if p.pages != None %} - {{ p.pages|inflected('stránka', 'stránky', 'stránek') }}{% endif %}{% if late %} - {{ late }}{% endif %}">🖺</a> <a href="{{ paper_link(u, p) }}" title="{{ p.uploaded_at|timeformat }}{% if p.broken %} - nekorektní PDF{% endif %}{% if p.pages != None %} - {{ p.pages|inflected('stránka', 'stránky', 'stránek') }}{% endif %}{% if late %} - {{ late }}{% endif %}">🖺</a>
{% set key = (u.user_id, task.task_id, "solution") %} {% set key = (u.user_id, task.task_id, "solution") %}
......
...@@ -61,7 +61,7 @@ Existuje více než jedna verze řešení, finální je podbarvená. ...@@ -61,7 +61,7 @@ Existuje více než jedna verze řešení, finální je podbarvená.
{% set active_sol_id = None %} {% set active_sol_id = None %}
{% endif %} {% endif %}
{% for p in sol_papers %} {% for p in sol_papers %}
{% set late = p.check_deadline(sc.round) %} {% set late = p.check_deadline(sc.task.round_part) %}
<tr{% if p.paper_id == active_sol_id %} class='sol-active'{% endif %}> <tr{% if p.paper_id == active_sol_id %} class='sol-active'{% endif %}>
<td{% if late %} class='sol-warn'{% endif %}>{{ p.uploaded_at|timeformat }} <td{% if late %} class='sol-warn'{% endif %}>{{ p.uploaded_at|timeformat }}
<td>{% if p.broken %}nekorektní PDF{% else %}{{ p.pages|or_dash }}{% endif %} <td>{% if p.broken %}nekorektní PDF{% else %}{{ p.pages|or_dash }}{% endif %}
......
...@@ -47,7 +47,7 @@ finální (ve výchozím stavu poslední nahrané).{% elif sc.allow_upload_solut ...@@ -47,7 +47,7 @@ finální (ve výchozím stavu poslední nahrané).{% elif sc.allow_upload_solut
{% if sol %} {% if sol %}
<td>{% if sol.final_submit_obj %} <td>{% if sol.final_submit_obj %}
{% set p = sol.final_submit_obj %} {% set p = sol.final_submit_obj %}
{% set late = p.check_deadline(round) %} {% set late = p.check_deadline(task.round_part) %}
{% if late %}<span class='sol-warn icon' title="{{ late }}"></span>{% endif %} {% if late %}<span class='sol-warn icon' title="{{ late }}"></span>{% endif %}
<a href='{{ paper_link(u, p) }}'> <a href='{{ paper_link(u, p) }}'>
{{- p.uploaded_at|timeformat }} {{- p.uploaded_at|timeformat }}
......
...@@ -85,15 +85,19 @@ def user_contest(id: int): ...@@ -85,15 +85,19 @@ def user_contest(id: int):
) )
@app.route('/user/contest/<int:id>/task-statement/zadani.pdf') @app.route('/user/contest/<int:id>/part/<int:part_id>/task-statement/zadani.pdf')
def user_task_statement(id: int): def user_task_statement(id: int, part_id: int):
contest = get_contest(id) contest = get_contest(id)
if not contest.round.task_statement_available(): round_part = db.get_session().query(db.RoundPart).get(part_id)
if not round_part or round_part.round_id != contest.round_id:
raise werkzeug.exceptions.NotFound()
if not round_part.task_statement_available():
logger.warn(f'Účastník #{g.user.user_id} chce zadání, na které nemá právo') logger.warn(f'Účastník #{g.user.user_id} chce zadání, na které nemá právo')
raise werkzeug.exceptions.Forbidden() raise werkzeug.exceptions.Forbidden()
return mo.web.util.send_task_statement(contest.round) return mo.web.util.send_task_statement(round_part)
class SubmitForm(FlaskForm): class SubmitForm(FlaskForm):
......
...@@ -40,9 +40,9 @@ class PagerForm(FlaskForm): ...@@ -40,9 +40,9 @@ class PagerForm(FlaskForm):
return (count, query) return (count, query)
def send_task_statement(round: db.Round) -> Response: def send_task_statement(round_part: db.RoundPart) -> Response:
assert round.tasks_file is not None assert round_part.tasks_file is not None
file = os.path.join(mo.util.data_dir('statements'), round.tasks_file) file = os.path.join(mo.util.data_dir('statements'), round_part.tasks_file)
if os.path.isfile(file): if os.path.isfile(file):
return send_file(file, mimetype='application/pdf') return send_file(file, mimetype='application/pdf')
else: else:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment