- hexi core: message handling, rate limiting, cooldown, plugin manager - Custom plugins: BF stats, daily check-in, quotes, persona cards, etc. - Community plugins vendored under hexi/plugins with local fixes - Web admin frontends (learning-chat, persona-admin), unified hexi/web - Tests for rate_limit/cooldown/memes/persona; poetry.lock Co-Authored-By: Claude <noreply@anthropic.com>
63 lines
2.0 KiB
Python
63 lines
2.0 KiB
Python
"""Playwright 渲染器:将报告 HTML 渲染为图片字节。
|
||
|
||
签名对应原插件 html_render(html, data, return_url, options)。
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
from typing import Any
|
||
|
||
from .core.utils.logger import logger
|
||
|
||
_SCALE_MAP = {
|
||
"ultra": 3,
|
||
"high": 2,
|
||
"normal": 1,
|
||
"low": 0.5,
|
||
}
|
||
|
||
|
||
async def html_render(
|
||
html_content: str,
|
||
data: dict | None = None,
|
||
return_url: bool = False,
|
||
options: dict | None = None,
|
||
) -> bytes | str:
|
||
"""渲染 HTML 为图片。返回 bytes(PNG/JPEG)。"""
|
||
options = options or {}
|
||
viewport_width = int(options.get("viewport_width", 1440))
|
||
viewport_height = int(options.get("viewport_height", 900))
|
||
full_page = bool(options.get("full_page", True))
|
||
img_type = str(options.get("type", "png")).lower()
|
||
if img_type in ("jpg", "jpeg"):
|
||
img_type = "jpeg"
|
||
quality = int(options.get("quality", 90))
|
||
timeout = int(options.get("timeout", 30000))
|
||
scale_level = str(options.get("device_scale_factor_level", "normal")).lower()
|
||
scale = _SCALE_MAP.get(scale_level, 1)
|
||
|
||
try:
|
||
from playwright.async_api import async_playwright
|
||
except Exception as e:
|
||
logger.error(f"[T2I] 无法导入 playwright: {e}")
|
||
return ""
|
||
|
||
try:
|
||
async with async_playwright() as p:
|
||
browser = await p.chromium.launch()
|
||
page = await browser.new_page(
|
||
viewport={"width": viewport_width, "height": viewport_height},
|
||
device_scale_factor=scale,
|
||
)
|
||
await page.set_content(html_content, wait_until="networkidle", timeout=timeout)
|
||
shot = await page.screenshot(
|
||
type=img_type,
|
||
quality=quality if img_type == "jpeg" else None,
|
||
full_page=full_page,
|
||
)
|
||
await browser.close()
|
||
return shot
|
||
except Exception as e:
|
||
logger.error(f"[T2I] Playwright 渲染失败: {e}", exc_info=True)
|
||
return ""
|