diff --git a/mo/web/org_contest.py b/mo/web/org_contest.py index 8b0d5edd4a3e56b8ac1aed91cf37c9816a0d3cbb..e3de4f555b02a7873fe5b0f0baa66c2459c49f11 100644 --- a/mo/web/org_contest.py +++ b/mo/web/org_contest.py @@ -633,6 +633,7 @@ class SubmitForm(FlaskForm): file_note = wtforms.TextAreaField("Poznámka k souboru") submit_sol = wtforms.SubmitField('Uložit a nahrát soubor jako řešení') submit_fb = wtforms.SubmitField('Uložit a nahrát soubor jako opravu') + delete = wtforms.SubmitField('Smazat řešení') class SetFinalForm(FlaskForm): @@ -704,6 +705,24 @@ def org_submit_list(contest_id: int, user_id: int, task_id: int, site_id: Option form = SubmitForm(obj=sol) if form.validate_on_submit(): + if sol and form.delete.data: + if sol.final_submit or sol.final_feedback: + flash('Nelze smazat řešení, ke kterému již byl odevzdán soubor', 'danger') + else: + flash('Řešení smazáno', 'success') + sess.delete(sol) + mo.util.log( + type=db.LogType.participant, + what=sc.user.user_id, + details={ + 'action': 'solution-removed', + 'task': task_id, + }, + ) + sess.commit() + app.logger.info(f"Řešení úlohy {sc.task.code} od účastníka {sc.user.user_id} smazáno") + return redirect(self_url) + points = form.points.data # Checks if sol and sc.allow_edit_points and points and points < 0: @@ -713,6 +732,21 @@ def org_submit_list(contest_id: int, user_id: int, task_id: int, site_id: Option flash('Schází soubor k nahrání, žádné změny nebyly uloženy', 'danger') return redirect(self_url) + if not sol and (sc.allow_edit_points or sc.allow_upload_solutions or sc.allow_upload_feedback): + flash('Řešení založeno', 'success') + sol = db.Solution(task=sc.task, user=sc.user) + sess.add(sol) + mo.util.log( + type=db.LogType.participant, + what=sc.user.user_id, + details={ + 'action': 'solution-created', + 'task': task_id, + }, + ) + sess.commit() + app.logger.info(f"Řešení úlohy {sc.task.code} od účastníka {sc.user.user_id} založeno") + # Edit sol and points if sol and sc.allow_edit_points: # Sol edit @@ -768,16 +802,6 @@ def org_submit_list(contest_id: int, user_id: int, task_id: int, site_id: Option 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.final_submit_obj = paper else: diff --git a/mo/web/templates/org_submit_list.html b/mo/web/templates/org_submit_list.html index 37ad2fd414a30dde82d47066507f15307b7f525e..ffb9443ae94574a9eb049d4b57b5b3a75a6e9009 100644 --- a/mo/web/templates/org_submit_list.html +++ b/mo/web/templates/org_submit_list.html @@ -161,44 +161,64 @@ Existuje více než jedna verze oprav, finální je podbarvená. </div> {% else %} -<p>Žádné odevzdané řešení. {% if form %}Můžete ho přidat pomocí formuláře níže.{% endif %} +<p>Žádné odevzdané řešení. {% if form %}Můžete ho založit pomocí formuláře níže.{% endif %} {% endif %} {% if form %} - -<div class="form-frame"> <form method="post" class="form-horizontal" enctype="multipart/form-data"> +<div class="form-frame"> {{ form.csrf_token }} + {% set action = 'Uložit' if solution else 'Založit řešení' %} {% if sc.allow_edit_points %} - <h3 style="margin-top: 10px;">Hodnocení řešení</h3> + {% if solution %} + <h3 style="margin-top: 10px;">Hodnocení řešení</h3> + {% else %} + <h3>Založit řešení</h3> + <p><i>Můžete rovnou vyplnit i poznámky a přidělené body + {%- if sc.allow_upload_feedback or sc.allow_upload_solutions %}, případně rovnou nahrát i soubor řešení nebo opravy{% endif %}. + </i></p> + {% endif %} {{ wtf.form_field(form.note, form_type='horizontal', horizontal_columns=('sm', 2, 10), rows=4)}} {{ wtf.form_field(form.org_note, form_type='horizontal', horizontal_columns=('sm', 2, 10), rows=4 )}} {{ wtf.form_field(form.points, form_type='horizontal', horizontal_columns=('sm', 2, 10) )}} {{ wtf.form_field( form.submit, form_type='horizontal', class='btn btn-primary', horizontal_columns=('sm', 2, 10), - value='Uložit bez nahrání souboru' if sc.allow_upload_feedback or sc.allow_upload_solutions else 'Uložit' + value=action + (' bez nahrání souboru' if sc.allow_upload_feedback or sc.allow_upload_solutions else '') )}} {% endif %} {% if sc.allow_upload_feedback or sc.allow_upload_solutions %} - <h3>Nahrání souboru</h3> - {% if sc.allow_edit_points %} - <p><i>Lze najednou editovat řešení (například zadat body) i nahrát soubor, použijte tlačítka na spodku formuláře.</i></p> + {% if solution %} + <h3>Nahrání souboru</h3> + {% if sc.allow_edit_points %} + <p><i>Lze najednou editovat řešení (například zadat body) i nahrát soubor, použijte tlačítka na spodku formuláře.</i></p> + {% endif %} + {% else %} + <h3>Založit řešení a nahrát soubor</h3> {% endif %} {{ wtf.form_field(form.file, form_type='horizontal', horizontal_columns=('sm', 2, 10)) }} {{ wtf.form_field(form.file_note, form_type='horizontal', horizontal_columns=('sm', 2, 10)) }} <div class="form-group"> <div class="btn btn-group col-sm-offset-2"> {% if sc.allow_upload_solutions %} - {{ wtf.form_field(form.submit_sol, class='btn btn-primary' )}} + {{ wtf.form_field(form.submit_sol, class='btn btn-primary', value=action + ' a nahrát soubor jako řešení' )}} {% endif %} {% if sc.allow_upload_feedback %} - {{ wtf.form_field(form.submit_fb, class='btn btn-success' )}} + {{ wtf.form_field(form.submit_fb, class='btn btn-success', value=action + ' a nahrát soubor jako opravu' )}} {% endif %} </div> </div> {% endif %} -</form> </div> + +{% if solution and not solution.final_submit and not solution.final_feedback and sc.allow_create_solutions %} +<div class="form-frame"> + <h3 style="margin-top: 10px;">Smazání řešení</h3> + <p>Toto řešení zatím neobsahuje žádný soubor. Pokud bylo přidáno omylem, můžete ho smazat.</p> + {{ wtf.form_field(form.delete, class='btn btn-danger') }} +</div> +{% endif %} +</form> + {% endif %} {% endblock %}