|
25 | 25 |
|
26 | 26 | __version__ = "0.0.1"
|
27 | 27 |
|
| 28 | +DEFAULT_CACHE_DIR = os.path.join(Path.home(), ".hpdf", "chromedriver") |
| 29 | + |
28 | 30 | # HTML2PDF.js prints unicode symbols to console. The following makes it work on
|
29 | 31 | # Windows which otherwise complains:
|
30 | 32 | # UnicodeEncodeError: 'charmap' codec can't encode characters in position 129-130: character maps to <undefined>
|
|
35 | 37 |
|
36 | 38 | class HTML2PDF_HTTPClient(HttpClient):
|
37 | 39 | def get(self, url, params=None, **kwargs) -> Response:
|
38 |
| - """ |
39 |
| - Add you own logic here like session or proxy etc. |
40 |
| - """ |
41 | 40 | last_error: Optional[Exception] = None
|
42 | 41 | for attempt in range(1, 3):
|
43 | 42 | print( # noqa: T201
|
@@ -147,9 +146,6 @@ def get_pdf_from_html(driver, url) -> bytes:
|
147 | 146 | "marginRight": get_inches_from_millimeters(21),
|
148 | 147 | }
|
149 | 148 |
|
150 |
| - print("html2pdf: executing print command with ChromeDriver.") # noqa: T201 |
151 |
| - result = driver.execute_cdp_cmd("Page.printToPDF", calculated_print_options) |
152 |
| - |
153 | 149 | class Done(Exception):
|
154 | 150 | pass
|
155 | 151 |
|
@@ -180,25 +176,33 @@ class Done(Exception):
|
180 | 176 | print(entry) # noqa: T201
|
181 | 177 | print('"""') # noqa: T201
|
182 | 178 |
|
| 179 | + # |
| 180 | + # Execute Print command with ChromeDriver. |
| 181 | + # |
| 182 | + print("html2pdf: executing print command with ChromeDriver.") # noqa: T201 |
| 183 | + result = driver.execute_cdp_cmd("Page.printToPDF", calculated_print_options) |
| 184 | + |
183 | 185 | data = base64.b64decode(result["data"])
|
184 | 186 | return data
|
185 | 187 |
|
186 | 188 |
|
| 189 | +def get_chrome_driver(path_to_cache_dir: str) -> str: |
| 190 | + cache_manager = HTML2PDF_CacheManager( |
| 191 | + file_manager=FileManager(os_system_manager=OperationSystemManager()), |
| 192 | + path_to_cache_dir=path_to_cache_dir, |
| 193 | + ) |
| 194 | + |
| 195 | + http_client = HTML2PDF_HTTPClient() |
| 196 | + download_manager = WDMDownloadManager(http_client) |
| 197 | + path_to_chrome = ChromeDriverManager( |
| 198 | + download_manager=download_manager, cache_manager=cache_manager |
| 199 | + ).install() |
| 200 | + return path_to_chrome |
| 201 | + |
| 202 | + |
187 | 203 | def create_webdriver(chromedriver: Optional[str], path_to_cache_dir: str):
|
188 |
| - print("html2pdf: creating ChromeDriver service.", flush=True) # noqa: T201 |
189 | 204 | if chromedriver is None:
|
190 |
| - cache_manager = HTML2PDF_CacheManager( |
191 |
| - file_manager=FileManager( |
192 |
| - os_system_manager=OperationSystemManager() |
193 |
| - ), |
194 |
| - path_to_cache_dir=path_to_cache_dir, |
195 |
| - ) |
196 |
| - |
197 |
| - http_client = HTML2PDF_HTTPClient() |
198 |
| - download_manager = WDMDownloadManager(http_client) |
199 |
| - path_to_chrome = ChromeDriverManager( |
200 |
| - download_manager=download_manager, cache_manager=cache_manager |
201 |
| - ).install() |
| 205 | + path_to_chrome = get_chrome_driver(path_to_cache_dir) |
202 | 206 | else:
|
203 | 207 | path_to_chrome = chromedriver
|
204 | 208 | print(f"html2pdf: ChromeDriver available at path: {path_to_chrome}") # noqa: T201
|
@@ -236,50 +240,99 @@ def main():
|
236 | 240 | os.environ["WDM_LOCAL"] = "1"
|
237 | 241 |
|
238 | 242 | parser = argparse.ArgumentParser(description="HTML2PDF printer script.")
|
| 243 | + |
239 | 244 | parser.add_argument(
|
| 245 | + "-v", "--version", action="version", version=__version__ |
| 246 | + ) |
| 247 | + |
| 248 | + command_subparsers = parser.add_subparsers(title="command", dest="command") |
| 249 | + command_subparsers.required = True |
| 250 | + |
| 251 | + # |
| 252 | + # Get driver command. |
| 253 | + # |
| 254 | + command_parser_get_driver = command_subparsers.add_parser( |
| 255 | + "get_driver", |
| 256 | + help="Check if ChromeDriver already exists locally. If not, download it.", |
| 257 | + description="", |
| 258 | + ) |
| 259 | + command_parser_get_driver.add_argument( |
| 260 | + "--cache-dir", |
| 261 | + type=str, |
| 262 | + help="Optional path to a cache directory whereto the ChromeDriver is downloaded.", |
| 263 | + ) |
| 264 | + |
| 265 | + # |
| 266 | + # Print command. |
| 267 | + # |
| 268 | + command_parser_print = command_subparsers.add_parser( |
| 269 | + "print", |
| 270 | + help="Main print command", |
| 271 | + description="", |
| 272 | + ) |
| 273 | + command_parser_print.add_argument( |
240 | 274 | "--chromedriver",
|
241 | 275 | type=str,
|
242 | 276 | help="Optional chromedriver path. Downloaded if not given.",
|
243 | 277 | )
|
244 |
| - parser.add_argument( |
| 278 | + command_parser_print.add_argument( |
245 | 279 | "--cache-dir",
|
246 | 280 | type=str,
|
247 | 281 | help="Optional path to a cache directory whereto the ChromeDriver is downloaded.",
|
248 | 282 | )
|
249 |
| - parser.add_argument("paths", nargs="+", help="Paths to input HTML file.") |
| 283 | + command_parser_print.add_argument( |
| 284 | + "paths", nargs="+", help="Paths to input HTML file." |
| 285 | + ) |
| 286 | + |
250 | 287 | args = parser.parse_args()
|
251 | 288 |
|
252 |
| - paths: List[str] = args.paths |
| 289 | + path_to_cache_dir: str |
| 290 | + if args.command == "get_driver": |
| 291 | + path_to_cache_dir = ( |
| 292 | + args.cache_dir |
| 293 | + if args.cache_dir is not None |
| 294 | + else (DEFAULT_CACHE_DIR) |
| 295 | + ) |
253 | 296 |
|
254 |
| - path_to_cache_dir: str = ( |
255 |
| - args.cache_dir |
256 |
| - if args.cache_dir is not None |
257 |
| - else (os.path.join(Path.home(), ".hpdf", "chromedriver")) |
258 |
| - ) |
259 |
| - driver = create_webdriver(args.chromedriver, path_to_cache_dir) |
| 297 | + path_to_chrome = get_chrome_driver(path_to_cache_dir) |
| 298 | + print(f"html2pdf: ChromeDriver available at path: {path_to_chrome}") # noqa: T201 |
| 299 | + sys.exit(0) |
260 | 300 |
|
261 |
| - @atexit.register |
262 |
| - def exit_handler(): |
263 |
| - print("html2pdf: exit handler: quitting the ChromeDriver.") # noqa: T201 |
264 |
| - driver.quit() |
| 301 | + elif args.command == "print": |
| 302 | + paths: List[str] = args.paths |
265 | 303 |
|
266 |
| - assert len(paths) % 2 == 0, ( |
267 |
| - f"Expecting an even number of input/output path arguments: {paths}." |
268 |
| - ) |
269 |
| - for current_pair_idx in range(0, 2, len(paths)): |
270 |
| - path_to_input_html = paths[current_pair_idx] |
271 |
| - path_to_output_pdf = paths[current_pair_idx + 1] |
| 304 | + path_to_cache_dir = ( |
| 305 | + args.cache_dir |
| 306 | + if args.cache_dir is not None |
| 307 | + else (DEFAULT_CACHE_DIR) |
| 308 | + ) |
| 309 | + driver = create_webdriver(args.chromedriver, path_to_cache_dir) |
272 | 310 |
|
273 |
| - assert os.path.isfile(path_to_input_html), path_to_input_html |
| 311 | + @atexit.register |
| 312 | + def exit_handler(): |
| 313 | + print("html2pdf: exit handler: quitting the ChromeDriver.") # noqa: T201 |
| 314 | + driver.quit() |
274 | 315 |
|
275 |
| - path_to_output_pdf_dir = os.path.dirname(path_to_output_pdf) |
276 |
| - Path(path_to_output_pdf_dir).mkdir(parents=True, exist_ok=True) |
| 316 | + assert len(paths) % 2 == 0, ( |
| 317 | + f"Expecting an even number of input/output path arguments: {paths}." |
| 318 | + ) |
| 319 | + for current_pair_idx in range(0, 2, len(paths)): |
| 320 | + path_to_input_html = paths[current_pair_idx] |
| 321 | + path_to_output_pdf = paths[current_pair_idx + 1] |
277 | 322 |
|
278 |
| - url = Path(os.path.abspath(path_to_input_html)).as_uri() |
| 323 | + assert os.path.isfile(path_to_input_html), path_to_input_html |
279 | 324 |
|
280 |
| - pdf_bytes = get_pdf_from_html(driver, url) |
281 |
| - with open(path_to_output_pdf, "wb") as f: |
282 |
| - f.write(pdf_bytes) |
| 325 | + path_to_output_pdf_dir = os.path.dirname(path_to_output_pdf) |
| 326 | + Path(path_to_output_pdf_dir).mkdir(parents=True, exist_ok=True) |
| 327 | + |
| 328 | + url = Path(os.path.abspath(path_to_input_html)).as_uri() |
| 329 | + |
| 330 | + pdf_bytes = get_pdf_from_html(driver, url) |
| 331 | + with open(path_to_output_pdf, "wb") as f: |
| 332 | + f.write(pdf_bytes) |
| 333 | + else: |
| 334 | + print("html2pdf: unknown command.") # noqa: T201 |
| 335 | + sys.exit(1) |
283 | 336 |
|
284 | 337 |
|
285 | 338 | if __name__ == "__main__":
|
|
0 commit comments