ghostscript: add output tracing

This commit is contained in:
James R. Barlow
2020-11-29 14:53:35 -08:00
parent b83d7f6d1a
commit 7e1223c12c
3 changed files with 41 additions and 10 deletions
+37 -6
View File
@@ -18,10 +18,11 @@ from subprocess import PIPE, CalledProcessError
from typing import Optional, cast
from PIL import Image
from tqdm import tqdm
from ocrmypdf.exceptions import MissingDependencyError, SubprocessOutputError
from ocrmypdf.helpers import Resolution
from ocrmypdf.subprocess import get_version, run
from ocrmypdf.subprocess import get_version, run, run_polling_stderr
log = logging.getLogger(__name__)
@@ -139,6 +140,27 @@ def rasterize_pdf(
im.save(fspath(output_file), dpi=page_dpi)
class GhostscriptFollower:
re_process = re.compile(r"Processing pages \d+ through (\d+).")
re_page = re.compile(r"Page (\d+)")
def __init__(self):
self.count = 0
self.tqdm = None
def __call__(self, line):
if not self.tqdm:
m = self.re_process.match(line.strip())
if m:
self.count = int(m.group(1))
self.tqdm = tqdm(total=self.count, desc="Ghostscript", unit='page')
return
else:
m = self.re_page.match(line.strip())
if m:
self.tqdm.update()
def generate_pdfa(
pdf_pages,
output_file: os.PathLike,
@@ -188,7 +210,6 @@ def generate_pdfa(
args_gs = (
[
GS,
"-dQUIET",
"-dBATCH",
"-dNOPAUSE",
"-dSAFER",
@@ -208,16 +229,26 @@ def generate_pdfa(
]
)
args_gs.extend(fspath(s) for s in pdf_pages) # Stringify Path objs
try:
with Path(output_file).open('wb') as output:
p = run(args_gs, stdout=output, stderr=PIPE, check=True)
p = run_polling_stderr(
args_gs,
stdout=output,
stderr=PIPE,
check=True,
text=True,
encoding='utf-8',
errors='replace',
callback=GhostscriptFollower(),
)
except CalledProcessError as e:
# Ghostscript does not change return code when it fails to create
# PDF/A - check PDF/A status elsewhere
log.error(e.stderr.decode(errors='replace'))
raise SubprocessOutputError('Ghostscript PDF/A rendering failed')
log.error(e.stderr)
raise SubprocessOutputError('Ghostscript PDF/A rendering failed') from e
else:
stderr = p.stderr.decode('utf-8', errors='replace')
stderr = p.stderr
if _gs_error_reported(stderr):
last_part = None
repcount = 0
+3 -3
View File
@@ -23,7 +23,7 @@ from unittest.mock import patch
from ocrmypdf import hookimpl
from ocrmypdf.builtin_plugins import ghostscript
from ocrmypdf.subprocess import run
from ocrmypdf.subprocess import run_polling_stderr
def run_rig_args(args, **kwargs):
@@ -33,13 +33,13 @@ def run_rig_args(args, **kwargs):
new_args = [
arg for arg in args if not arg.startswith('-dPDFA') and not arg.endswith('.ps')
]
proc = run(new_args, **kwargs)
proc = run_polling_stderr(new_args, **kwargs)
return proc
@hookimpl
def generate_pdfa(pdf_pages, pdfmark, output_file, compression, pdf_version, pdfa_part):
with patch('ocrmypdf._exec.ghostscript.run', new=run_rig_args):
with patch('ocrmypdf._exec.ghostscript.run_polling_stderr', new=run_rig_args):
ghostscript.generate_pdfa(
pdf_pages=pdf_pages,
pdfmark=pdfmark,
+1 -1
View File
@@ -34,7 +34,7 @@ def raise_gs_fail(*args, **kwargs):
@hookimpl
def generate_pdfa(pdf_pages, pdfmark, output_file, compression, pdf_version, pdfa_part):
with patch('ocrmypdf._exec.ghostscript.run', new=raise_gs_fail):
with patch('ocrmypdf._exec.ghostscript.run_polling_stderr', new=raise_gs_fail):
ghostscript.generate_pdfa(
pdf_pages=pdf_pages,
pdfmark=pdfmark,