#!/usr/bin/env python3 """ Simple build wrapper for EBoek.info Scraper Creates a standalone executable using PyInstaller """ import os import sys import subprocess import shutil from pathlib import Path def main(): """Main build process.""" print("=" * 50) print("EBoek.info Scraper - Executable Builder") print("=" * 50) print() project_root = Path(__file__).parent os.chdir(project_root) print(f"Working from: {project_root}") print() # Check if PyInstaller is installed try: import PyInstaller print(f"PyInstaller {PyInstaller.__version__} found") except ImportError: print("Installing PyInstaller...") subprocess.run([sys.executable, "-m", "pip", "install", "pyinstaller"], check=True) # Clean previous builds print() for directory in ["dist", "build"]: if Path(directory).exists(): shutil.rmtree(directory) print(f"Cleaned {directory}/") # Determine platform-specific settings is_windows = sys.platform.startswith('win') app_name = "EBoek_Scraper" # Build command build_cmd = [ sys.executable, "-m", "PyInstaller", "--onefile", "--windowed", "--name", app_name, # Hidden imports for PyQt5 "--hidden-import", "PyQt5.QtCore", "--hidden-import", "PyQt5.QtGui", "--hidden-import", "PyQt5.QtWidgets", # Hidden imports for Selenium "--hidden-import", "selenium", "--hidden-import", "selenium.webdriver", "--hidden-import", "selenium.webdriver.chrome", "--hidden-import", "selenium.webdriver.chrome.options", "--hidden-import", "selenium.webdriver.common.by", # Hidden imports for our modules "--hidden-import", "core.scraper", "--hidden-import", "core.scraper_thread", "--hidden-import", "core.credentials", "--hidden-import", "gui.main_window", "--hidden-import", "gui.login_dialog", "--hidden-import", "gui.progress_dialog", "--hidden-import", "utils.validators", # Bookys scraper modules "--hidden-import", "core.bookys_scraper", "--hidden-import", "core.bookys_thread", "--hidden-import", "gui.bookys_window", "--hidden-import", "gui.startup_dialog", # Exclude unnecessary modules "--exclude-module", "tkinter", "--exclude-module", "matplotlib", "--exclude-module", "numpy", "--exclude-module", "pandas", # Main script "gui_main.py" ] print() print("Building executable...") print("This may take a few minutes...") print() # Run PyInstaller result = subprocess.run(build_cmd) if result.returncode != 0: print("Build failed!") sys.exit(1) print("Build completed successfully!") # Check if executable was created exe_name = "EBoek_Scraper.exe" if is_windows else "EBoek_Scraper" exe_path = Path("dist") / exe_name if not exe_path.exists(): print(f"Error: Executable not found at {exe_path}") sys.exit(1) # Display results file_size = exe_path.stat().st_size / (1024 * 1024) # MB print() print("=" * 50) print("BUILD SUCCESSFUL!") print("=" * 50) print(f"Executable location: {exe_path}") print(f"File size: {file_size:.1f} MB") print() if is_windows: print("Windows Instructions:") print(f" Run: {exe_path}") print(" Windows may show security warning on first run") print(" Click 'More Info' -> 'Run Anyway' if prompted") else: print("macOS/Linux Instructions:") print(f" Run: ./{exe_path}") print() print("Ready for distribution!") if __name__ == "__main__": main()