# -*- mode: python ; coding: utf-8 -*- """ PyInstaller spec para AR-ElecArrangement. Empaca: - Backend Python (backend/main.py como entrypoint) - Frontend static (frontend/dist/ como recurso bundled) - Data (data/ con catálogos JSON) Resultado: dist/AR-ElecArrangement/AR-ElecArrangement.exe Cuando se ejecuta, inicia el server en 0.0.0.0:5505 y abre el browser. """ from PyInstaller.utils.hooks import collect_data_files block_cipher = None # Recursos que el .exe debe llevar dentro de sys._MEIPASS datas = [ ('frontend/dist', 'frontend/dist'), ('data', 'data'), ] # Catálogos (futuro): garantiza que cualquier JSON de data/ se incluya # automáticamente cuando agreguemos más. # Dependencias que PyInstaller a veces no detecta solo (uvicorn loaders) hiddenimports = [ 'uvicorn.logging', 'uvicorn.loops', 'uvicorn.loops.auto', 'uvicorn.protocols', 'uvicorn.protocols.http', 'uvicorn.protocols.http.auto', 'uvicorn.protocols.websockets', 'uvicorn.protocols.websockets.auto', 'uvicorn.lifespan', 'uvicorn.lifespan.on', ] a = Analysis( ['backend/main.py'], pathex=['backend'], binaries=[], datas=datas, hiddenimports=hiddenimports, hookspath=[], runtime_hooks=[], excludes=['tkinter', 'matplotlib', 'PySide6', 'PyQt5', 'PyQt6'], win_no_prefer_redirects=False, win_private_assemblies=False, cipher=block_cipher, noarchive=False, ) pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) exe = EXE( pyz, a.scripts, [], exclude_binaries=True, name='AR-ElecArrangement', debug=False, bootloader_ignore_signals=False, strip=False, upx=True, console=True, # mantiene ventana CMD visible — útil para ver logs disable_windowed_traceback=False, target_arch=None, codesign_identity=None, entitlements_file=None, icon=None, # TODO Sprint 14: agregar icon.ico ) coll = COLLECT( exe, a.binaries, a.zipfiles, a.datas, strip=False, upx=True, upx_exclude=[], name='AR-ElecArrangement', )