216 lines
5.1 KiB
Python
216 lines
5.1 KiB
Python
"""
|
||
平台适配器基类
|
||
定义了所有平台适配器的通用接口。
|
||
"""
|
||
|
||
from abc import ABC, abstractmethod
|
||
from typing import Optional, Dict, Any
|
||
from playwright.async_api import Page
|
||
|
||
from ..core.models import (
|
||
PlatformType,
|
||
AccountInfo,
|
||
Content,
|
||
PublishResult,
|
||
UploadStatus,
|
||
PublishStatus
|
||
)
|
||
from ..auth.base_auth import BaseAuth
|
||
|
||
|
||
class BaseAdapter(ABC):
|
||
"""平台适配器基类"""
|
||
|
||
def __init__(self, platform: PlatformType):
|
||
self.platform = platform
|
||
self.platform_name = platform.value
|
||
|
||
@abstractmethod
|
||
async def login(self, account_info: AccountInfo, headless: bool = False) -> bool:
|
||
"""
|
||
登录平台
|
||
|
||
Args:
|
||
account_info: 账号信息
|
||
headless: 是否使用无头模式
|
||
|
||
Returns:
|
||
登录是否成功
|
||
"""
|
||
pass
|
||
|
||
@abstractmethod
|
||
async def publish_content(self, page: Page, content: Content, account_info: AccountInfo) -> PublishResult:
|
||
"""
|
||
发布内容
|
||
|
||
Args:
|
||
page: Playwright页面对象
|
||
content: 要发布的内容
|
||
account_info: 账号信息
|
||
|
||
Returns:
|
||
发布结果
|
||
"""
|
||
pass
|
||
|
||
@abstractmethod
|
||
async def check_login_status(self, page: Page) -> bool:
|
||
"""
|
||
检查登录状态
|
||
|
||
Args:
|
||
page: Playwright页面对象
|
||
|
||
Returns:
|
||
是否已登录
|
||
"""
|
||
pass
|
||
|
||
@abstractmethod
|
||
def get_authenticator(self) -> BaseAuth:
|
||
"""
|
||
获取认证器实例
|
||
|
||
Returns:
|
||
认证器实例
|
||
"""
|
||
pass
|
||
|
||
async def validate_content(self, content: Content) -> tuple[bool, str]:
|
||
"""
|
||
验证内容是否符合平台要求
|
||
|
||
Args:
|
||
content: 要验证的内容
|
||
|
||
Returns:
|
||
(是否有效, 错误信息)
|
||
"""
|
||
# 基础验证
|
||
if not content.title.strip():
|
||
return False, "标题不能为空"
|
||
|
||
if not content.description.strip():
|
||
return False, "内容描述不能为空"
|
||
|
||
if len(content.title) > 100:
|
||
return False, "标题过长,最多100个字符"
|
||
|
||
if len(content.description) > 1000:
|
||
return False, "内容过长,最多1000个字符"
|
||
|
||
return True, ""
|
||
|
||
async def wait_for_upload_complete(
|
||
self,
|
||
page: Page,
|
||
timeout: int = 300,
|
||
check_interval: float = 2.0
|
||
) -> bool:
|
||
"""
|
||
等待上传完成
|
||
|
||
Args:
|
||
page: Playwright页面对象
|
||
timeout: 超时时间(秒)
|
||
check_interval: 检查间隔(秒)
|
||
|
||
Returns:
|
||
上传是否完成
|
||
"""
|
||
import asyncio
|
||
start_time = asyncio.get_event_loop().time()
|
||
|
||
while asyncio.get_event_loop().time() - start_time < timeout:
|
||
if await self._check_upload_status(page):
|
||
return True
|
||
await asyncio.sleep(check_interval)
|
||
|
||
return False
|
||
|
||
async def _check_upload_status(self, page: Page) -> bool:
|
||
"""
|
||
检查上传状态(子类实现)
|
||
|
||
Args:
|
||
page: Playwright页面对象
|
||
|
||
Returns:
|
||
上传是否完成
|
||
"""
|
||
# 默认实现,子类应该重写
|
||
return True
|
||
|
||
async def wait_for_publish_complete(
|
||
self,
|
||
page: Page,
|
||
timeout: int = 60,
|
||
check_interval: float = 2.0
|
||
) -> bool:
|
||
"""
|
||
等待发布完成
|
||
|
||
Args:
|
||
page: Playwright页面对象
|
||
timeout: 超时时间(秒)
|
||
check_interval: 检查间隔(秒)
|
||
|
||
Returns:
|
||
发布是否完成
|
||
"""
|
||
import asyncio
|
||
start_time = asyncio.get_event_loop().time()
|
||
|
||
while asyncio.get_event_loop().time() - start_time < timeout:
|
||
if await self._check_publish_status(page):
|
||
return True
|
||
await asyncio.sleep(check_interval)
|
||
|
||
return False
|
||
|
||
async def _check_publish_status(self, page: Page) -> bool:
|
||
"""
|
||
检查发布状态(子类实现)
|
||
|
||
Args:
|
||
page: Playwright页面对象
|
||
|
||
Returns:
|
||
发布是否完成
|
||
"""
|
||
# 默认实现,子类应该重写
|
||
return True
|
||
|
||
def create_publish_result(
|
||
self,
|
||
success: bool,
|
||
message: str,
|
||
task_id: str,
|
||
account: str,
|
||
error_details: Optional[Dict[str, Any]] = None,
|
||
duration: Optional[float] = None
|
||
) -> PublishResult:
|
||
"""
|
||
创建发布结果对象
|
||
|
||
Args:
|
||
success: 是否成功
|
||
message: 结果消息
|
||
task_id: 任务ID
|
||
account: 账号名称
|
||
error_details: 错误详情
|
||
duration: 执行耗时
|
||
|
||
Returns:
|
||
发布结果对象
|
||
"""
|
||
return PublishResult(
|
||
task_id=task_id,
|
||
platform=self.platform,
|
||
account=account,
|
||
success=success,
|
||
message=message,
|
||
error_details=error_details,
|
||
duration=duration
|
||
) |