""" CloudSearch Transfer — 配置管理 v1.0.0 支持环境变量 + JSON文件 + 数据库多级配置源 """ import os import json from pathlib import Path from typing import Optional, Dict, Any from dataclasses import dataclass, field @dataclass class PlatformConfig: """单个网盘平台的配置""" enabled: bool = False cookie: str = "" # Cookie字符串(夸克/百度/UC/123) refresh_token: str = "" # OAuth RefreshToken(阿里/迅雷) access_token: str = "" # 运行时AccessToken(自动刷新) account_name: str = "" # 账号名(多账号路由) save_dir: str = "/" # 默认转存目录 share_password: str = "" # 分享密码 banned_keywords: list = field(default_factory=list) # 广告过滤关键词 extra: Dict[str, Any] = field(default_factory=dict) # 扩展字段 @dataclass class TransferConfig: """转存服务配置""" # HTTP request_timeout: int = 30 # 请求超时(秒) max_retries: int = 3 # 最大重试次数 retry_delay: float = 1.0 # 重试延迟(秒) # 任务轮询 task_poll_interval: float = 0.5 # 轮询间隔(秒) task_poll_max_attempts: int = 50 # 最大轮询次数 task_poll_max_wait: int = 60 # 最大等待时间(秒) # 并发控制 max_concurrent_transfers: int = 5 # 最大并发转存数 transfer_queue_size: int = 100 # 转存队列大小 # 广告过滤 ad_filter_enabled: bool = True # 是否启用广告过滤 default_banned_keywords: list = field(default_factory=lambda: [ "公众号", "微信", "扫码", "加群", "QQ群", "广告", "关注", "免费领取", "点击领取", "全网", "最全", ]) # 分享设置 default_share_period: str = "permanent" # 永久/7d/30d auto_generate_password: bool = False # 自动生成分享密码 class ConfigManager: """统一配置管理器""" def __init__(self, config_path: Optional[str] = None): self._config_path = config_path or os.getenv( "TRANSFER_CONFIG_PATH", "/data/transfer_config.json" ) self.platforms: Dict[str, PlatformConfig] = {} self.transfer: TransferConfig = TransferConfig() self._load() def _load(self): """加载配置:环境变量 → JSON文件 → 默认值""" # 1. 从JSON文件加载 if Path(self._config_path).exists(): with open(self._config_path) as f: data = json.load(f) self._parse_json(data) # 2. 环境变量覆盖 self._apply_env_overrides() def _parse_json(self, data: dict): """解析JSON配置""" # 平台配置 platforms_data = data.get("platforms", {}) for name, cfg in platforms_data.items(): self.platforms[name] = PlatformConfig( enabled=cfg.get("enabled", False), cookie=cfg.get("cookie", ""), refresh_token=cfg.get("refresh_token", ""), access_token=cfg.get("access_token", ""), account_name=cfg.get("account_name", name), save_dir=cfg.get("save_dir", "/"), share_password=cfg.get("share_password", ""), banned_keywords=cfg.get("banned_keywords", []), extra=cfg.get("extra", {}), ) # 传输配置 transfer_data = data.get("transfer", {}) if transfer_data: self.transfer = TransferConfig( request_timeout=transfer_data.get("request_timeout", 30), max_retries=transfer_data.get("max_retries", 3), retry_delay=transfer_data.get("retry_delay", 1.0), task_poll_interval=transfer_data.get("task_poll_interval", 0.5), task_poll_max_attempts=transfer_data.get("task_poll_max_attempts", 50), max_concurrent_transfers=transfer_data.get("max_concurrent_transfers", 5), ad_filter_enabled=transfer_data.get("ad_filter_enabled", True), ) def _apply_env_overrides(self): """环境变量覆盖:TRANSFER__COOKIE 等""" env_map = { "quark": "QUARK", "baidu": "BAIDU", "aliyun": "ALIYUN", "uc": "UC", "xunlei": "XUNLEI", "pan123": "PAN123", "cloud189": "CLOUD189", } for platform, prefix in env_map.items(): cookie = os.getenv(f"TRANSFER_{prefix}_COOKIE") if cookie: if platform not in self.platforms: self.platforms[platform] = PlatformConfig() self.platforms[platform].cookie = cookie self.platforms[platform].enabled = True token = os.getenv(f"TRANSFER_{prefix}_REFRESH_TOKEN") if token: if platform not in self.platforms: self.platforms[platform] = PlatformConfig() self.platforms[platform].refresh_token = token self.platforms[platform].enabled = True def get_platform(self, name: str) -> Optional[PlatformConfig]: """获取平台配置""" config = self.platforms.get(name) if config and config.enabled: return config return None def get_enabled_platforms(self) -> list: """获取所有已启用的平台名""" return [name for name, cfg in self.platforms.items() if cfg.enabled] def save(self): """保存配置到文件""" data = { "platforms": { name: { "enabled": cfg.enabled, "cookie": cfg.cookie[:20] + "..." if cfg.cookie else "", "refresh_token": cfg.refresh_token[:20] + "..." if cfg.refresh_token else "", "account_name": cfg.account_name, "save_dir": cfg.save_dir, "share_password": cfg.share_password, "banned_keywords": cfg.banned_keywords, "extra": cfg.extra, } for name, cfg in self.platforms.items() }, "transfer": { "request_timeout": self.transfer.request_timeout, "max_retries": self.transfer.max_retries, "max_concurrent_transfers": self.transfer.max_concurrent_transfers, "ad_filter_enabled": self.transfer.ad_filter_enabled, } } Path(self._config_path).parent.mkdir(parents=True, exist_ok=True) with open(self._config_path, "w") as f: json.dump(data, f, indent=2, ensure_ascii=False)