import os import sys def _app_dir(): if getattr(sys, "frozen", False): # PyInstaller onefile: assets read-only nằm trong thư mục giải nén tạm return os.path.join(sys._MEIPASS, "app") return os.path.dirname(os.path.abspath(__file__)) def _storage_dir(): # Test/dev isolation: env override thắng (pytest set để không đụng storage # thật — app production có thể đang chạy và ghi file state). env_dir = os.getenv("SONICFORGE_STORAGE_DIR") if env_dir: return env_dir if getattr(sys, "frozen", False): # Dữ liệu ghi được (DB, uploads, processed) phải ngoài thư mục tạm root = os.environ.get("APPDATA") or os.path.expanduser("~") return os.path.join(root, "SonicForgeDAW", "storage") return os.path.join(_app_dir(), "storage") def _default_vst_dir(): """Thư mục VST mặc định theo platform (env VST_DIR vẫn thắng). Windows: thư mục VST3 chuẩn của hệ thống — user có thể thêm thư mục khác qua Plugins Manager (plugin_dirs.json). Docker/Linux: mount qua compose.""" if os.name == "nt": pf = os.environ.get("ProgramFiles", r"C:\Program Files") return os.path.join(pf, "Common Files", "VST3") if sys.platform == "darwin": return "/Library/Audio/Plug-Ins/VST3" return "/opt/daw_engine/vst3" def _default_soundfont_dir(): if os.name == "nt": root = os.environ.get("APPDATA") or os.path.expanduser("~") return os.path.join(root, "SonicForgeDAW", "soundfonts") if sys.platform == "darwin": return os.path.expanduser("~/Music/SonicForgeDAW/soundfonts") return "/opt/daw_engine/soundfonts" class Settings: REDIS_URL: str = os.getenv("REDIS_URL", "redis://localhost:6379/0") CELERY_BROKER_URL: str = os.getenv("CELERY_BROKER_URL", "redis://localhost:6379/0") CELERY_RESULT_BACKEND: str = os.getenv("CELERY_RESULT_BACKEND", "redis://localhost:6379/0") APP_DIR: str = _app_dir() BASE_DIR: str = os.path.dirname(APP_DIR) TEMPLATES_DIR: str = os.path.join(APP_DIR, "templates") STORAGE_DIR: str = _storage_dir() UPLOADS_DIR: str = os.path.join(STORAGE_DIR, "uploads") PROCESSED_DIR: str = os.path.join(STORAGE_DIR, "processed") # Plugin dirs — người dùng khai báo qua .env / docker-compose (Docker) # hoặc qua Plugins Manager (Windows/macOS, lưu theo user). Default theo # platform (Windows: thư mục VST3 chuẩn; Linux: mount compose). VST_DIR: str = os.getenv("VST_DIR", _default_vst_dir()) SOUNDFONT_DIR: str = os.getenv("SOUNDFONT_DIR", _default_soundfont_dir()) # Thư viện preset VST3 (.vstpreset) — cầu nối Carla → pedalboard. # Nằm trong storage nên tự động nằm trong volume mount (docker) / thư mục # storage (Windows desktop). PRESET_DIR: str = os.path.join(STORAGE_DIR, "presets") settings = Settings()