""" CookieCloud数据模型 """ from dataclasses import dataclass, field from typing import Optional, Dict, List from datetime import datetime @dataclass class CookieConfig: """CookieCloud配置""" server: str username: str password: str timeout: int = 30 verify_ssl: bool = True ignore_cookies: List[str] = field(default_factory=lambda: [ "CookieAutoDeleteBrowsingDataCleanup", "CookieAutoDeleteCleaningDiscarded" ]) def __post_init__(self): """验证配置参数""" if not self.server: raise ValueError("服务器地址不能为空") if not self.username: raise ValueError("用户名不能为空") if not self.password: raise ValueError("密码不能为空") if not self.server.startswith(('http://', 'https://')): self.server = f"https://{self.server}" @dataclass class CookieData: """Cookie数据""" domain: str name: str value: str path: str = "/" secure: bool = False http_only: bool = False expiry: Optional[datetime] = None def to_dict(self) -> Dict: """转换为字典""" return { 'domain': self.domain, 'name': self.name, 'value': self.value, 'path': self.path, 'secure': self.secure, 'httpOnly': self.http_only, 'expiry': self.expiry.isoformat() if self.expiry else None } @classmethod def from_dict(cls, data: Dict) -> 'CookieData': """从字典创建""" expiry = None if data.get('expiry'): try: expiry = datetime.fromisoformat(data['expiry']) except (ValueError, TypeError): pass return cls( domain=data.get('domain', ''), name=data.get('name', ''), value=data.get('value', ''), path=data.get('path', '/'), secure=data.get('secure', False), http_only=data.get('httpOnly', False), expiry=expiry ) @dataclass class CookieCollection: """Cookie集合""" domain: str cookies: List[CookieData] = field(default_factory=list) def to_cookie_string(self, ignore_list: List[str] = None) -> str: """转换为cookie字符串""" ignore_list = ignore_list or [] cookie_parts = [] for cookie in self.cookies: if cookie.name not in ignore_list: cookie_parts.append(f"{cookie.name}={cookie.value}") return ";".join(cookie_parts) def add_cookie(self, cookie: CookieData): """添加cookie""" self.cookies.append(cookie) def get_cookie_by_name(self, name: str) -> Optional[CookieData]: """根据名称获取cookie""" for cookie in self.cookies: if cookie.name == name: return cookie return None @dataclass class DownloadResult: """下载结果""" success: bool cookies: Dict[str, CookieCollection] = field(default_factory=dict) error_message: str = "" total_domains: int = 0 total_cookies: int = 0 download_time: float = 0.0 def get_cookie_string(self, domain: str) -> Optional[str]: """获取指定域名的cookie字符串""" collection = self.cookies.get(domain) if collection: return collection.to_cookie_string() return None def get_domains(self) -> List[str]: """获取所有域名列表""" return list(self.cookies.keys())