Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/pdfplumber/repair.py: 29%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1import pathlib
2import shutil
3import subprocess
4from io import BufferedReader, BytesIO
5from typing import Literal, Optional, Union
7T_repair_setting = Literal["default", "prepress", "printer", "ebook", "screen"]
10def _repair(
11 path_or_fp: Union[str, pathlib.Path, BufferedReader, BytesIO],
12 password: Optional[str] = None,
13 gs_path: Optional[Union[str, pathlib.Path]] = None,
14 setting: T_repair_setting = "default",
15) -> BytesIO:
17 executable = (
18 gs_path
19 or shutil.which("gs")
20 or shutil.which("gswin32c")
21 or shutil.which("gswin64c")
22 )
23 if executable is None: # pragma: nocover
24 raise Exception(
25 "Cannot find Ghostscript, which is required for repairs.\n"
26 "Visit https://www.ghostscript.com/ for installation instructions."
27 )
29 repair_args = [
30 executable,
31 "-sstdout=%stderr",
32 "-o",
33 "-",
34 "-sDEVICE=pdfwrite",
35 f"-dPDFSETTINGS=/{setting}",
36 ]
38 if password:
39 repair_args += [f"-sPDFPassword={password}"]
41 if isinstance(path_or_fp, (str, pathlib.Path)):
42 stdin = None
43 repair_args += [str(pathlib.Path(path_or_fp).absolute())]
44 else:
45 stdin = path_or_fp
46 repair_args += ["-"]
48 proc = subprocess.Popen(
49 repair_args,
50 stdin=subprocess.PIPE if stdin else None,
51 stdout=subprocess.PIPE,
52 stderr=subprocess.PIPE,
53 )
55 stdout, stderr = proc.communicate(stdin.read() if stdin else None)
57 if proc.returncode:
58 raise Exception(f"{stderr.decode('utf-8')}")
60 return BytesIO(stdout)
63def repair(
64 path_or_fp: Union[str, pathlib.Path, BufferedReader, BytesIO],
65 outfile: Optional[Union[str, pathlib.Path]] = None,
66 password: Optional[str] = None,
67 gs_path: Optional[Union[str, pathlib.Path]] = None,
68 setting: T_repair_setting = "default",
69) -> Optional[BytesIO]:
70 repaired = _repair(path_or_fp, password, gs_path=gs_path, setting=setting)
71 if outfile:
72 with open(outfile, "wb") as f:
73 f.write(repaired.read())
74 return None
75 else:
76 return repaired