diff --git a/mo/web/org_contest.py b/mo/web/org_contest.py
index 9e07c38b5ab73e7ad1290ab1d4e6cd6955498064..909c525553fadde5aa2cdc849e86ce5d277df922 100644
--- a/mo/web/org_contest.py
+++ b/mo/web/org_contest.py
@@ -1328,14 +1328,14 @@ class UploadSubmitsForm(FlaskForm):
     submit = wtforms.SubmitField('Odeslat')
 
 
+@app.route('/org/contest/c/<int:ct_id>/upload', methods=('GET', 'POST'))
+@app.route('/org/contest/c/<int:ct_id>/site/<int:site_id>/upload', methods=('GET', 'POST'))
 @app.route('/org/contest/c/<int:ct_id>/task/<int:task_id>/upload', methods=('GET', 'POST'))
 @app.route('/org/contest/c/<int:ct_id>/site/<int:site_id>/task/<int:task_id>/upload', methods=('GET', 'POST'))
 @app.route('/org/contest/r/<int:round_id>/task/<int:task_id>/upload', methods=('GET', 'POST'))
 @app.route('/org/contest/r/<int:round_id>/h/<int:hier_id>/task/<int:task_id>/upload', methods=('GET', 'POST'))
-def org_generic_batch_upload(task_id: int, round_id: Optional[int] = None, hier_id: Optional[int] = None, ct_id: Optional[int] = None, site_id: Optional[int] = None):
+def org_generic_batch_upload(task_id: Optional[int] = None, round_id: Optional[int] = None, hier_id: Optional[int] = None, ct_id: Optional[int] = None, site_id: Optional[int] = None):
     ctx = get_context(round_id=round_id, hier_id=hier_id, ct_id=ct_id, site_id=site_id, task_id=task_id)
-    task = ctx.task
-    assert task
 
     # Základní kontrola, zda vůbec chceme akci spustit. Zbytek se kontrole uvnitř jobu.
     # Zatím neumíme dávkově nahrávat řešení.
