""" Paths Module. ============= This module handles all file system path resolution for the application. It is critical for ensuring portability, distinguishing between: 1. Running as a raw Python script (using `__file__`). 2. Running as a frozen PyInstaller EXE (using `sys.executable`). It creates necessary directories (models, libs) if they do not exist. """ import sys import os from pathlib import Path from typing import Optional def get_bundle_path() -> Path: """ Returns the root directory of the application bundle. When frozen, this is the internal temporary directory (sys._MEIPASS). When running as script, this is the project root. Use this for bundled assets like QML, SVGs, etc. """ if getattr(sys, 'frozen', False): return Path(sys._MEIPASS) # Project root (assuming this file is at src/core/paths.py) return Path(__file__).resolve().parent.parent.parent def get_base_path() -> Path: """ Returns the directory where persistent data should be stored. Always points to the directory containing the .exe or the project root. Use this for models, settings, recordings. """ if getattr(sys, 'frozen', False): return Path(sys.executable).parent return get_bundle_path() def get_models_path() -> Path: """ Returns the absolute path to the 'models' directory. This directory is used to store the Whisper AI model files. The directory is automatically created if it does not exist. Returns: Path: Absolute path to the ./models directory next to the output binary. """ path = get_base_path() / "models" path.mkdir(parents=True, exist_ok=True) return path def get_libs_path() -> Path: """ Returns the absolute path to the 'libs' directory. This directory is used to store external binaries like `ffmpeg.exe`. The directory is automatically created if it does not exist. Returns: Path: Absolute path to the ./libs directory next to the output binary. """ path = get_base_path() / "libs" path.mkdir(parents=True, exist_ok=True) return path def get_ffmpeg_path() -> str: """ Resolves the path to the FFmpeg executable. Logic: 1. Checks for `ffmpeg.exe` in the local `./libs` folder. 2. Fallbacks to the system-wide "ffmpeg" command if local file is missing. Returns: str: Absolute path to the local binary, or just "ffmpeg" string for system PATH lookup. """ libs_path = get_libs_path() ffmpeg_exe = libs_path / "ffmpeg.exe" if ffmpeg_exe.exists(): return str(ffmpeg_exe.absolute()) # Fallback to system PATH return "ffmpeg"