diff --git a/build.spec b/build.spec index 2b83630..b2a6aa0 100644 --- a/build.spec +++ b/build.spec @@ -9,22 +9,31 @@ SELF_PATH = str(Path(".").absolute()) if SELF_PATH not in sys.path: sys.path.insert(0, SELF_PATH) -from constants import WORKING_DIR, DEFAULT_LANG +from constants import WORKING_DIR, SITE_PACKAGES_PATH, DEFAULT_LANG if TYPE_CHECKING: from PyInstaller.building.api import PYZ, EXE from PyInstaller.building.build_main import Analysis - -datas: list[tuple[str | Path, str]] = [ - ("pickaxe.ico", '.'), # icon file +# (source_path, dest_path, required) +to_add: list[tuple[Path, str, bool]] = [ + (Path("pickaxe.ico"), '.', True), # icon file # SeleniumWire HTTPS/SSL cert file and key - ("./env/Lib/site-packages/seleniumwire/ca.crt", "./seleniumwire"), - ("./env/Lib/site-packages/seleniumwire/ca.key", "./seleniumwire"), + (Path(SITE_PACKAGES_PATH, "seleniumwire/ca.crt"), "./seleniumwire", False), + (Path(SITE_PACKAGES_PATH, "seleniumwire/ca.key"), "./seleniumwire", False), ] for lang_filepath in WORKING_DIR.joinpath("lang").glob("*.json"): if lang_filepath.stem != DEFAULT_LANG: - datas.append((lang_filepath, "lang")) + to_add.append((lang_filepath, "lang", True)) + +# ensure the required to-be-added data exists +datas: list[tuple[Path, str]] = [] +for source_path, dest_path, required in to_add: + if source_path.exists(): + datas.append((source_path, dest_path)) + elif required: + raise FileNotFoundError(str(source_path)) + block_cipher = None a = Analysis( @@ -41,6 +50,7 @@ a = Analysis( "setuptools._distutils.dir_util", "setuptools._distutils.file_util", "setuptools._distutils.archive_util", + "PIL._tkinter_finder", ], runtime_hooks=[], cipher=block_cipher, diff --git a/constants.py b/constants.py index 98ccd04..17b6e33 100644 --- a/constants.py +++ b/constants.py @@ -22,6 +22,14 @@ IS_PACKAGED = hasattr(sys, "_MEIPASS") # logging special levels CALL = logging.INFO - 1 logging.addLevelName(CALL, "CALL") +# site-packages venv path changes depending on the system platform +if sys.platform == "win32": + SYS_SITE_PACKAGES = "Lib/site-packages" +else: + # On Linux, the site-packages path includes a versioned 'pythonX.Y' folder part + # The Lib folder is also spelled in lowercase: 'lib' + version_info = sys.version_info + SYS_SITE_PACKAGES = f"lib/python{version_info.major}.{version_info.minor}/site-packages" def _resource_path(relative_path: Path | str) -> Path: @@ -46,6 +54,9 @@ SELF_PATH = Path(sys.argv[0]).absolute() if SELF_PATH.stem == "pyinstaller": SELF_PATH = Path(__file__).with_name("main.py").absolute() WORKING_DIR = SELF_PATH.absolute().parent +# Development paths +VENV_PATH = Path(WORKING_DIR, "env") +SITE_PACKAGES_PATH = Path(VENV_PATH, SYS_SITE_PACKAGES) # Translations path # NOTE: These don't have to be available to the end-user, so the path points to the internal dir LANG_PATH = _resource_path("lang")