""" CloudSearch Transfer — 适配器工厂 v1.0.0 参考 cloud-auto-save 的 AdapterFactory + AccountManager """ import hashlib import logging from typing import Optional, Dict, Type from .base import BaseCloudDriveAdapter, match_url from ..config import ConfigManager from ..errors import TransferError, TransferErrorCode logger = logging.getLogger(__name__) class AdapterFactory: """ 适配器工厂 - URL正则自动识别网盘类型 - 实例缓存:同平台+同Cookie单例 - 多账号路由 """ # 平台注册表(延迟导入避免循环引用) _registry: Dict[str, Type[BaseCloudDriveAdapter]] = {} # 实例缓存 key: "platform:cookie_hash[:16]" _cache: Dict[str, BaseCloudDriveAdapter] = {} def __init__(self, config_manager: ConfigManager): self.config_manager = config_manager self._register_all() def _register_all(self): """注册所有平台适配器""" from .quark import QuarkAdapter from .baidu import BaiduAdapter from .aliyun import AliyunAdapter from .uc import UcAdapter from .xunlei import XunleiAdapter from .pan115 import Pan115Adapter from .pan123 import Pan123Adapter from .cloud189 import Cloud189Adapter self._registry = { "quark": QuarkAdapter, "baidu": BaiduAdapter, "aliyun": AliyunAdapter, "uc": UcAdapter, "xunlei": XunleiAdapter, "pan115": Pan115Adapter, "pan123": Pan123Adapter, "cloud189": Cloud189Adapter, } def detect_platform(self, url: str) -> Optional[str]: """根据URL自动识别网盘平台""" for platform_key, adapter_cls in self._registry.items(): if match_url(url, adapter_cls): return platform_key return None def get_adapter(self, platform_key: str) -> Optional[BaseCloudDriveAdapter]: """获取适配器实例(带缓存)""" config = self.config_manager.get_platform(platform_key) if not config: return None adapter_cls = self._registry.get(platform_key) if not adapter_cls: return None # 构建缓存键 cache_key = self._cache_key(platform_key, config) if cache_key in self._cache: return self._cache[cache_key] # 创建新实例 adapter = adapter_cls(config, self.config_manager.transfer) self._cache[cache_key] = adapter logger.info(f"[Factory] Created adapter: {platform_key} " f"(cache_key={cache_key})") return adapter def get_adapter_for_url(self, url: str) -> Optional[BaseCloudDriveAdapter]: """根据URL自动获取适配器""" platform = self.detect_platform(url) if not platform: raise TransferError(TransferErrorCode.URL_INVALID, message=f"无法识别链接平台: {url}") adapter = self.get_adapter(platform) if not adapter: raise TransferError(TransferErrorCode.NO_CONFIG, message=f"平台 {platform} 未配置凭证", platform=platform) return adapter def invalidate_cache(self, platform_key: str = None): """清除缓存""" if platform_key: keys = [k for k in self._cache if k.startswith(platform_key)] for k in keys: del self._cache[k] else: self._cache.clear() def _cache_key(self, platform: str, config) -> str: """构建缓存键""" credential = config.cookie or config.refresh_token or "" token_hash = hashlib.md5(credential.encode()).hexdigest()[:16] return f"{platform}:{config.account_name}:{token_hash}"