Files
MoviePilot/app/foundation/environment.py
DDSRem 2de976f6b3 Merge pull request #7050 from DDSRem-Dev/codex-comment-migration
docs: 统一全项目中文注释和结构化契约说明
2026-10-17 19:26:29 +08:00

131 lines
3.0 KiB
Python

"""
不依赖运行时和适配器的宿主环境探测原语。
"""
import os
import platform
import sys
import sysconfig
from pathlib import Path
from typing import Optional
def is_docker() -> bool:
"""
判断当前进程是否运行在约定的 Docker 环境中。
"""
return Path("/.dockerenv").exists()
def is_frozen() -> bool:
"""
判断当前 Python 进程是否为冻结二进制。
"""
return bool(getattr(sys, "frozen", False))
def is_free_threaded_runtime() -> bool:
"""
判断当前解释器是否为 CPython 无全局解释器锁构建。
"""
gil_disabled: object = sysconfig.get_config_var("Py_GIL_DISABLED")
return gil_disabled == 1
def is_gil_enabled() -> bool:
"""
返回当前 CPython 进程是否实际启用了 GIL。
"""
return sys._is_gil_enabled()
def is_windows() -> bool:
"""
判断当前操作系统是否为 Windows。
"""
return os.name == "nt"
def is_exe() -> bool:
"""
判断当前是否为 MoviePilot-V3.exe 部署环境。
"""
if not is_windows():
return False
try:
return Path.exists(Path(__file__).parents[4] / "MoviePilot-V3.exe")
except PermissionError:
return False
def is_macos() -> bool:
"""
判断当前操作系统是否为 macOS。
"""
return platform.system() == "Darwin"
def is_aarch64() -> bool:
"""
判断当前 CPU 是否属于 64 位 ARM 架构。
"""
return platform.machine().lower() in {"aarch64", "arm64"}
def is_aarch() -> bool:
"""
判断当前 CPU 是否属于非 64 位 ARM 架构。
"""
arch_name = platform.machine().lower()
return arch_name.startswith(("arm", "aarch")) and not is_aarch64()
def is_x86_64() -> bool:
"""
判断当前 CPU 是否属于 64 位 x86 架构。
"""
return platform.machine().lower() in {"amd64", "x86_64"}
def is_x86_32() -> bool:
"""
判断当前 CPU 是否属于 32 位 x86 架构。
"""
return platform.machine().lower() in {"i386", "i686", "x86", "386", "x86_32"}
def cpu_arch() -> str:
"""
返回 MoviePilot 既有合同使用的 CPU 架构名称。
"""
if is_x86_64():
return "x86_64"
if is_x86_32():
return "x86_32"
if is_aarch64():
return "Arm64"
if is_aarch():
return "Arm32"
return platform.machine()
def get_config_path(config_dir: Optional[str] = None) -> Path:
"""
按显式目录、容器、冻结进程和源码运行顺序确定配置目录。
"""
configured = config_dir or os.getenv("CONFIG_DIR")
if configured:
return Path(configured)
if is_docker():
return Path("/config")
if is_frozen():
return Path(sys.executable).parent / "config"
return Path(__file__).resolve().parents[2] / "config"
def get_env_path(config_dir: Optional[str] = None) -> Path:
"""
返回给定运行环境对应的 ``app.env`` 文件路径。
"""
return get_config_path(config_dir) / "app.env"