From 42fb76fef7b92fbdbb90ce0ea762d1a038d4f6f3 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 24 Jun 2025 17:29:51 +0530 Subject: [PATCH] Windows: Fix a regression in the previous release that caused terminal windows to popup momentarily when adding PDF files or converting them. Fixes #2115246 [When converting / importing PDF file into 8.5 on windows (10/11), multiple command windows will pop up for fraction of a second](https://bugs.launchpad.net/calibre/+bug/2115246) --- src/calibre/ebooks/metadata/pdf.py | 28 +++++++++++++++++----------- src/calibre/ebooks/pdf/pdftohtml.py | 3 ++- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/src/calibre/ebooks/metadata/pdf.py b/src/calibre/ebooks/metadata/pdf.py index 82dfe952b5..a77009bd49 100644 --- a/src/calibre/ebooks/metadata/pdf.py +++ b/src/calibre/ebooks/metadata/pdf.py @@ -25,6 +25,16 @@ def get_tools(): return pdfinfo, pdftoppm +def check_output(*a): + from calibre.ebooks.pdf.pdftohtml import creationflags + return subprocess.check_output(list(a), creationflags=creationflags) + + +def check_call(*a): + from calibre.ebooks.pdf.pdftohtml import creationflags + subprocess.check_call(list(a), creationflags=creationflags) + + def read_info(outputdir, get_cover): ''' Read info dict and cover from a pdf file named src.pdf in outputdir. Note that this function changes the cwd to outputdir and is therefore not @@ -37,7 +47,7 @@ def read_info(outputdir, get_cover): ans = {} try: - raw = subprocess.check_output([pdfinfo, '-enc', 'UTF-8', '-isodates', 'src.pdf']) + raw = check_output(pdfinfo, '-enc', 'UTF-8', '-isodates', 'src.pdf') except subprocess.CalledProcessError as e: prints(f'pdfinfo errored out with return code: {e.returncode}') return None @@ -61,7 +71,7 @@ def read_info(outputdir, get_cover): # https://cgit.freedesktop.org/poppler/poppler/commit/?id=c91483aceb1b640771f572cb3df9ad707e5cad0d # we can no longer rely on it. try: - raw = subprocess.check_output([pdfinfo, '-meta', 'src.pdf']).strip() + raw = check_output(pdfinfo, '-meta', 'src.pdf').strip() except subprocess.CalledProcessError as e: prints(f'pdfinfo failed to read XML metadata with return code: {e.returncode}') else: @@ -74,8 +84,8 @@ def read_info(outputdir, get_cover): if get_cover: try: - subprocess.check_call([pdftoppm, '-singlefile', '-jpeg', '-cropbox', - 'src.pdf', 'cover']) + check_call(pdftoppm, '-singlefile', '-jpeg', '-cropbox', + 'src.pdf', 'cover') except subprocess.CalledProcessError as e: prints(f'pdftoppm errored out with return code: {e.returncode}') @@ -85,21 +95,17 @@ def read_info(outputdir, get_cover): def page_images(pdfpath, outputdir='.', first=1, last=1, image_format='jpeg', prefix='page-images'): pdftoppm = get_tools()[1] outputdir = os.path.abspath(outputdir) - args = {} - if iswindows: - args['creationflags'] = subprocess.HIGH_PRIORITY_CLASS | subprocess.CREATE_NO_WINDOW try: - subprocess.check_call([ + check_call( pdftoppm, '-cropbox', '-' + image_format, '-f', str(first), - '-l', str(last), pdfpath, os.path.join(outputdir, prefix) - ], **args) + '-l', str(last), pdfpath, os.path.join(outputdir, prefix)) except subprocess.CalledProcessError as e: raise ValueError(f'Failed to render PDF, pdftoppm errorcode: {e.returncode}') def is_pdf_encrypted(path_to_pdf): pdfinfo = get_tools()[0] - raw = subprocess.check_output([pdfinfo, path_to_pdf]) + raw = check_output(pdfinfo, path_to_pdf) q = re.search(br'^Encrypted:\s*(\S+)', raw, flags=re.MULTILINE) if q is not None: return q.group(1) == b'yes' diff --git a/src/calibre/ebooks/pdf/pdftohtml.py b/src/calibre/ebooks/pdf/pdftohtml.py index ac84dbafc5..90e8078c3b 100644 --- a/src/calibre/ebooks/pdf/pdftohtml.py +++ b/src/calibre/ebooks/pdf/pdftohtml.py @@ -16,11 +16,12 @@ from calibre.utils.cleantext import clean_xml_chars from calibre.utils.ipc import eintr_retry_call PDFTOHTML = 'pdftohtml' + ('.exe' if iswindows else '') +creationflags = subprocess.DETACHED_PROCESS if iswindows else 0 def popen(cmd, **kw): if iswindows: - kw['creationflags'] = subprocess.DETACHED_PROCESS + kw['creationflags'] = creationflags return subprocess.Popen(cmd, **kw)