From 05e8f69544113d94919f7c89b594969c3c42d2dd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ji=C5=99=C3=AD=20Setni=C4=8Dka?= <setnicka@seznam.cz>
Date: Mon, 6 Sep 2021 00:37:27 +0200
Subject: [PATCH] =?UTF-8?q?T=C5=99=C3=ADd=C4=9Bn=C3=AD=20sken=C5=AF=20-=20?=
 =?UTF-8?q?p=C5=99epou=C5=BEit=C3=AD=20jobu=20process=5Fscans=20jako=20sor?=
 =?UTF-8?q?t=5Fscans?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Zatím nemá výkonnou část.
---
 db/upgrade-20210906.sql |  3 ++
 mo/db.py                |  1 +
 mo/jobs/protocols.py    | 64 +++++++++++++++++++++++++++++++++++++++++
 mo/web/org_contest.py   |  4 ++-
 4 files changed, 71 insertions(+), 1 deletion(-)
 create mode 100644 db/upgrade-20210906.sql

diff --git a/db/upgrade-20210906.sql b/db/upgrade-20210906.sql
new file mode 100644
index 00000000..e271f258
--- /dev/null
+++ b/db/upgrade-20210906.sql
@@ -0,0 +1,3 @@
+SET ROLE 'mo_osmo';
+
+ALTER TYPE job_type ADD VALUE 'sort_scans';
diff --git a/mo/db.py b/mo/db.py
index 3be34948..19964c40 100644
--- a/mo/db.py
+++ b/mo/db.py
@@ -633,6 +633,7 @@ class JobType(MOEnum):
     upload_feedback = auto()
     create_protocols = auto()
     process_scans = auto()
+    sort_scans = auto()
 
 
 class JobState(MOEnum):
diff --git a/mo/jobs/protocols.py b/mo/jobs/protocols.py
index 1b386d61..f908fc81 100644
--- a/mo/jobs/protocols.py
+++ b/mo/jobs/protocols.py
@@ -353,3 +353,67 @@ def _process_scan_file(args: ScanJobArgs) -> List[ScanJobPage]:
         logger.debug(f'Scan: Strana #{page_nr}: {qr}')
 
     return output
+
+
+#
+# Job sort_scans: Roztřídí nascanované protokoly a založí jednotlivá řešení
+#
+# Je to recyklovaný process_scans job.
+#
+# Vstupní JSON (beze změny z process_scans):
+#        { 'contest_id': ID contestu,
+#          'site_id': ID soutěžního místa nebo none,
+#          'task_ids': [task_id, ...],
+#          'in_files': [názvy vstupních souborů]
+#        }
+#
+# Výstupní JSON:
+#        null
+
+
+def schedule_sort_scans(job_id: int, for_user: db.User) -> int:
+    # Znovupoužijeme starý job, jen mu změníme typ
+    the_job = TheJob(job_id)
+    job = the_job.load()
+    assert job is not None
+
+    sess = db.get_session()
+    contest = sess.query(db.Contest).options(joinedload(db.Contest.round)).get(job.in_json['contest_id'])
+    assert contest is not None
+
+    job.type = db.JobType.sort_scans
+    job.created_at = mo.now
+    job.expires_at = None
+    job.user = for_user
+    job.description = f'Rozdělení již roztříděných scanů {contest.round.round_code_short()}'
+
+    the_job.submit()
+    return the_job.job_id
+
+
+@job_handler(db.JobType.sort_scans)
+def handle_sort_scans(the_job: TheJob):
+    job = the_job.job
+    assert job.in_json is not None
+    contest_id = job.in_json['contest_id']  # type: ignore
+    site_id = job.in_json['site_id']        # type: ignore
+    task_ids = job.in_json['task_ids']      # type: ignore
+    in_files: List[str] = job.in_json['in_files']  # type: ignore
+
+    sess = db.get_session()
+    contest = sess.query(db.Contest).options(joinedload(db.Contest.round)).get(contest_id)
+    assert contest is not None
+    round = contest.round
+    round_code = round.round_code_short()
+
+    user_ids = set(u[0] for u in _get_user_id_query(contest, site_id).all())
+
+    tasks = sess.query(db.Task).filter(db.Task.task_id.in_(task_ids)).all()
+    tasks_by_code = {t.code: t for t in tasks}
+
+    # Jelikož se plánujeme zamyslet na dlouhou dobu, uzavřeme databázovou session.
+    sess.commit()
+
+    # TODO: paralelně rozstříhat a sestavit správná PDFka
+
+    # TODO: založit správná řešení
diff --git a/mo/web/org_contest.py b/mo/web/org_contest.py
index 4260a28d..752cae79 100644
--- a/mo/web/org_contest.py
+++ b/mo/web/org_contest.py
@@ -1901,7 +1901,9 @@ def org_contest_scans_process(ct_id: int, job_id: int, site_id: Optional[int] =
         if len(errors) > 0:
             flash('Nelze zpracovat, dokud kontrola vrací chyby. Nejdříve je opravte.')
             return redirect(self_url)
-        print("PROCESS")
+        mo.jobs.protocols.schedule_sort_scans(job_id, for_user=g.user)
+        flash('Skeny zařazeny pro zpracování, během několika chvil se řešení roztřídí k soutěžícím.', 'success')
+        return redirect(url_for('org_jobs'))
 
     def png_small(page: db.ScanPage) -> str:
         return ctx.url_for(
-- 
GitLab