- 修复Redis认证 (配置密码) - 启动Python管理后台 (端口9531, 15个功能开关) - 统一版本号 0.2.7 - 更新docker-compose.yml (镜像版本/Redis URL/Admin服务)
173 lines
6.7 KiB
Python
173 lines
6.7 KiB
Python
"""
|
||
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_<PLATFORM>_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)
|