From 9f3a52fd123ef92ab29cc740ce5983264f295e51 Mon Sep 17 00:00:00 2001 From: "James R. Barlow" Date: Mon, 1 Aug 2022 13:58:24 -0700 Subject: [PATCH] windows: compare Ghostscript versions properly --- src/ocrmypdf/subprocess/_windows.py | 30 ++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/ocrmypdf/subprocess/_windows.py b/src/ocrmypdf/subprocess/_windows.py index a5dd9e02..5b983fde 100644 --- a/src/ocrmypdf/subprocess/_windows.py +++ b/src/ocrmypdf/subprocess/_windows.py @@ -6,12 +6,15 @@ from __future__ import annotations import logging import os +import re import shutil import sys from itertools import chain from pathlib import Path from typing import Any, Callable, Iterable, Iterator, TypeVar +from packaging.version import InvalidVersion, Version + if sys.version_info >= (3, 10): from typing import TypeAlias else: @@ -100,6 +103,31 @@ def registry_path_tesseract(env=None) -> Iterator[Path]: log.warning(e) +def _program_version_in_path_key(path: Path) -> tuple[str, Version | None]: + """Key function for comparing Ghostscript and Tesseract paths. + + Ghostscript installs on Windows: + %PROGRAMFILES%/gs/gs9.56.1 -> ('gs', Version('9.56.1')) + %PROGRAMFILES%/gs/gs9.24 -> ('gs', Version('9.24')) + + Tesseract looks like: + %PROGRAMFILES%/Tesseract-OCR -> ('Tesseract-OCR', None) + + Thus ensuring the resulting tuple will order the alternatives correctly, + e.g. gs10.0 > gs9.99. + """ + match = re.match(r'([^0-9]+)(.*)', str(path.name)) + if match: + try: + program = match.group(1) + version_str = match.group(2) + version = Version(version_str) + return program, version + except InvalidVersion: + pass + return path.name, None + + def program_files_paths(env=None) -> Iterator[Path]: if not env: env = os.environ @@ -117,7 +145,7 @@ def program_files_paths(env=None) -> Iterator[Path]: return iter( sorted( (p for p in path_walker()), - key=lambda p: (p.name, p.parent.name), + key=_program_version_in_path_key, reverse=True, ) )