|
|
|
|
|
""" |
|
|
Build script for Medical Transcription GUI Application |
|
|
Скрипт для сборки Windows .exe файла с использованием uv |
|
|
""" |
|
|
|
|
|
import os |
|
|
import sys |
|
|
import subprocess |
|
|
from pathlib import Path |
|
|
import shutil |
|
|
|
|
|
|
|
|
def build_exe(): |
|
|
"""Собрать Windows .exe файл""" |
|
|
|
|
|
print("=" * 60) |
|
|
print("Medical Transcription GUI - Windows Build (with uv)") |
|
|
print("=" * 60) |
|
|
|
|
|
root_dir = Path(__file__).parent.absolute() |
|
|
|
|
|
|
|
|
try: |
|
|
result = subprocess.run(['uv', '--version'], capture_output=True, text=True) |
|
|
if result.returncode == 0: |
|
|
print(f"\n✓ uv найден: {result.stdout.strip()}") |
|
|
else: |
|
|
print("\n❌ uv не установлен или недоступен!") |
|
|
print("Установите uv: pip install uv") |
|
|
return False |
|
|
except FileNotFoundError: |
|
|
print("\n❌ uv не найден в PATH!") |
|
|
print("Установите uv: pip install uv") |
|
|
return False |
|
|
|
|
|
|
|
|
print("\n📦 Проверка PyInstaller...") |
|
|
try: |
|
|
result = subprocess.run(['uv', 'pip', 'list'], capture_output=True, text=True) |
|
|
if 'pyinstaller' in result.stdout.lower(): |
|
|
print("✓ PyInstaller установлен") |
|
|
else: |
|
|
print("⚠️ PyInstaller не установлен, установим его...") |
|
|
subprocess.run(['uv', 'pip', 'install', 'pyinstaller>=6.0.0']) |
|
|
except Exception as e: |
|
|
print(f"⚠️ Не смогли проверить PyInstaller: {e}") |
|
|
|
|
|
|
|
|
required_files = [ |
|
|
'run_gui.py', |
|
|
'build_windows.spec', |
|
|
'medical_terms.txt', |
|
|
'app/gui_app.py', |
|
|
'pipeline/medical_pipeline.py', |
|
|
'corrector/report_generator.py', |
|
|
] |
|
|
|
|
|
print("\n📋 Проверка необходимых файлов:") |
|
|
for file in required_files: |
|
|
file_path = root_dir / file |
|
|
if file_path.exists(): |
|
|
print(f" ✓ {file}") |
|
|
else: |
|
|
print(f" ❌ {file} - НЕ НАЙДЕН!") |
|
|
return False |
|
|
|
|
|
|
|
|
print("\n🧹 Очистка старых сборок...") |
|
|
for folder in ['dist', 'build', '__pycache__']: |
|
|
folder_path = root_dir / folder |
|
|
if folder_path.exists(): |
|
|
shutil.rmtree(folder_path) |
|
|
print(f" Удалена папка: {folder}") |
|
|
|
|
|
|
|
|
print("\n🔨 Сборка приложения с PyInstaller...") |
|
|
spec_file = root_dir / 'build_windows.spec' |
|
|
|
|
|
cmd = [ |
|
|
'uv', |
|
|
'run', |
|
|
'--', |
|
|
'pyinstaller', |
|
|
'--onefile', |
|
|
'--windowed', |
|
|
'--name=MedicalTranscriber', |
|
|
str(spec_file) |
|
|
] |
|
|
|
|
|
print(f"Команда: {' '.join(cmd)}\n") |
|
|
|
|
|
try: |
|
|
result = subprocess.run(cmd, cwd=str(root_dir), capture_output=False, text=True) |
|
|
|
|
|
if result.returncode != 0: |
|
|
print(f"\n❌ Ошибка при сборке с кодом {result.returncode}") |
|
|
return False |
|
|
|
|
|
except Exception as e: |
|
|
print(f"\n❌ Ошибка при запуске PyInstaller: {e}") |
|
|
return False |
|
|
|
|
|
|
|
|
exe_path = root_dir / 'dist' / 'MedicalTranscriber.exe' |
|
|
if exe_path.exists(): |
|
|
size_mb = exe_path.stat().st_size / (1024 * 1024) |
|
|
print(f"\n✅ Сборка успешна!") |
|
|
print(f"📦 {exe_path.name} ({size_mb:.1f} МБ)") |
|
|
print(f"📍 Расположение: {exe_path.parent}") |
|
|
return True |
|
|
else: |
|
|
print(f"\n⚠️ Файл .exe не найден в {exe_path.parent}") |
|
|
print("Проверьте наличие dist/ папки и наличие ошибок выше") |
|
|
return False |
|
|
|
|
|
|
|
|
def main(): |
|
|
"""Главная функция""" |
|
|
success = build_exe() |
|
|
|
|
|
if success: |
|
|
print("\n" + "=" * 60) |
|
|
print("🎉 Приложение успешно собрано!") |
|
|
print("=" * 60) |
|
|
print("\nДля запуска приложения:") |
|
|
print(" dist\\MedicalTranscriber.exe") |
|
|
print("\nИли двойной клик на файл в проводнике Windows") |
|
|
return 0 |
|
|
else: |
|
|
print("\n" + "=" * 60) |
|
|
print("❌ Сборка не удалась") |
|
|
print("=" * 60) |
|
|
print("\nДля отладки:") |
|
|
print(" 1. Убедитесь что uv установлен: uv --version") |
|
|
print(" 2. Установите зависимости: uv pip install -r requirements.txt") |
|
|
print(" 3. Запустите сборку: python build_exe.py") |
|
|
return 1 |
|
|
|
|
|
|
|
|
if __name__ == '__main__': |
|
|
sys.exit(main()) |
|
|
|