review: fix critical/medium bugs in 4 plugins (round 2)
group_horse_racing: - settle_race: rewrite with 7 bug fixes (race condition, draw double-credit, empty participants, etc.) - models.py: reorder fields for correct defaults, add indexes - message_service: add logger import danding_points: - api.py: add finally blocks to 3 methods (add_points, get_history, get_leaderboard) - database.py: add finally block to get_user_balance chatai: - __init__.py: deprecated API→asyncio.to_thread, deduplicate logging, taskkill filter for safety - screenshot.py: XSS protection with bleach on HTML content - requirements.txt: add bleach dependency danding_qqpush: - api.py L13: fix self-referencing _renderer NameError crash - api.py: lazy singleton pattern via _get_renderer() instead of per-request ImageRenderer - __init__.py: mask Token in log output (security) All 34 tests pass.
This commit is contained in:
@@ -42,7 +42,8 @@ def register_routes():
|
||||
routes = create_routes(plugin_config.Token, plugin_config)
|
||||
driver.server_app.include_router(routes)
|
||||
|
||||
logger.info(f"[Danding_QqPush] API 路由已注册: /danding/qqpush/{plugin_config.Token}")
|
||||
masked = plugin_config.Token[:4] + "***" if len(plugin_config.Token) > 4 else "***"
|
||||
logger.info(f"[Danding_QqPush] API 路由已注册: /danding/qqpush/{masked}")
|
||||
|
||||
|
||||
# 插件加载时注册路由
|
||||
|
||||
@@ -10,9 +10,24 @@ from .text_parser import TextParser
|
||||
from .image_render import ImageRenderer
|
||||
|
||||
# Module-level singleton: load font once, reuse across requests
|
||||
_renderer = _renderer # reuse module-level singleton
|
||||
_renderer: Optional['ImageRenderer'] = None
|
||||
from .sender import sender
|
||||
|
||||
def _get_renderer(config: Config) -> 'ImageRenderer':
|
||||
global _renderer
|
||||
if _renderer is None:
|
||||
_renderer = ImageRenderer(
|
||||
width=config.ImageWidth,
|
||||
font_size=config.ImageFontSize,
|
||||
padding=config.ImagePadding,
|
||||
line_spacing=config.ImageLineSpacing,
|
||||
bg_color=config.ImageBgColor,
|
||||
text_color=config.ImageTextColor,
|
||||
font_paths=config.FontPaths,
|
||||
)
|
||||
return _renderer
|
||||
|
||||
|
||||
|
||||
# 请求体模型
|
||||
class PushRequest(BaseModel):
|
||||
@@ -93,18 +108,8 @@ def create_routes(token: str, config: Config):
|
||||
parsed_text = text_parser.parse(data.text)
|
||||
logger.info(f"解析文本: {parsed_text[:50]}..." if len(parsed_text) > 50 else parsed_text)
|
||||
|
||||
# 4. 生成图片
|
||||
image_renderer = ImageRenderer(
|
||||
width=config.ImageWidth,
|
||||
font_size=config.ImageFontSize,
|
||||
padding=config.ImagePadding,
|
||||
line_spacing=config.ImageLineSpacing,
|
||||
bg_color=config.ImageBgColor,
|
||||
text_color=config.ImageTextColor,
|
||||
font_paths=config.FontPaths
|
||||
)
|
||||
|
||||
image_base64 = await asyncio.to_thread(image_renderer.render_to_base64, parsed_text)
|
||||
# 4. 生成图片 (reuse shared renderer to avoid per-request font loading)
|
||||
image_base64 = await asyncio.to_thread(_get_renderer(config).render_to_base64, parsed_text)
|
||||
logger.info("图片生成成功")
|
||||
|
||||
# 5. 发送消息
|
||||
|
||||
Reference in New Issue
Block a user