Skip to content
Snippets Groups Projects

Tolerování nekorektních PDF

Merged Martin Mareš requested to merge mj/pdf-errors into master
1 file
+ 34
14
Compare changes
  • Side-by-side
  • Inline
+ 34
14
@@ -2,6 +2,7 @@ import datetime
import multiprocessing
import os
import pikepdf
from typing import Any
import werkzeug.utils
import mo.db as db
@@ -26,7 +27,7 @@ class Submitter:
try:
self._do_submit(paper, tmpfile)
duration = (datetime.datetime.now() - t_start).total_seconds()
logger.info(f'Submit: Hotovo: file={paper.file_name} pages={paper.pages} bytes={paper.bytes} time={duration:.3f}')
logger.info(f'Submit: Hotovo: file={paper.file_name} pages={paper.pages} bytes={paper.bytes} time={duration:.3f} broken={1 if paper.broken else 0}')
except SubmitException as e:
duration = (datetime.datetime.now() - t_start).total_seconds()
preserved_as = mo.util.link_to_dir(tmpfile, mo.util.data_dir('errors'), prefix='submit-')
@@ -71,24 +72,43 @@ class Submitter:
raise SubmitException('Interní chyba při zpracování PDF: EOF.')
if 'error' in result:
logger.info('Submit: PDF error: ' + result['error'])
raise SubmitException('Soubor není korektní PDF.')
logger.info('Submit: PDF error: %s', result['error'])
if result['pdf-like']:
logger.info('Submit: Soubor akceptován s varováním')
paper.broken = True
else:
raise SubmitException('Soubor není korektní PDF.')
else:
paper.pages = result['pages']
paper.bytes = os.path.getsize(tmpfile)
paper.pages = result['pages']
self._file_paper(paper, tmpfile)
# Zpracování PDF běží v samostatném procesu, výsledek pošle jako slovník rourou.
def _process_pdf(tmpfile, pipe):
def _process_pdf(tmpfile: str, pipe):
result: Any = {}
try:
with pikepdf.open(tmpfile, attempt_recovery=False) as pdf:
pages = len(pdf.pages)
result['pages'] = len(pdf.pages)
except pikepdf.PdfError as e:
pipe.send({
"error": str(e),
})
return
pipe.send({
"pages": pages,
})
result['error'] = str(e)
result['pdf-like'] = Submitter._looks_like_pdf(tmpfile)
pipe.send(result)
def _looks_like_pdf(tmpfile: str) -> bool:
"""PDFka, která nezvládne otevřít QPDF, jsme ochotni akceptovat s warningem,
pokud začátek i konec souboru vypadá jako PDF."""
with open(tmpfile, 'rb') as f:
header = f.read(5)
if header != b'%PDF-':
return False
f.seek(0, 2)
size = f.tell()
if size < 100:
return False
f.seek(-100, 2)
trailer = f.read(100)
return b'startxref' in trailer and b'%%EOF' in trailer
Loading