#!/usr/bin/env python3 """ fcco-Converter V2 – Build-Skript Erstellt plattformabhängige Standalone-Executables mit PyInstaller. Aufruf: python build.py """ import platform import subprocess import sys from pathlib import Path import shutil def build(): system = platform.system() project_dir = Path(__file__).parent dist_dir = project_dir / "dist" # Alte App löschen app_name = "fcco-Converter" if system == "Darwin": old_app = dist_dir / f"{app_name}.app" else: old_app = dist_dir / f"{app_name}.exe" if old_app.exists(): if old_app.is_dir(): shutil.rmtree(old_app) else: old_app.unlink() # Basis-Argumente für PyInstaller args = [ sys.executable, "-m", "PyInstaller", "--onefile", "--windowed", "--name", app_name, "--clean", ] # Icon hinzufügen (wenn vorhanden) icon_path = project_dir / "icon.ico" if icon_path.exists(): args.extend(["--icon", str(icon_path)]) # Versteckte Imports (die PyInstaller evtl. nicht automatisch findet) hidden_imports = [ "customtkinter", "mutagen", "mutagen.easyid3", "mutagen.id3", "static_ffmpeg", ] for imp in hidden_imports: args.extend(["--hidden-import", imp]) # CustomTkinter-Daten einbinden try: import customtkinter ctk_path = Path(customtkinter.__file__).parent if system == "Windows": args.extend(["--add-data", f"{ctk_path};customtkinter"]) else: args.extend(["--add-data", f"{ctk_path}:customtkinter"]) except ImportError: print("WARNUNG: customtkinter nicht installiert. Bitte 'pip install -r requirements.txt' ausführen.") # Hauptdatei args.append(str(project_dir / "main.py")) print(f"Build für {system}...") print(f"Befehl: {' '.join(args)}") print() result = subprocess.run(args, cwd=str(project_dir)) if result.returncode == 0: # Kopiere config.json in den dist Ordner, damit die App sie direkt findet config_src = project_dir / "config.json" if config_src.exists(): shutil.copy(config_src, dist_dir / "config.json") # ZIP-Archiv für das Release erstellen import tempfile sys_name = "macos" if system == "Darwin" else system.lower() zip_name = f"fcco-Converter-{sys_name}" zip_path = dist_dir / zip_name with tempfile.TemporaryDirectory() as tmpdir: tmp = Path(tmpdir) # App/Exe ins Temp-Verzeichnis kopieren if system == "Darwin": shutil.copytree(dist_dir / f"{app_name}.app", tmp / f"{app_name}.app") else: shutil.copy(dist_dir / f"{app_name}.exe", tmp / f"{app_name}.exe") # config.json mit in die ZIP packen if config_src.exists(): shutil.copy(config_src, tmp / "config.json") shutil.make_archive(str(zip_path), 'zip', str(tmp)) print() print(f"Build erfolgreich! Ausgabe in: {dist_dir}") print(f"ZIP für Release: {zip_path}.zip") else: print() print(f"Build fehlgeschlagen (Code {result.returncode}).") sys.exit(1) if __name__ == "__main__": build()