diff --git a/mo/web/org_round.py b/mo/web/org_round.py
index 993c0904896bdbc4798f4513c41ae63d4ef3e440..49a50661f5ded388ad2d28ff72e54e477602d33c 100644
--- a/mo/web/org_round.py
+++ b/mo/web/org_round.py
@@ -1,10 +1,12 @@
import decimal
from flask import render_template, g, redirect, url_for, flash, request
import locale
+import flask_wtf.file
from flask_wtf.form import FlaskForm
import bleach
from bleach.sanitizer import ALLOWED_TAGS
import markdown
+import os
from sqlalchemy import func
from sqlalchemy.orm import joinedload
from sqlalchemy.sql.functions import coalesce
@@ -520,6 +522,61 @@ def org_task_statement(id: int):
return mo.web.util.send_task_statement(round)
+class StatementEditForm(FlaskForm):
+ file = flask_wtf.file.FileField("Soubor", render_kw={'autofocus': True})
+ upload = wtforms.SubmitField('Nahrát')
+ delete = wtforms.SubmitField('Smazat')
+
+
+@app.route('/org/contest/r/<int:id>/task-statement/edit', methods=('GET', 'POST'))
+def org_edit_statement(id: int):
+ sess = db.get_session()
+ round, _, rr = get_round_rr(id, Right.manage_round, True)
+
+ def log_changes():
+ if sess.is_modified(round):
+ changes = db.get_object_changes(round)
+ app.logger.info(f"Kolo #{id} změněno, změny: {changes}")
+ mo.util.log(
+ type=db.LogType.round,
+ what=id,
+ details={'action': 'edit', 'changes': changes},
+ )
+
+ form = StatementEditForm()
+ if form.validate_on_submit():
+ if form.upload.data:
+ if form.file.data is not None:
+ file = form.file.data.stream
+ secure_category = werkzeug.utils.secure_filename(round.category)
+ stmt_dir = f'{round.year}-{secure_category}-{round.seq}'
+ full_dir = os.path.join(mo.util.data_dir('statements'), stmt_dir)
+ os.makedirs(full_dir, exist_ok=True)
+ full_name = mo.util.link_to_dir(file.name, full_dir, suffix='.pdf')
+ file_name = os.path.join(stmt_dir, os.path.basename(full_name))
+ app.logger.info(f'Nahráno zadání: {file_name}')
+
+ round.tasks_file = file_name
+ log_changes()
+ sess.commit()
+ flash('Zadání nahráno', 'success')
+ return redirect(url_for('org_round', id=id))
+ else:
+ flash('Vyberte si prosím soubor', 'danger')
+ if form.delete.data:
+ round.tasks_file = None
+ log_changes()
+ sess.commit()
+ flash('Zadání smazáno', 'success')
+ return redirect(url_for('org_round', id=id))
+
+ return render_template(
+ 'org_edit_statement.html',
+ round=round,
+ form=form,
+ )
+
+
class MessageAddForm(FlaskForm):
title = wtforms.StringField('Nadpis', validators=[validators.Required()])
markdown = wtforms.TextAreaField(
diff --git a/mo/web/templates/org_edit_statement.html b/mo/web/templates/org_edit_statement.html
new file mode 100644
index 0000000000000000000000000000000000000000..3f5a3cf06d560096db40821cc50e27b9ac22cfb6
--- /dev/null
+++ b/mo/web/templates/org_edit_statement.html
@@ -0,0 +1,12 @@
+{% extends "base.html" %}
+{% import "bootstrap/wtf.html" as wtf %}
+
+{% block title %}Zadání kola {{ round.round_code() }}{% endblock %}
+{% block breadcrumbs %}
+{{ contest_breadcrumbs(round=round, action="Zadáni") }}
+{% endblock %}
+{% block body %}
+
+{{ wtf.quick_form(form, form_type='horizontal', button_map={'upload': 'primary', 'delete': 'danger'}) }}
+
+{% endblock %}
diff --git a/mo/web/templates/org_round.html b/mo/web/templates/org_round.html
index 9648bb8bc7e1631ede11d568919478d95c7ce82e..7b4e71b75cddecbc7680eb14427f362de328089c 100644
--- a/mo/web/templates/org_round.html
+++ b/mo/web/templates/org_round.html
@@ -77,6 +77,7 @@
{% endif %}
{% if can_manage_round %}
<a class="btn btn-default" href='{{ url_for('org_round_edit', id=round.round_id) }}'>Nastavení a termíny</a>
+ <a class="btn btn-default" href='{{ url_for('org_edit_statement', id=round.round_id) }}'>Zadání</a>
{% endif %}
{% if round.has_messages %}
<a class="btn btn-default" href='{{ url_for('org_round_messages', id=round.round_id) }}'>Zprávičky</a>