番号插件新增封面全图模糊,发送前自动遮罩处理
变更项: 1. 在 fanhao_search 插件中新增全图高斯模糊处理函数,发送封面前统一执行。 2. 增加 cover_blur_enable 与 cover_blur_radius 配置项,支持开关和模糊强度调节。 3. 封面处理失败时回退原图并记录日志,保证主流程可用。 4. 初始化日志补充模糊配置参数,便于排查线上行为。
This commit is contained in:
@@ -20,9 +20,14 @@ http_proxy = ""
|
||||
allow_download_link = true
|
||||
|
||||
# 是否发送封面预览图(默认关闭)
|
||||
allow_preview_cover = false
|
||||
allow_preview_cover = true
|
||||
|
||||
# 当开启磁力时,是否优先返回“带字幕”磁力
|
||||
prefer_subtitle_magnet = true
|
||||
|
||||
# 封面图是否开启全图模糊(建议开启)
|
||||
cover_blur_enable = true
|
||||
|
||||
# 全图模糊强度(高斯半径,数值越大越模糊)
|
||||
cover_blur_radius = 18
|
||||
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
from typing import Any, Dict, List, Optional, Tuple
|
||||
import re
|
||||
from urllib.parse import urljoin
|
||||
import io
|
||||
|
||||
import aiohttp
|
||||
from bs4 import BeautifulSoup
|
||||
from loguru import logger
|
||||
from PIL import Image, ImageFilter
|
||||
|
||||
from base.plugin_common.message_plugin_interface import MessagePluginInterface
|
||||
from base.plugin_common.plugin_interface import PluginStatus
|
||||
@@ -73,6 +75,9 @@ class FanhaoSearchPlugin(MessagePluginInterface):
|
||||
self.allow_download_link = False
|
||||
self.allow_preview_cover = False
|
||||
self.prefer_subtitle_magnet = True
|
||||
# 封面图降敏配置:默认开启全图模糊,降低群内图片内容风险。
|
||||
self.cover_blur_enable = True
|
||||
self.cover_blur_radius = 18
|
||||
|
||||
def initialize(self, context: Dict[str, Any]) -> bool:
|
||||
"""初始化插件配置。"""
|
||||
@@ -90,11 +95,14 @@ class FanhaoSearchPlugin(MessagePluginInterface):
|
||||
self.allow_download_link = bool(cfg.get("allow_download_link", False))
|
||||
self.allow_preview_cover = bool(cfg.get("allow_preview_cover", False))
|
||||
self.prefer_subtitle_magnet = bool(cfg.get("prefer_subtitle_magnet", True))
|
||||
self.cover_blur_enable = bool(cfg.get("cover_blur_enable", True))
|
||||
self.cover_blur_radius = max(1, int(cfg.get("cover_blur_radius", 18) or 18))
|
||||
|
||||
self.LOG.info(
|
||||
f"[{self.name}] 初始化完成: enable={self.enable}, commands={self._commands}, "
|
||||
f"base_url={self.javbus_base_url}, allow_download_link={self.allow_download_link}, "
|
||||
f"allow_preview_cover={self.allow_preview_cover}, timeout={self.request_timeout_seconds}s"
|
||||
f"allow_preview_cover={self.allow_preview_cover}, cover_blur_enable={self.cover_blur_enable}, "
|
||||
f"cover_blur_radius={self.cover_blur_radius}, timeout={self.request_timeout_seconds}s"
|
||||
)
|
||||
return True
|
||||
|
||||
@@ -176,6 +184,32 @@ class FanhaoSearchPlugin(MessagePluginInterface):
|
||||
raise RuntimeError(f"图片下载失败 status={resp.status}, url={url}")
|
||||
return await resp.read()
|
||||
|
||||
def _apply_full_blur_to_image_bytes(self, image_bytes: bytes) -> bytes:
|
||||
"""对图片执行全图高斯模糊。
|
||||
|
||||
设计说明:
|
||||
1. 这里使用 Pillow 的 GaussianBlur 对整图处理,不做局部区域判断;
|
||||
2. 输出统一转为 JPEG,避免源图格式差异导致发送失败;
|
||||
3. 若处理异常则回退原图,保证主流程可用性。
|
||||
"""
|
||||
if not image_bytes:
|
||||
return image_bytes
|
||||
if not self.cover_blur_enable:
|
||||
return image_bytes
|
||||
try:
|
||||
with Image.open(io.BytesIO(image_bytes)) as image:
|
||||
# 转为 RGB 统一颜色空间,避免 RGBA 保存 JPEG 报错。
|
||||
if image.mode in ("RGBA", "P"):
|
||||
image = image.convert("RGB")
|
||||
# 全图高斯模糊,半径可在配置中调整。
|
||||
blurred = image.filter(ImageFilter.GaussianBlur(radius=float(self.cover_blur_radius)))
|
||||
output = io.BytesIO()
|
||||
blurred.save(output, format="JPEG", quality=88)
|
||||
return output.getvalue()
|
||||
except Exception as e:
|
||||
self.LOG.warning(f"[{self.name}] 封面全图模糊失败,回退原图: error={e}")
|
||||
return image_bytes
|
||||
|
||||
@staticmethod
|
||||
def _extract_plain_value_from_info_p(info_p) -> str:
|
||||
"""从详情页 <p> 节点中提取纯文本值。
|
||||
@@ -462,6 +496,8 @@ class FanhaoSearchPlugin(MessagePluginInterface):
|
||||
if cover_url:
|
||||
try:
|
||||
cover_bytes = await self._http_get_bytes(cover_url, referer=detail_url)
|
||||
# 发送前执行全图模糊,避免直接发送原始封面。
|
||||
cover_bytes = self._apply_full_blur_to_image_bytes(cover_bytes)
|
||||
await bot.send_image_message(target, cover_bytes)
|
||||
except Exception as cover_error:
|
||||
self.LOG.warning(f"[{self.name}] 封面发送失败: code={normalized_code}, error={cover_error}")
|
||||
@@ -475,4 +511,3 @@ class FanhaoSearchPlugin(MessagePluginInterface):
|
||||
def get_plugin():
|
||||
"""返回插件实例。"""
|
||||
return FanhaoSearchPlugin()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user