Skip to content
Snippets Groups Projects

Generování protokolů a zpracování scanů

Merged Martin Mareš requested to merge mj/protokoly into devel
4 files
+ 54
35
Compare changes
  • Side-by-side
  • Inline

Files

  • c3f8387d
    Jobs: Každý job má svůj adresář · c3f8387d
    Martin Mareš authored
    Pro každý job založíme data/jobs/<job_id> a všechny soubory, které
    k jobu patří, ukládáme tam.
    
    Umožní nám to:
    
      (1) Lépe diagnostikovat joby, které skončily chybou, protože
          všechny pracovní soubory zůstanou zachované.
    
      (2) Joby s více výstupními soubory (to bude potřeba pro zpracování scanů).
    
      (3) Hezky pojmenované pracovní (a tím pádem i výstupní) soubory.
+ 28
31
@@ -2,6 +2,7 @@
from datetime import timedelta
import os
import shutil
from sqlalchemy import or_
from typing import Optional, Dict, Callable, List
@@ -19,20 +20,6 @@ def send_notify():
logger.debug('Job: Není komu poslat notifikaci')
def job_file_path(name: str) -> str:
return os.path.join(mo.util.data_dir('jobs'), name)
def job_file_size(name: Optional[str]) -> Optional[int]:
if name is None:
return None
try:
return os.path.getsize(job_file_path(name))
except OSError:
return -1
class TheJob:
"""Job z pohledu Pythonu."""
@@ -52,35 +39,45 @@ class TheJob:
return self.job
def create(self, type: db.JobType, for_user: db.User) -> db.Job:
self.job = db.Job(type=type, state=db.JobState.ready, user=for_user)
return self.job
def attach_file(self, tmp_name: str, suffix: str):
"""Vytvoří hardlink na daný pracovní soubor v adresáři jobů."""
full_name = mo.util.link_to_dir(tmp_name, mo.util.data_dir('jobs'), suffix=suffix)
name = os.path.basename(full_name)
logger.debug(f'Job: Příloha {tmp_name} -> {name}')
return name
self.job = db.Job(type=type, state=db.JobState.preparing, user=for_user)
def submit(self):
# Do DB přidáváme nehotový job, protože potřebujeme znát job_id pro založení adresáře
sess = db.get_session()
sess.add(self.job)
sess.flush()
self.job_id = self.job.job_id
logger.info(f'Job: Vytvořen job #{self.job_id} pro uživatele #{self.job.user_id}')
sess.commit()
job_dir = self.job.dir_path()
if os.path.exists(job_dir):
# Hypoteticky by se mohlo stát, že se recykluje job_id od jobu, jehož
# vytvoření selhalo před commitem. Zkusíme tedy smazat prázdný adresář.
os.rmdir(job_dir)
os.mkdir(job_dir)
return self.job
def attach_file(self, tmp_name: str, attachment_name: str) -> str:
"""Vytvoří hardlink na daný pracovní soubor v adresáři jobu."""
full_name = self.job.file_path(attachment_name)
os.link(tmp_name, full_name)
logger.debug(f'Job: Příloha {tmp_name} -> {full_name}')
return attachment_name
def submit(self):
self.job.state = db.JobState.ready
db.get_session().commit()
send_notify()
def _finish_remove(self):
sess = db.get_session()
job = self.job
if job.in_file is not None:
mo.util.unlink_if_exists(job_file_path(job.in_file))
if job.out_file is not None:
mo.util.unlink_if_exists(job_file_path(job.out_file))
job_dir = self.job.dir_path()
if os.path.exists(job_dir):
shutil.rmtree(job_dir)
sess.delete(job)
sess.commit()
Loading