From f3bb158690d1f3e3e780645ddfb1d7a3908e7ec3 Mon Sep 17 00:00:00 2001
From: Martin Mares <mj@ucw.cz>
Date: Sat, 25 Sep 2021 16:41:45 +0200
Subject: [PATCH] =?UTF-8?q?Jobs:=20Joby=20na=20pr=C3=A1ci=20se=20submity?=
 =?UTF-8?q?=20p=C5=99ed=C4=9Bl=C3=A1ny=20na=20nov=C3=A9=20rozhran=C3=AD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 mo/jobs/submit.py     | 26 +++++++++++++++-----------
 mo/web/org_contest.py |  7 ++++---
 2 files changed, 19 insertions(+), 14 deletions(-)

diff --git a/mo/jobs/submit.py b/mo/jobs/submit.py
index ba937cab..136d17f0 100644
--- a/mo/jobs/submit.py
+++ b/mo/jobs/submit.py
@@ -13,7 +13,7 @@ import werkzeug.utils
 import zipfile
 
 import mo.db as db
-from mo.jobs import TheJob, job_handler, job_file_path
+from mo.jobs import TheJob, job_handler
 from mo.submit import Submitter, SubmitException
 from mo.util import logger, data_dir
 from mo.util_format import inflect_number, inflect_by_number, data_size
@@ -25,6 +25,7 @@ from mo.util_format import inflect_number, inflect_by_number, data_size
 # Vstupní JSON:
 #        { 'papers': [ seznam paper_id ke stažení ],
 #          'want_feedback': true/false,
+#          'out_name': jméno výstupního souboru bez přípony,
 #        }
 #
 # Výstupní JSON:
@@ -32,11 +33,11 @@ from mo.util_format import inflect_number, inflect_by_number, data_size
 #
 
 
-def schedule_download_submits(paper_ids: List[int], description: str, for_user: db.User, want_subdirs: bool):
+def schedule_download_submits(paper_ids: List[int], description: str, for_user: db.User, want_subdirs: bool, out_name: str):
     the_job = TheJob()
     job = the_job.create(db.JobType.download_submits, for_user)
     job.description = description
-    job.in_json = {'papers': paper_ids, 'want_subdirs': want_subdirs}
+    job.in_json = {'papers': paper_ids, 'want_subdirs': want_subdirs, 'out_name': out_name}
     the_job.submit()
 
 
@@ -46,6 +47,7 @@ def handle_download_submits(the_job: TheJob):
     assert job.in_json is not None
     ids: List[int] = job.in_json['papers']  # type: ignore
     want_subdirs: bool = job.in_json['want_subdirs']  # type: ignore
+    out_name: str = job.in_json['out_name']  # type: ignore
 
     sess = db.get_session()
     papers = (sess.query(db.Paper, db.User, db.Task.code, db.Place)
@@ -59,11 +61,13 @@ def handle_download_submits(the_job: TheJob):
               .all())
     papers.sort(key=lambda p: (p[1].sort_key(), p[2]))
 
-    temp_file = NamedTemporaryFile(suffix='.zip', dir=data_dir('tmp'), mode='w+b')
-    logger.debug('Job: Vytvářím archiv %s', temp_file.name)
+    out_name = werkzeug.utils.secure_filename(out_name + '.zip')
+    out_path = job.file_path(out_name)
+    out_file = open(out_path, mode='w+b')
+    logger.debug('Job: Vytvářím archiv %s', out_path)
 
     cnt = 0
-    with zipfile.ZipFile(temp_file, mode='w') as zip:
+    with zipfile.ZipFile(out_file, mode='w') as zip:
         for p, u, task_code, place in papers:
             cnt += 1
             full_name = u.full_name()
@@ -78,10 +82,10 @@ def handle_download_submits(the_job: TheJob):
             zip.write(filename=os.path.join(data_dir('submits'), p.file_name or p.orig_file_name),
                       arcname=fn)
 
-    job.out_file = the_job.attach_file(temp_file.name, '.zip')
-    out_size = temp_file.tell()
+    job.out_file = out_name
+    out_size = out_file.tell()
     job.result = 'Celkem ' + inflect_number(cnt, 'soubor', 'soubory', 'souborů') + ', ' + data_size(out_size)
-    temp_file.close()
+    out_file.close()
 
 
 #
@@ -114,7 +118,7 @@ def schedule_upload_feedback(round: db.Round, tmp_file: str, description: str, f
         'only_region_id': only_region.place_id if only_region is not None else None,
         'only_task_id': only_task.task_id if only_task is not None else None,
     }
-    job.in_file = the_job.attach_file(tmp_file, '.zip')
+    job.in_file = the_job.attach_file(tmp_file, 'upload.zip')
     the_job.submit()
 
 
@@ -284,7 +288,7 @@ def handle_upload_feedback(the_job: TheJob):
             return False
 
     cnt_good = 0
-    parse_zip(job_file_path(job.in_file))
+    parse_zip(job.file_path(job.in_file))
 
     if not the_job.errors:
         resolve_tasks(files)
diff --git a/mo/web/org_contest.py b/mo/web/org_contest.py
index 823c12bb..7bf4996b 100644
--- a/mo/web/org_contest.py
+++ b/mo/web/org_contest.py
@@ -1163,7 +1163,7 @@ class DownloadSubmitsForm(FlaskForm):
     download_fb_mix = wtforms.SubmitField('Stáhnout opravená/účastnická')
 
 
-def download_submits(form: DownloadSubmitsForm, round: db.Round, sol_query, pion_query, subj_suffix: str, want_subdirs: bool) -> bool:
+def download_submits(form: DownloadSubmitsForm, round: db.Round, sol_query, pion_query, out_name: str, subj_suffix: str, want_subdirs: bool) -> bool:
     if not form.validate_on_submit():
         return False
 
@@ -1196,7 +1196,7 @@ def download_submits(form: DownloadSubmitsForm, round: db.Round, sol_query, pion
         return False
 
     paper_ids = [p for p in paper_ids if p is not None]
-    mo.jobs.submit.schedule_download_submits(paper_ids, f'{subj_prefix} {subj_suffix}', g.user, want_subdirs)
+    mo.jobs.submit.schedule_download_submits(paper_ids, f'{subj_prefix} {subj_suffix}', g.user, want_subdirs, out_name)
     flash('Příprava řešení ke stažení zahájena.', 'success')
     return True
 
@@ -1236,7 +1236,8 @@ def org_generic_batch_download(task_id: int, round_id: Optional[int] = None, hie
             subj = f'{subj} ({contest.place.name})'
         elif hier_place is not None:
             subj = f'{subj} ({hier_place.name})'
-        if download_submits(form, round, sol_query, pion_query, subj, contest is None):
+        out_name = f'reseni_{task.code}'
+        if download_submits(form, round, sol_query, pion_query, out_name, subj, contest is None):
             return redirect(url_for('org_jobs'))
 
     sol_paper = aliased(db.Paper)
-- 
GitLab