1 line
13 KiB
JSON
1 line
13 KiB
JSON
{"repo": "825824004/nas115", "files": {"backend/app/config.py": {"22891c2f2d6d90e39d8cceb0c17eddaf2eb258c1": {"t": 1785746885.6988833, "n": 11037, "h": "794e09f24f6579c6", "c": "\"\"\"配置管理 — 环境变量 + 数据库运行时配置\"\"\"\n\nimport logging\nimport os\nfrom functools import lru_cache\nfrom typing import List, Optional\n\nfrom pydantic import Field\nfrom pydantic_settings import BaseSettings\n\nlogger = logging.getLogger(__name__)\n\n\nclass Settings(BaseSettings):\n \"\"\"全局配置:环境变量初始化 + 数据库运行时覆盖\"\"\"\n\n # ── 通用 ──\n tz: str = \"Asia/Shanghai\"\n secret_key: str = Field(default=\"change-me\", alias=\"SECRET_KEY\")\n backend_port: int = 8088\n\n # ── AI 引擎 ──\n ai_base_url: str = Field(default=\"https://api.deepseek.com/v1\", alias=\"AI_BASE_URL\")\n ai_api_key: str = Field(default=\"\", alias=\"AI_API_KEY\")\n ai_model: str = Field(default=\"deepseek-chat\", alias=\"AI_MODEL\")\n ai_fallback_model: str = Field(default=\"\", alias=\"AI_FALLBACK_MODEL\")\n ai_max_history: int = Field(default=20, alias=\"AI_MAX_HISTORY\")\n ai_max_tokens: int = Field(default=2048, alias=\"AI_MAX_TOKENS\")\n ai_temperature: float = Field(default=0.7, alias=\"AI_TEMPERATURE\")\n\n # ── AI Agent (V2.0 参考 MoviePilot) ──\n ai_agent_enable: bool = Field(default=True, alias=\"AI_AGENT_ENABLE\")\n ai_agent_global: bool = Field(default=True, alias=\"AI_AGENT_GLOBAL\")\n ai_agent_verbose: bool = Field(default=False, alias=\"AI_AGENT_VERBOSE\")\n ai_agent_max_iterations: int = Field(default=5, alias=\"AI_AGENT_MAX_ITERATIONS\")\n ai_recommend_enabled: bool = Field(default=True, alias=\"AI_RECOMMEND_ENABLED\")\n ai_recommend_user_preference: str = Field(default=\"\", alias=\"AI_RECOMMEND_USER_PREFERENCE\")\n api_token: str = Field(default=\"\", alias=\"API_TOKEN\")\n\n # ── 115 网盘 ──\n pan115_cookie: str = Field(default=\"\", alias=\"PAN115_COOKIE\")\n pan115_default_target_dir: str = Field(default=\"/NAS115转存\", alias=\"PAN115_DEFAULT_TARGET_DIR\")\n pan115_transfer_timeout: int = Field(default=120, alias=\"PAN115_TRANSFER_TIMEOUT\")\n\n # ── Telegram (频道搜索 + Bot) ──\n tg_api_id: str = Field(default=\"\", alias=\"TG_API_ID\")\n tg_api_hash: str = Field(default=\"\", alias=\"TG_API_HASH\")\n tg_phone: str = Field(default=\"\", alias=\"TG_PHONE\")\n tg_channels: str = Field(default=\"tgsearchers3\", alias=\"TG_CHANNELS\")\n tg_history_limit: int = Field(default=200, alias=\"TG_HISTORY_LIMIT\")\n tg_search_timeout: int = Field(default=30, alias=\"TG_SEARCH_TIMEOUT\")\n tg_proxy: str = Field(default=\"\", alias=\"TG_PROXY\")\n # TG Bot (参考 media_automator)\n tg_bot_token: str = Field(default=\"\", alias=\"TG_BOT_TOKEN\")\n tg_bot_enabled: bool = Field(default=False, alias=\"TG_BOT_ENABLED\")\n tg_bot_admin_ids: str = Field(default=\"\", alias=\"TG_BOT_ADMIN_IDS\")\n tg_bot_monitor_channels: bool = Field(default=True, alias=\"TG_BOT_MONITOR_CHANNELS\")\n tg_bot_notify_on_complete: bool = Field(default=True, alias=\"TG_BOT_NOTIFY_ON_COMPLETE\")\n\n # ── HDHive / 第三方 ──\n hdhive_base_url: str = Field(default=\"https://hdhive.site\", alias=\"HDHIVE_BASE_URL\")\n hdhive_cookie: str = Field(default=\"\", alias=\"HDHIVE_COOKIE\")\n haisou_api_key: str = Field(default=\"\", alias=\"HAISOU_API_KEY\")\n custom_sources_url: str = Field(default=\"\", alias=\"CUSTOM_SOURCES_URL\")\n\n # ── PanSou ──\n pansou_api_url: str = Field(default=\"\", alias=\"PANSOU_API_URL\")\n pansou_api_token: str = Field(default=\"\", alias=\"PANSOU_API_TOKEN\")\n\n # ── 搜索 ──\n search_concurrency: int = Field(default=5, alias=\"SEARCH_CONCURRENCY\")\n search_source_timeout: int = Field(default=30, alias=\"SEARCH_SOURCE_TIMEOUT\")\n search_cache_ttl: int = Field(default=60, alias=\"SEARCH_CACHE_TTL\")\n max_search_results: int = Field(default=50, alias=\"MAX_SEARCH_RESULTS\")\n search_exclude_keywords: str = Field(default=\"\", alias=\"SEARCH_EXCLUDE_KEYWORDS\")\n search_include_keywords: str = Field(default=\"\", alias=\"SEARCH_INCLUDE_KEYWORDS\")\n\n # ── 任务 ──\n task_max_retries: int = Field(default=3, alias=\"TASK_MAX_RETRIES\")\n task_timeout: int = Field(default=300, alias=\"TASK_TIMEOUT\")\n ws_heartbeat_interval: int = Field(default=30, alias=\"WS_HEARTBEAT_INTERVAL\")\n\n # ── 运行时覆盖标志 ──\n _runtime_overrides: dict = {}\n\n @property\n def tg_channel_list(self) -> List[str]:\n return [c.strip() for c in self.tg_channels.split(\",\") if c.strip()]\n\n @property\n def tg_bot_admin_id_list(self) -> List[int]:\n return [int(x.strip()) for x in self.tg_bot_admin_ids.split(\",\") if x.strip().isdigit()]\n\n @property\n def has_ai_config(self) -> bool:\n return bool(self.ai_api_key and self.ai_base_url)\n\n @property\n def has_tg_config(self) -> bool:\n return bool(self.tg_api_id and self.tg_api_hash)\n\n @property\n def has_tg_bot_config(self) -> bool:\n return bool(self.tg_bot_token and self.tg_bot_enabled)\n\n @property\n def has_pan115_config(self) -> bool:\n return bool(self.pan115_cookie)\n\n @property\n def has_pansou_config(self) -> bool:\n return bool(self.pansou_api_url)\n\n @property\n def has_hdhive_config(self) -> bool:\n return bool(self.hdhive_base_url and self.hdhive_cookie)\n\n @property\n def has_haisou_config(self) -> bool:\n return bool(self.haisou_api_key)\n\n @property\n def search_exclude_list(self) -> List[str]:\n return [k.strip() for k in self.search_exclude_keywords.split(\",\") if k.strip()]\n\n @property\n def has_mcp_auth(self) -> bool:\n return bool(self.api_token)\n\n # ── 运行时配置覆盖 ──\n\n def apply_runtime_overrides(self, overrides: dict):\n \"\"\"从数据库加载运行时覆盖\"\"\"\n self._runtime_overrides = overrides or {}\n for key, value in self._runtime_overrides.items():\n if hasattr(self, key):\n setattr(self, key, value)\n logger.info(f\"已加载 {len(self._runtime_overrides)} 项运行时配置\")\n\n def get_runtime_overrides(self) -> dict:\n return dict(self._runtime_overrides)\n\n class Config:\n env_file = \".env\"\n env_file_encoding = \"utf-8\"\n extra = \"ignore\"\n\n\n@lru_cache()\ndef get_settings() -> Settings:\n return Settings()\n\n\n# ── 配置 Schema (供前端生成设置表单) ──\n\nSETTINGS_SCHEMA = [\n {\n \"group\": \"AI 引擎\",\n \"icon\": \"brain\",\n \"test_module\": \"ai\",\n \"fields\": [\n {\"key\": \"ai_base_url\", \"label\": \"API Base URL\", \"type\": \"text\", \"placeholder\": \"https://api.deepseek.com/v1\"},\n {\"key\": \"ai_api_key\", \"label\": \"API Key\", \"type\": \"password\", \"placeholder\": \"sk-...\"},\n {\"key\": \"ai_model\", \"label\": \"模型\", \"type\": \"text\", \"placeholder\": \"deepseek-chat\"},\n {\"key\": \"ai_fallback_model\", \"label\": \"备用模型\", \"type\": \"text\", \"placeholder\": \"可选\"},\n {\"key\": \"ai_max_history\", \"label\": \"最大对话轮数\", \"type\": \"number\", \"default\": 20},\n {\"key\": \"ai_max_tokens\", \"label\": \"最大 Token\", \"type\": \"number\", \"default\": 2048},\n {\"key\": \"ai_temperature\", \"label\": \"温度\", \"type\": \"number\", \"step\": 0.1, \"default\": 0.7},\n {\"key\": \"ai_agent_enable\", \"label\": \"启用 Agent 模式\", \"type\": \"toggle\", \"default\": True},\n {\"key\": \"ai_agent_max_iterations\", \"label\": \"Agent 最大迭代\", \"type\": \"number\", \"default\": 5},\n {\"key\": \"ai_recommend_enabled\", \"label\": \"启用 AI 推荐\", \"type\": \"toggle\", \"default\": True},\n {\"key\": \"ai_recommend_user_preference\", \"label\": \"推荐偏好\", \"type\": \"textarea\", \"placeholder\": \"优先4K WEB-DL,避免枪版...\"},\n ],\n },\n {\n \"group\": \"115 网盘\",\n \"icon\": \"cloud\",\n \"test_module\": \"pan115\",\n \"fields\": [\n {\"key\": \"pan115_cookie\", \"label\": \"Cookie\", \"type\": \"textarea\", \"placeholder\": \"UID=...; CID=...; SEID=...; KID=...\"},\n {\"key\": \"pan115_default_target_dir\", \"label\": \"默认转存目录\", \"type\": \"text\", \"placeholder\": \"/NAS115转存\"},\n {\"key\": \"pan115_transfer_timeout\", \"label\": \"转存超时(秒)\", \"type\": \"number\", \"default\": 120},\n ],\n },\n {\n \"group\": \"Telegram\",\n \"icon\": \"telegram\",\n \"test_module\": \"telegram\",\n \"fields\": [\n {\"key\": \"tg_api_id\", \"label\": \"API ID\", \"type\": \"text\", \"placeholder\": \"1234567\"},\n {\"key\": \"tg_api_hash\", \"label\": \"API Hash\", \"type\": \"password\", \"placeholder\": \"abcdef...\"},\n {\"key\": \"tg_phone\", \"label\": \"手机号\", \"type\": \"text\", \"placeholder\": \"+8613800138000\"},\n {\"key\": \"tg_channels\", \"label\": \"搜索频道(逗号分隔)\", \"type\": \"textarea\", \"placeholder\": \"tgsearchers3,channel2\"},\n {\"key\": \"tg_history_limit\", \"label\": \"历史消息数\", \"type\": \"number\", \"default\": 200},\n {\"key\": \"tg_search_timeout\", \"label\": \"搜索超时(秒)\", \"type\": \"number\", \"default\": 30},\n {\"key\": \"tg_proxy\", \"label\": \"代理\", \"type\": \"text\", \"placeholder\": \"socks5://127.0.0.1:7890\"},\n ],\n },\n {\n \"group\": \"TG Bot\",\n \"icon\": \"bot\",\n \"test_module\": \"tgbot\",\n \"fields\": [\n {\"key\": \"tg_bot_enabled\", \"label\": \"启用 TG Bot\", \"type\": \"toggle\", \"default\": False},\n {\"key\": \"tg_bot_token\", \"label\": \"Bot Token\", \"type\": \"password\", \"placeholder\": \"123456:ABC-DEF...\"},\n {\"key\": \"tg_bot_admin_ids\", \"label\": \"管理员 ID(逗号分隔)\", \"type\": \"text\", \"placeholder\": \"123456789\"},\n {\"key\": \"tg_bot_monitor_channels\", \"label\": \"监控频道新消息\", \"type\": \"toggle\", \"default\": True},\n {\"key\": \"tg_bot_notify_on_complete\", \"label\": \"任务完成通知\", \"type\": \"toggle\", \"default\": True},\n ],\n },\n {\n \"group\": \"搜索源 — 盘搜 & 第三方\",\n \"icon\": \"search\",\n \"fields\": [\n {\"key\": \"pansou_api_url\", \"label\": \"盘搜 API URL\", \"type\": \"text\", \"placeholder\": \"http://localhost:8080 (自建PanSou实例)\", \"test_module\": \"pansou\"},\n {\"key\": \"pansou_api_token\", \"label\": \"盘搜 Token\", \"type\": \"password\", \"placeholder\": \"可选\"},\n {\"key\": \"hdhive_base_url\", \"label\": \"HDHive URL\", \"type\": \"text\", \"placeholder\": \"https://hdhive.site\", \"test_module\": \"hdhive\"},\n {\"key\": \"hdhive_cookie\", \"label\": \"HDHive Cookie\", \"type\": \"textarea\", \"placeholder\": \"session=...\"},\n {\"key\": \"haisou_api_key\", \"label\": \"海搜 API Key\", \"type\": \"password\", \"placeholder\": \"可选\", \"test_module\": \"haisou\"},\n {\"key\": \"custom_sources_url\", \"label\": \"自定义源 URL\", \"type\": \"text\", \"placeholder\": \"可选\"},\n ],\n },\n {\n \"group\": \"搜索配置\",\n \"icon\": \"filter\",\n \"fields\": [\n {\"key\": \"search_concurrency\", \"label\": \"并发搜索数\", \"type\": \"number\", \"default\": 5},\n {\"key\": \"search_source_timeout\", \"label\": \"单源超时(秒)\", \"type\": \"number\", \"default\": 30},\n {\"key\": \"max_search_results\", \"label\": \"最大结果数\", \"type\": \"number\", \"default\": 50},\n {\"key\": \"search_exclude_keywords\", \"label\": \"排除关键词(逗号分隔)\", \"type\": \"textarea\", \"placeholder\": \"枪版,抢先版,CAM\"},\n {\"key\": \"search_include_keywords\", \"label\": \"包含关键词(逗号分隔)\", \"type\": \"textarea\", \"placeholder\": \"可选\"},\n ],\n },\n {\n \"group\": \"任务与安全\",\n \"icon\": \"shield\",\n \"fields\": [\n {\"key\": \"task_max_retries\", \"label\": \"最大重试\", \"type\": \"number\", \"default\": 3},\n {\"key\": \"task_timeout\", \"label\": \"任务超时(秒)\", \"type\": \"number\", \"default\": 300},\n {\"key\": \"api_token\", \"label\": \"API Token (MCP认证)\", \"type\": \"password\", \"placeholder\": \"可选\"},\n ],\n },\n]\n"}}}} |