Remove old widget-based Python UI (replaced by QML), unused build scripts, NL/variable/webfont variants, old shaders, PNG icons (replaced by SVGs), and standalone test files. Add build.bat and build.spec for the bootstrapper build system.
96 lines
3.0 KiB
Python
96 lines
3.0 KiB
Python
# -*- mode: python ; coding: utf-8 -*-
|
|
# WhisperVoice — Single-file portable bootstrapper
|
|
#
|
|
# This builds a TINY exe that contains only:
|
|
# - The bootstrapper (downloads Python + deps on first run)
|
|
# - The app source code (bundled as data, extracted to runtime/app/)
|
|
#
|
|
# NO heavy dependencies (torch, PySide6, etc.) are bundled.
|
|
|
|
import os
|
|
import glob
|
|
|
|
block_cipher = None
|
|
|
|
# ── Collect app source as data (goes into app_source/ inside the bundle) ──
|
|
|
|
app_datas = []
|
|
|
|
# main.py
|
|
app_datas.append(('main.py', 'app_source'))
|
|
|
|
# requirements.txt
|
|
app_datas.append(('requirements.txt', 'app_source'))
|
|
|
|
# src/**/*.py (core, ui, utils — preserving directory structure)
|
|
for py in glob.glob('src/**/*.py', recursive=True):
|
|
dest = os.path.join('app_source', os.path.dirname(py))
|
|
app_datas.append((py, dest))
|
|
|
|
# src/ui/qml/** (QML files, shaders, SVGs, fonts, qmldir)
|
|
qml_dir = os.path.join('src', 'ui', 'qml')
|
|
for pattern in ('*.qml', '*.qsb', '*.frag', '*.svg', '*.ico', '*.png',
|
|
'qmldir', 'AUTHORS.txt', 'OFL.txt'):
|
|
for f in glob.glob(os.path.join(qml_dir, pattern)):
|
|
app_datas.append((f, os.path.join('app_source', qml_dir)))
|
|
|
|
# Fonts
|
|
for f in glob.glob(os.path.join(qml_dir, 'fonts', 'ttf', '*.ttf')):
|
|
app_datas.append((f, os.path.join('app_source', qml_dir, 'fonts', 'ttf')))
|
|
|
|
# assets/
|
|
if os.path.exists(os.path.join('assets', 'icon.ico')):
|
|
app_datas.append((os.path.join('assets', 'icon.ico'), os.path.join('app_source', 'assets')))
|
|
|
|
# ── Analysis — only the bootstrapper, NO heavy imports ────────────────────
|
|
|
|
a = Analysis(
|
|
['bootstrapper.py'],
|
|
pathex=[],
|
|
binaries=[],
|
|
datas=app_datas,
|
|
hiddenimports=[],
|
|
hookspath=[],
|
|
hooksconfig={},
|
|
runtime_hooks=[],
|
|
excludes=[
|
|
# Exclude everything heavy — the bootstrapper only uses stdlib
|
|
'torch', 'numpy', 'scipy', 'PySide6', 'shiboken6',
|
|
'faster_whisper', 'ctranslate2', 'llama_cpp',
|
|
'sounddevice', 'soundfile', 'keyboard', 'pyperclip',
|
|
'psutil', 'pynvml', 'pystray', 'PIL', 'Pillow',
|
|
'darkdetect', 'huggingface_hub', 'requests',
|
|
'tqdm', 'onnxruntime', 'av',
|
|
'tkinter', 'matplotlib', 'notebook', 'IPython',
|
|
],
|
|
win_no_prefer_redirects=False,
|
|
win_private_assemblies=False,
|
|
cipher=block_cipher,
|
|
noarchive=False,
|
|
)
|
|
|
|
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
|
|
|
|
# ── Single-file EXE (--onefile) ──────────────────────────────────────────
|
|
|
|
exe = EXE(
|
|
pyz,
|
|
a.scripts,
|
|
a.binaries,
|
|
a.zipfiles,
|
|
a.datas,
|
|
[],
|
|
name='WhisperVoice',
|
|
debug=False,
|
|
bootloader_ignore_signals=False,
|
|
strip=False,
|
|
upx=True,
|
|
console=False, # No console — bootstrapper allocates one when needed
|
|
disable_windowed_traceback=False,
|
|
argv_emulation=False,
|
|
target_arch=None,
|
|
codesign_identity=None,
|
|
entitlements_file=None,
|
|
icon='assets/icon.ico',
|
|
)
|