diff --git a/mo/jobs/submit.py b/mo/jobs/submit.py index 9ae525e5d208af7e3fba27c9b46279c00cf12dd8..0fca647803c37c0292e6d35ce36245ad4017358f 100644 --- a/mo/jobs/submit.py +++ b/mo/jobs/submit.py @@ -1,17 +1,71 @@ # Implementace jobů pracujících se submity -from mo.util import logger +import os +from sqlalchemy.orm import joinedload +from tempfile import NamedTemporaryFile +from typing import List +import unicodedata +import werkzeug.utils +import zipfile + +from mo.util import logger, data_dir import mo.db as db from mo.jobs import TheJob, job_handler +def schedule_download_submits(paper_ids: List[int], description: str, for_user: db.User): + tj = TheJob() + job = tj.create(db.JobType.download_submits, for_user) + job.description = description + job.in_json = {'papers': paper_ids} + tj.submit() + + @job_handler(db.JobType.download_submits) def handle_download_submits(tj: TheJob): - logger.debug('Entering download_submits') - pass + """Zazipuje zadané papíry. + + Vstupní JSON: + { 'papers': [ seznam paper_id ke stažení ] } + + Výstupní JSON: + null + """ + + job = tj.job + assert job.in_json is not None + # FIXME: Typování JSONu... + ids = job.in_json['papers'] + + sess = db.get_session() + papers = (sess.query(db.Paper) + .filter(db.Paper.paper_id.in_(ids)) + .options(joinedload(db.Paper.for_user_obj), + joinedload(db.Paper.task)) + .all()) + + temp_file = NamedTemporaryFile(suffix='.zip', dir=data_dir('tmp'), mode='w+b') + logger.debug('Job: Vytvářím archiv %s', temp_file.name) + # FIXME: Setřídit soubory + + cnt = 0 + with zipfile.ZipFile(temp_file, mode='w') as zip: + for p in papers: + cnt += 1 + full_name = p.for_user_obj.full_name() + ascii_name = (unicodedata.normalize('NFD', full_name) + .encode('ascii', 'ignore') + .decode('utf-8')) + fn = f'{p.task.code}_{cnt:04d}_{p.for_user}_{p.paper_id}_{ascii_name}.pdf' + fn = werkzeug.utils.secure_filename(fn) + logger.debug('Job: Přidávám %s', fn) + zip.write(filename=os.path.join(data_dir('submits'), p.file_name), + arcname=fn) + + job.out_file = tj.attach_file(temp_file.name, '.zip') + temp_file.close() @job_handler(db.JobType.upload_feedback) def handle_upload_feedback(tj: TheJob): - logger.debug('Entering upload_feedback') - pass + raise NotImplementedError()