|
@@ -40,11 +40,12 @@ class PublishResult:
|
|
|
video_url: str = ""
|
|
video_url: str = ""
|
|
|
message: str = ""
|
|
message: str = ""
|
|
|
error: str = ""
|
|
error: str = ""
|
|
|
- need_captcha: bool = False # 是否需要验证码
|
|
|
|
|
- captcha_type: str = "" # 验证码类型: phone, slider, image
|
|
|
|
|
- screenshot_base64: str = "" # 页面截图(Base64)
|
|
|
|
|
- page_url: str = "" # 当前页面 URL
|
|
|
|
|
- status: str = "" # 状态: uploading, processing, success, failed, need_captcha, need_action
|
|
|
|
|
|
|
+ need_captcha: bool = False
|
|
|
|
|
+ captcha_type: str = ""
|
|
|
|
|
+ screenshot_base64: str = ""
|
|
|
|
|
+ page_url: str = ""
|
|
|
|
|
+ status: str = ""
|
|
|
|
|
+ screenshot_path: str = ""
|
|
|
|
|
|
|
|
|
|
|
|
|
@dataclass
|
|
@dataclass
|
|
@@ -344,6 +345,41 @@ class BasePublisher(ABC):
|
|
|
print(f"[{self.platform_name}] 截图失败: {e}")
|
|
print(f"[{self.platform_name}] 截图失败: {e}")
|
|
|
return ""
|
|
return ""
|
|
|
|
|
|
|
|
|
|
+ async def save_screenshot_to_file(self, directory: str = None, filename_prefix: str = "publish_failed") -> str:
|
|
|
|
|
+ """
|
|
|
|
|
+ 保存截图到指定目录,返回文件路径
|
|
|
|
|
+
|
|
|
|
|
+ Args:
|
|
|
|
|
+ directory: 截图保存目录,默认为 uploads/screenshots
|
|
|
|
|
+ filename_prefix: 文件名前缀
|
|
|
|
|
+
|
|
|
|
|
+ Returns:
|
|
|
|
|
+ str: 保存的文件路径,失败返回空字符串
|
|
|
|
|
+ """
|
|
|
|
|
+ if not self.page:
|
|
|
|
|
+ return ""
|
|
|
|
|
+
|
|
|
|
|
+ try:
|
|
|
|
|
+ if directory is None:
|
|
|
|
|
+ current_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
|
|
|
+ directory = os.path.join(current_dir, '..', '..', 'uploads', 'screenshots')
|
|
|
|
|
+
|
|
|
|
|
+ directory = os.path.abspath(directory)
|
|
|
|
|
+ os.makedirs(directory, exist_ok=True)
|
|
|
|
|
+
|
|
|
|
|
+ timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
|
|
|
|
+ task_info = f"_task{self.publish_task_id}" if self.publish_task_id else ""
|
|
|
|
|
+ account_info = f"_acc{self.publish_account_id}" if self.publish_account_id else ""
|
|
|
|
|
+ filename = f"{filename_prefix}_{self.platform_name}{task_info}{account_info}_{timestamp}.png"
|
|
|
|
|
+ filepath = os.path.join(directory, filename)
|
|
|
|
|
+
|
|
|
|
|
+ await self.page.screenshot(path=filepath, type="png")
|
|
|
|
|
+ print(f"[{self.platform_name}] 截图已保存: {filepath}")
|
|
|
|
|
+ return filepath
|
|
|
|
|
+ except Exception as e:
|
|
|
|
|
+ print(f"[{self.platform_name}] 保存截图失败: {e}")
|
|
|
|
|
+ return ""
|
|
|
|
|
+
|
|
|
async def request_sms_code_from_frontend(self, phone: str = "", timeout_seconds: int = 120, message: str = "") -> str:
|
|
async def request_sms_code_from_frontend(self, phone: str = "", timeout_seconds: int = 120, message: str = "") -> str:
|
|
|
node_api_url = os.environ.get('NODEJS_API_URL', 'http://localhost:3000').rstrip('/')
|
|
node_api_url = os.environ.get('NODEJS_API_URL', 'http://localhost:3000').rstrip('/')
|
|
|
internal_api_key = os.environ.get('INTERNAL_API_KEY', 'internal-api-key-default')
|
|
internal_api_key = os.environ.get('INTERNAL_API_KEY', 'internal-api-key-default')
|
|
@@ -1035,16 +1071,26 @@ class BasePublisher(ABC):
|
|
|
"""
|
|
"""
|
|
|
运行发布任务
|
|
运行发布任务
|
|
|
包装了 publish 方法,添加了异常处理和资源清理
|
|
包装了 publish 方法,添加了异常处理和资源清理
|
|
|
|
|
+ 发布失败时自动保存截图到 uploads/screenshots 目录
|
|
|
"""
|
|
"""
|
|
|
try:
|
|
try:
|
|
|
- return await self.publish(cookies, params)
|
|
|
|
|
|
|
+ result = await self.publish(cookies, params)
|
|
|
|
|
+ if not result.success and self.page:
|
|
|
|
|
+ screenshot_path = await self.save_screenshot_to_file()
|
|
|
|
|
+ if screenshot_path:
|
|
|
|
|
+ result.screenshot_path = screenshot_path
|
|
|
|
|
+ return result
|
|
|
except Exception as e:
|
|
except Exception as e:
|
|
|
import traceback
|
|
import traceback
|
|
|
traceback.print_exc()
|
|
traceback.print_exc()
|
|
|
|
|
+ screenshot_path = ""
|
|
|
|
|
+ if self.page:
|
|
|
|
|
+ screenshot_path = await self.save_screenshot_to_file()
|
|
|
return PublishResult(
|
|
return PublishResult(
|
|
|
success=False,
|
|
success=False,
|
|
|
platform=self.platform_name,
|
|
platform=self.platform_name,
|
|
|
- error=str(e)
|
|
|
|
|
|
|
+ error=str(e),
|
|
|
|
|
+ screenshot_path=screenshot_path
|
|
|
)
|
|
)
|
|
|
finally:
|
|
finally:
|
|
|
await self.close_browser()
|
|
await self.close_browser()
|