Files
proxy-god/ProxyChainManager.spec
Dr Jones 28f00c0887 fix: production-ready build pipeline + audit_device() crash
- fingerprint.py: audit_device() crashed with "cannot unpack non-iterable
  bool" because of a stray `webrtc_ok, _ = ... and True or False` line.
  Replaced with a proper Chrome+Edge registry probe using _WEBRTC_*
  module constants.

- ProxyChainManager.spec: removed the hardcoded absolute run.py path,
  resolve everything relative to SPECPATH so the spec is portable on any
  machine / CI runner. Bundled signup_extension/ and world_map.png as
  data files (these were missing — the runtime would fall back to drawn
  landmasses and the signup browser extension would 404 in the frozen
  build). Added PIL._tkinter_finder hidden import for safety.

- scripts/setup_and_build.ps1: build now uses the spec file instead of
  re-deriving CLI flags. The old `--onefile --windowed --collect-all
  customtkinter` invocation IGNORED the spec and silently dropped the
  bundled data files. Also added explicit $LASTEXITCODE check.

Verified end-to-end: clean PyInstaller build produces a 32MB exe with
signup_extension (8 TOC entries), world_map.png (4), customtkinter
(365) all present.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 17:24:55 -07:00

74 lines
1.7 KiB
Python

# -*- mode: python ; coding: utf-8 -*-
"""PyInstaller spec for ProxyChainManager.
Build:
python -m PyInstaller --noconfirm --clean ProxyChainManager.spec
Always builds relative to the spec file's directory so the script works on
any machine / CI runner.
"""
import os
from pathlib import Path
from PyInstaller.utils.hooks import collect_all
# SPECPATH is provided by PyInstaller; fall back to CWD for IDE linters.
_ROOT = Path(globals().get("SPECPATH", os.getcwd())).resolve()
datas = []
binaries = []
hiddenimports = [
'pystray._win32',
'PIL._tkinter_finder',
]
tmp_ret = collect_all('customtkinter')
datas += tmp_ret[0]; binaries += tmp_ret[1]; hiddenimports += tmp_ret[2]
# Bundle runtime data files. Each tuple is (src_relative_to_spec, dest_in_bundle).
_BUNDLE_DATA = [
('proxy_chain_manager/signup_extension', 'proxy_chain_manager/signup_extension'),
('proxy_chain_manager/world_map.png', 'proxy_chain_manager'),
]
for src, dest in _BUNDLE_DATA:
p = _ROOT / src
if p.exists():
datas.append((str(p), dest))
a = Analysis(
[str(_ROOT / 'run.py')],
pathex=[str(_ROOT)],
binaries=binaries,
datas=datas,
hiddenimports=hiddenimports,
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
noarchive=False,
optimize=0,
)
pyz = PYZ(a.pure)
exe = EXE(
pyz,
a.scripts,
a.binaries,
a.datas,
[],
name='ProxyChainManager',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=False,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
uac_admin=True,
)