| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- """DMS环境配置。"""
- from __future__ import annotations
- import os
- from pathlib import Path
- from typing import Any
- from zoneinfo import ZoneInfo, ZoneInfoNotFoundError
- import shutil
- BACKEND_ROOT = Path(__file__).resolve().parents[1]
- DEFAULT_STORAGE_ROOT = BACKEND_ROOT / "dms-storage"
- DEFAULT_UI_DICTIONARY_CONFIG_PATH = (
- BACKEND_ROOT / "dms" / "resources" / "ui-dictionaries.zh-CN.json"
- )
- DEFAULT_DATABASE_URL = (
- "mysql+pymysql://dms_app:change-me@127.0.0.1:3306/dms?charset=utf8mb4"
- )
- def _positive_int(name: str, default: int) -> int:
- raw_value = os.environ.get(name)
- if raw_value is None or not raw_value.strip():
- return default
- try:
- value = int(raw_value)
- except ValueError as exc:
- raise ValueError(f"{name}必须是正整数") from exc
- if value <= 0:
- raise ValueError(f"{name}必须是正整数")
- return value
- def load_dms_config() -> dict[str, Any]:
- """从环境变量加载DMS配置,不读取或覆盖现有AI配置。"""
- storage_value = os.environ.get("DMS_STORAGE_ROOT", "").strip()
- storage_root = Path(storage_value or DEFAULT_STORAGE_ROOT).expanduser()
- max_upload_size = _positive_int(
- "DMS_MAX_UPLOAD_SIZE", 100 * 1024 * 1024
- )
- max_file_size = _positive_int(
- "DMS_MAX_FILE_SIZE", min(50 * 1024 * 1024, max_upload_size)
- )
- if max_file_size > max_upload_size:
- raise ValueError("DMS_MAX_FILE_SIZE不得超过DMS_MAX_UPLOAD_SIZE")
- database_url = os.environ.get("DMS_DATABASE_URL", "").strip()
- ui_dictionary_config_value = os.environ.get(
- "DMS_UI_DICTIONARY_CONFIG_PATH", ""
- ).strip()
- ui_dictionary_config_path = Path(
- ui_dictionary_config_value or DEFAULT_UI_DICTIONARY_CONFIG_PATH
- ).expanduser()
- business_timezone = (
- os.environ.get("DMS_BUSINESS_TIMEZONE", "").strip()
- or "Asia/Shanghai"
- )
- try:
- ZoneInfo(business_timezone)
- except (ZoneInfoNotFoundError, ValueError) as exc:
- raise ValueError("DMS_BUSINESS_TIMEZONE必须是有效的IANA时区") from exc
- office_preview_enabled = (
- os.environ.get("DMS_OFFICE_PREVIEW_ENABLED", "true").strip().lower()
- in {"1", "true", "yes", "on"}
- )
- libreoffice_executable = (
- os.environ.get("DMS_LIBREOFFICE_EXECUTABLE", "").strip()
- or shutil.which("soffice")
- or shutil.which("libreoffice")
- or ""
- )
- libreoffice_timeout_seconds = _positive_int(
- "DMS_LIBREOFFICE_TIMEOUT_SECONDS", 60
- )
- libreoffice_max_concurrency = _positive_int(
- "DMS_LIBREOFFICE_MAX_CONCURRENCY", 2
- )
- pdf_viewer_engine_raw = (
- os.environ.get("DMS_PDF_VIEWER_ENGINE", "iframe").strip().lower()
- )
- pdf_viewer_engine = (
- pdf_viewer_engine_raw if pdf_viewer_engine_raw in {"iframe", "pdfjs"} else "iframe"
- )
- return {
- "SQLALCHEMY_DATABASE_URI": database_url or DEFAULT_DATABASE_URL,
- "SQLALCHEMY_TRACK_MODIFICATIONS": False,
- "SQLALCHEMY_ENGINE_OPTIONS": {
- "isolation_level": "READ COMMITTED",
- "pool_pre_ping": True,
- "pool_recycle": 1800,
- "connect_args": {
- "init_command": "SET time_zone = '+00:00'",
- },
- },
- "DMS_STORAGE_ROOT": str(storage_root.resolve()),
- "DMS_MAX_UPLOAD_SIZE": max_upload_size,
- "DMS_MAX_FILE_SIZE": max_file_size,
- "MAX_CONTENT_LENGTH": max_upload_size,
- "DMS_BATCH_MAX_FILES": _positive_int("DMS_BATCH_MAX_FILES", 50),
- "DMS_BUSINESS_TIMEZONE": business_timezone,
- "DMS_JWT_SECRET": os.environ.get("DMS_JWT_SECRET", ""),
- "DMS_JWT_ISSUER": "dms",
- "DMS_JWT_EXPIRES_SECONDS": 7200,
- "DMS_JWT_KEEP_SIGNED_IN_EXPIRES_SECONDS": 604800,
- "DMS_UI_DICTIONARY_CONFIG_PATH": str(
- ui_dictionary_config_path.resolve()
- ),
- "DMS_OFFICE_PREVIEW_ENABLED": office_preview_enabled,
- "DMS_LIBREOFFICE_EXECUTABLE": libreoffice_executable,
- "DMS_LIBREOFFICE_TIMEOUT_SECONDS": libreoffice_timeout_seconds,
- "DMS_LIBREOFFICE_MAX_CONCURRENCY": libreoffice_max_concurrency,
- "DMS_PDF_VIEWER_ENGINE": pdf_viewer_engine,
- }
|