Skip to content
Snippets Groups Projects
Commit 765ffd35 authored by Martin Mareš's avatar Martin Mareš
Browse files

Orgové už mohou odevzdávat řešení i opravení

parent 7614a61e
Branches
No related tags found
1 merge request!9WIP: Zárodek uživatelské části webu a submitování
...@@ -515,17 +515,81 @@ def get_solution_context(contest_id: int, user_id: int, task_id: int, site_id: O ...@@ -515,17 +515,81 @@ def get_solution_context(contest_id: int, user_id: int, task_id: int, site_id: O
) )
@app.route('/org/contest/c/<int:contest_id>/submit/<int:user_id>/<int:task_id>/') class SubmitForm(FlaskForm):
@app.route('/org/contest/c/<int:contest_id>/site/<int:site_id>/submit/<int:user_id>/<int:task_id>/') file = flask_wtf.file.FileField("Soubor", validators=[flask_wtf.file.FileRequired()])
note = wtforms.TextAreaField("Poznámka")
submit_sol = wtforms.SubmitField('Odevzdat řešení')
submit_fb = wtforms.SubmitField('Odevzdat opravené')
@app.route('/org/contest/c/<int:contest_id>/submit/<int:user_id>/<int:task_id>/', methods=('GET', 'POST'))
@app.route('/org/contest/c/<int:contest_id>/site/<int:site_id>/submit/<int:user_id>/<int:task_id>/', methods=('GET', 'POST'))
def org_submit_list(contest_id: int, user_id: int, task_id: int, site_id: Optional[int] = None): def org_submit_list(contest_id: int, user_id: int, task_id: int, site_id: Optional[int] = None):
sc = get_solution_context(contest_id, user_id, task_id, site_id) sc = get_solution_context(contest_id, user_id, task_id, site_id)
sess = db.get_session()
form: Optional[SubmitForm] = None
if sc.allow_upload_solutions or sc.allow_upload_feedback:
form = SubmitForm()
if not sc.allow_upload_solutions:
del form.submit_sol
if not sc.allow_upload_feedback:
del form.submit_fb
if form.validate_on_submit():
# FIXME: Viz komentář o efektivitě v user_contest_task
tmp_name = secrets.token_hex(16)
tmp_path = os.path.join(app.instance_path, 'tmp', tmp_name)
form.file.data.save(tmp_path)
if sc.allow_upload_solutions and form.submit_sol.data:
type = db.PaperType.solution
elif sc.allow_upload_feedback and form.submit_fb.data:
type = db.PaperType.feedback
else:
raise werkzeug.exceptions.Forbidden()
paper = db.Paper(task=sc.task, for_user_obj=sc.user, uploaded_by_obj=g.user, type=type, note=form.note.data)
submitter = mo.submit.Submitter(instance_path=app.instance_path)
self_url = url_for('org_submit_list', contest_id=contest_id, user_id=user_id, task_id=task_id, site_id=site_id)
try:
submitter.submit_paper(paper, tmp_path)
except mo.submit.SubmitException as e:
flash(f'Chyba: {e}', 'danger')
# FIXME: Tady nemažeme tmpfile, zatím si ho chceme nechat pro analýzu.
return redirect(self_url)
sess.add(paper)
# FIXME: Bylo by hezké použít INSERT ... ON CONFLICT UPDATE
# (SQLAlchemy to umí, ale ne přes ORM, jen core rozhraním)
sol = (sess.query(db.Solution)
.filter_by(user_id=user_id, task_id=task_id)
.with_for_update()
.one_or_none())
if sol is None:
sol = db.Solution(task=sc.task, user=sc.user)
sess.add(sol)
if type == db.PaperType.solution:
sol.last_submit_obj = paper
else:
sol.last_feedback_obj = paper
sess.commit()
if type == db.PaperType.solution:
flash('Řešení odevzdáno', 'success')
else:
flash('Opravené řešení odevzdána', 'success')
return redirect(self_url)
# Najdeme řešení úlohy (nemusí existovat) # Najdeme řešení úlohy (nemusí existovat)
sol = (db.get_session().query(db.Solution) sol = (sess.query(db.Solution)
.filter_by(user_id=user_id, task_id=task_id) .filter_by(user_id=user_id, task_id=task_id)
.one_or_none()) .one_or_none())
papers = (db.get_session().query(db.Paper) papers = (sess.query(db.Paper)
.filter_by(for_user_obj=sc.user, task=sc.task) .filter_by(for_user_obj=sc.user, task=sc.task)
.options(joinedload(db.Paper.uploaded_by_obj)) .options(joinedload(db.Paper.uploaded_by_obj))
.order_by(db.Paper.uploaded_at.desc()) .order_by(db.Paper.uploaded_at.desc())
...@@ -549,6 +613,7 @@ def org_submit_list(contest_id: int, user_id: int, task_id: int, site_id: Option ...@@ -549,6 +613,7 @@ def org_submit_list(contest_id: int, user_id: int, task_id: int, site_id: Option
fb_papers=fb_papers, fb_papers=fb_papers,
for_site=(site_id is not None), for_site=(site_id is not None),
paper_link=paper_link, paper_link=paper_link,
form=form,
) )
... ...
......
...@@ -78,4 +78,12 @@ ...@@ -78,4 +78,12 @@
<p>Žádná. <p>Žádná.
{% endif %} {% endif %}
{% if form %}
<h3>Odevzdávání</h3>
{{ wtf.quick_form(form, form_type='basic', button_map={'submit_sol': 'primary', 'submit_fb': 'success'}) }}
{% endif %}
{% endblock %} {% endblock %}
...@@ -154,7 +154,7 @@ def user_contest_task(contest_id: int, task_id: int): ...@@ -154,7 +154,7 @@ def user_contest_task(contest_id: int, task_id: int):
sess.commit() sess.commit()
flash('Úloha odevzdána', 'success') flash('Řešení odevzdáno', 'success')
return redirect(url_for('user_contest', id=contest_id)) return redirect(url_for('user_contest', id=contest_id))
papers = (sess.query(db.Paper) papers = (sess.query(db.Paper)
... ...
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment