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(): 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") 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") settings = Settings()