@@ -1349,21 +1349,22 @@ def org_generic_batch_upload(task_id: int, round_id: Optional[int] = None, hier_
     return render_template(
         'org_generic_batch_upload.html',
         ctx=ctx,
-        task=task,
+        task=ctx.task,
         bucket_name=bucket_name, policy=policy,
     )
 
 
+@app.route('/org/contest/c/<int:ct_id>/upload-success', methods=['GET'])
+@app.route('/org/contest/c/<int:ct_id>/site/<int:site_id>/upload-success', methods=['GET'])
 @app.route('/org/contest/c/<int:ct_id>/task/<int:task_id>/upload-success', methods=['GET'])
 @app.route('/org/contest/c/<int:ct_id>/site/<int:site_id>/task/<int:task_id>/upload-success', methods=['GET'])
 @app.route('/org/contest/r/<int:round_id>/task/<int:task_id>/upload-success', methods=['GET'])
 @app.route('/org/contest/r/<int:round_id>/h/<int:hier_id>/task/<int:task_id>/upload-success', methods=['GET'])
-def org_generic_batch_upload_success(task_id: int, round_id: Optional[int] = None, hier_id: Optional[int] = None, ct_id: Optional[int] = None, site_id: Optional[int] = None):
+def org_generic_batch_upload_success(task_id: Optional[int] = None, round_id: Optional[int] = None, hier_id: Optional[int] = None, ct_id: Optional[int] = None, site_id: Optional[int] = None):
     ctx = get_context(round_id=round_id, hier_id=hier_id, ct_id=ct_id, site_id=site_id, task_id=task_id)
-    assert ctx.task is not None
     mo.jobs.submit.schedule_upload_feedback(
             ctx.round, mo.jobs.strip_job_dir(request.args.get('key')),
-            f'Nahrání opravených řešení {ctx.task.code} ({ctx.contest.place.name})',
+            f'Nahrání opravených řešení {ctx.task.code} ({ctx.contest.place.name})' if ctx.task else f'Nahrání opravených řešení pro {ctx.round.name} {ctx.round.category} ({ctx.contest.place.name})',
             for_user=g.user,
             only_contest=ctx.contest, only_site=ctx.site, only_region=ctx.hier_place, only_task=ctx.task)
     return redirect(url_for('org_jobs'))
diff --git a/mo/web/templates/org_contest.html b/mo/web/templates/org_contest.html
index e0dbcf11020ae33710ae9810783826477bd286c1..d5540acd8bed25618a30f1c9e115baedfbdff5fc 100644
--- a/mo/web/templates/org_contest.html
+++ b/mo/web/templates/org_contest.html
@@ -158,6 +158,11 @@
         {% if not site and ((can_view_contestants and state == RoundState.grading) or state == RoundState.closed) %}
         <a class="btn btn-warning" href='{{ ctx.url_for('org_score') }}'><span class="glyphicon glyphicon-bullhorn"></span> Výsledky</a>
         {% endif %}
+        {% if can_upload %}
+        <a class='btn btn-default' href="{{ ctx.url_for('org_generic_batch_upload') }}">
+            <span class="glyphicon glyphicon-cloud-upload"></span> Nahrát ZIP
+        </a>
+        {% endif %}
     </div>
 </div>
 </div>
diff --git a/mo/web/templates/org_contest_solutions.html b/mo/web/templates/org_contest_solutions.html
index a85a2bf5d64b31bc0a9ae56f434455858be61daa..490dd305b00a0bc000fc0b97c2318065a915d4e3 100644
--- a/mo/web/templates/org_contest_solutions.html
+++ b/mo/web/templates/org_contest_solutions.html
@@ -128,7 +128,7 @@ Odkazem v záhlaví se lze dostat na podrobný výpis odevzdání všech účast
 				<a class='btn btn-xs btn-default' href="{{ ctx.url_for('org_generic_batch_download', task_id=task.task_id) }}" title="Stáhnout ZIP řešení úlohy {{ task.code }}"><span class="glyphicon glyphicon-cloud-download"></span></a>
 			<td>
 			{% if rights.can_upload_feedback() %}
-				<a class='btn btn-xs btn-default' href="{{ ctx.url_for('org_generic_batch_upload', task_id=task.task_id) }}" title="Nahrát ZIP opravených řešení úlohy {{ task.code }}"><span class="glyphicon glyphicon-cloud-upload"></span></a>
+				<a class='btn btn-xs btn-default' href="{{ ctx.url_for('org_generic_batch_upload', task_id=task.task_id) }}" title="Nahrát ZIP řešení úlohy {{ task.code }}"><span class="glyphicon glyphicon-cloud-upload"></span></a>
 			{% endif %}
 			<td>
 				{% if edit_points or edit_create %}
diff --git a/mo/web/templates/org_contest_task.html b/mo/web/templates/org_contest_task.html
index beb9fc79c444d8883f3b0721bfaf8a504401b4e0..76904f0cb243d1cac93adfc21d4f8e2b9f93fa41 100644
--- a/mo/web/templates/org_contest_task.html
+++ b/mo/web/templates/org_contest_task.html
@@ -44,9 +44,9 @@
 </form>
 {% else %}
 <p>
-	<a class='btn btn-primary' href="{{ ctx.url_for('org_generic_batch_download') }}"><span class="glyphicon glyphicon-cloud-download"></span> Stáhnout řešení</a>
+	<a class='btn btn-primary' href="{{ ctx.url_for('org_generic_batch_download') }}"><span class="glyphicon glyphicon-cloud-download"></span> Stáhnout ZIP řešení</a>
 	{% if rights.can_upload_feedback() %}
-	<a class='btn btn-primary' href="{{ ctx.url_for('org_generic_batch_upload') }}"><span class="glyphicon glyphicon-cloud-upload"></span> Nahrát ZIP opravených řešení</a>
+	<a class='btn btn-primary' href="{{ ctx.url_for('org_generic_batch_upload') }}"><span class="glyphicon glyphicon-cloud-upload"></span> Nahrát ZIP řešení</a>
 	{% endif %}
 	{% if allow_create_solutions %}
 	<a class="btn btn-primary" href="{{ ctx.url_for('org_contest_task_create') }}">Založit řešení</a>
diff --git a/mo/web/templates/org_generic_batch_upload.html b/mo/web/templates/org_generic_batch_upload.html
index e844b3f48ec79eab898ea8cff64285ad0403703c..82fbf74a531a8141f9f4b3dc8d4879e0376981da 100644
--- a/mo/web/templates/org_generic_batch_upload.html
+++ b/mo/web/templates/org_generic_batch_upload.html
@@ -1,13 +1,13 @@
 {% extends "base.html" %}
 {% import "bootstrap/wtf.html" as wtf %}
 
-{% block title %}Nahrání opravených řešení úlohy {{ task.code }}: {{ task.name }}{% endblock %}
+{% block title %}Nahrání opravených řešení{% if task %} úlohy {{ task.code }}: {{ task.name }}{% endif %}{% endblock %}
 {% block breadcrumbs %}
-{{ ctx.breadcrumbs(action="Nahrání opravených řešení") }}
+{{ ctx.breadcrumbs(action="Nahrát ZIP řešení") }}
 {% endblock %}
 
 {% block body %}
-<p>Zde můžete najednou nahrát více opravených řešení zabalených do souboru typu ZIP.
+<p>Zde můžete nahrát najednou více PDF souborů zabalených do jednoho souboru typu ZIP.
 
 <p>Soubory opravených řešení se musí jmenovat stejně jako původní soubory účastnických řešení.
 Na zařazení souborů do adresářů nezáleží.
@@ -19,8 +19,8 @@ Pokud nahrajete řešení téhož účastníka znovu, uloží se nová verze.
     {% for key, value in policy.items() %}
     <input type="hidden" name="{{ key }}" value="{{ value }}">
     {% endfor %}
-    <div class="form-group required"><label class="control-label" for="file">Soubor</label>
-        <input id="file" name="file" required="" type="file">
+    <div class="form-group required"><label class="control-label" for="file">ZIP soubor</label>
+        <input id="file" name="file" required="" type="file" accept=".zip,application/zip">
     </div>
     <input class="btn btn-primary" type="submit" value="Odeslat">
 </form>