OCR截屏JSON/YAML配置块剥离:新增_strip_json_yaml_blocks方法在切行前剥离JSON对象块/key-value行/YAML列表;OCR行过滤和Poll过滤加JSON/YAML语法兜底;修复微信右侧配置面板与用户消息搅合导致消息丢失
This commit is contained in:
+90
@@ -1121,6 +1121,12 @@ class MessageMonitor:
|
|||||||
self._ocr_garbage_count[platform] = 0
|
self._ocr_garbage_count[platform] = 0
|
||||||
self._ocr_last_text[platform] = raw_text
|
self._ocr_last_text[platform] = raw_text
|
||||||
|
|
||||||
|
# —— JSON/YAML 配置块剥离 ——
|
||||||
|
# 微信 OCR 截屏范围 40%-98%,常把右侧文档/配置面板(JSON/YAML)一起截入
|
||||||
|
# JSON 块("key": value, {, })和 YAML 块(key: value)跟用户消息混在一起
|
||||||
|
# 在 split 前先剥离这些行,避免 JSON 碎片污染用户消息
|
||||||
|
raw_text = self._strip_json_yaml_blocks(raw_text, platform)
|
||||||
|
|
||||||
# —— 行切割 + 尾标清理 ——
|
# —— 行切割 + 尾标清理 ——
|
||||||
ocr_lines = []
|
ocr_lines = []
|
||||||
for l in raw_text.split('\n'):
|
for l in raw_text.split('\n'):
|
||||||
@@ -1309,6 +1315,17 @@ class MessageMonitor:
|
|||||||
logger.debug(f"[{platform}] OCR 过滤: 纯非中文乱码 line={line!r}")
|
logger.debug(f"[{platform}] OCR 过滤: 纯非中文乱码 line={line!r}")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
# —— JSON/YAML 碎片兜底:OCR 截屏混入配置面板 ——
|
||||||
|
# 行首是 "key": value 或 key: value(YAML)→ 配置面板碎片
|
||||||
|
if re.match(r'^["\']?[a-zA-Z_][\w]*["\']?\s*:\s*["\d\[\{tfn]', line):
|
||||||
|
logger.debug(f"[{platform}] OCR 过滤: JSON行 {line!r}")
|
||||||
|
continue
|
||||||
|
if re.match(r'^[a-zA-Z_][\w]*\s*:\s*["\w\d]', line) and \
|
||||||
|
not re.match(r'^(https?|ftp)://', line) and \
|
||||||
|
not re.match(r'^[a-zA-Z_][\w]*\s*:\s*/', line):
|
||||||
|
logger.debug(f"[{platform}] OCR 过滤: YAML行 {line!r}")
|
||||||
|
continue
|
||||||
|
|
||||||
# —— 末尾 #标题 碎片兜底 ——
|
# —— 末尾 #标题 碎片兜底 ——
|
||||||
# OCR 时间戳分割可能遗漏尾部 " #测试" " #草" 等 md 标题碎片
|
# OCR 时间戳分割可能遗漏尾部 " #测试" " #草" 等 md 标题碎片
|
||||||
# 注:\s+ 要求空格在前,避免误杀 "C#语言" "中文#标签"
|
# 注:\s+ 要求空格在前,避免误杀 "C#语言" "中文#标签"
|
||||||
@@ -1724,6 +1741,70 @@ class MessageMonitor:
|
|||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _strip_json_yaml_blocks(raw_text: str, platform: str = "") -> str:
|
||||||
|
"""剥离 OCR 截屏中混入的 JSON/YAML 配置块。
|
||||||
|
|
||||||
|
微信 OCR 截屏范围 40%-98%,常把右侧文档/配置面板一起截入。
|
||||||
|
JSON 块("key": value, {, })和 YAML 块(key: value, - item)
|
||||||
|
跟用户消息混在一起,导致 split 后 JSON 碎片污染用户消息行。
|
||||||
|
|
||||||
|
策略:逐行检测,丢弃明显是 JSON/YAML 语法的行。
|
||||||
|
用户聊天不会写 "key": value 或 { } 块。
|
||||||
|
"""
|
||||||
|
lines = raw_text.split('\n')
|
||||||
|
cleaned = []
|
||||||
|
in_json_block = False
|
||||||
|
brace_depth = 0
|
||||||
|
|
||||||
|
for line in lines:
|
||||||
|
stripped = line.strip()
|
||||||
|
if not stripped:
|
||||||
|
cleaned.append(line)
|
||||||
|
continue
|
||||||
|
|
||||||
|
# 检测 JSON 对象块开始/结束
|
||||||
|
if stripped == '{' or stripped.startswith('{') and '"' in stripped:
|
||||||
|
in_json_block = True
|
||||||
|
brace_depth = stripped.count('{') - stripped.count('}')
|
||||||
|
logger.debug(f"[{platform}] JSON块剥离: 开始 {stripped[:60]!r}")
|
||||||
|
continue
|
||||||
|
|
||||||
|
if in_json_block:
|
||||||
|
brace_depth += stripped.count('{') - stripped.count('}')
|
||||||
|
if brace_depth <= 0:
|
||||||
|
in_json_block = False
|
||||||
|
logger.debug(f"[{platform}] JSON块剥离: 结束 {stripped[:60]!r}")
|
||||||
|
continue
|
||||||
|
|
||||||
|
# JSON 行特征: "key": value 或 "key": "value"
|
||||||
|
if re.match(r'^["\']?[a-zA-Z_][\w]*["\']?\s*:\s*["\d\[\{tfn]', stripped):
|
||||||
|
logger.debug(f"[{platform}] JSON块剥离: key-value行 {stripped[:60]!r}")
|
||||||
|
continue
|
||||||
|
|
||||||
|
# YAML 行特征: key: value(无引号,非 URL)
|
||||||
|
if re.match(r'^[a-zA-Z_][\w]*\s*:\s*["\w\d]', stripped) and \
|
||||||
|
not re.match(r'^(https?|ftp)://', stripped) and \
|
||||||
|
not re.match(r'^[a-zA-Z_][\w]*\s*:\s*/', stripped):
|
||||||
|
logger.debug(f"[{platform}] JSON块剥离: YAML行 {stripped[:60]!r}")
|
||||||
|
continue
|
||||||
|
|
||||||
|
# YAML 列表项: - item
|
||||||
|
if re.match(r'^-\s+\S', stripped) and \
|
||||||
|
not re.match(r'^-\s*[\u4e00-\u9fff]', stripped):
|
||||||
|
logger.debug(f"[{platform}] JSON块剥离: YAML列表 {stripped[:60]!r}")
|
||||||
|
continue
|
||||||
|
|
||||||
|
# 纯 JSON 数组: [ "item", ... ]
|
||||||
|
if stripped.startswith('[') and stripped.endswith(']') and \
|
||||||
|
'"' in stripped:
|
||||||
|
logger.debug(f"[{platform}] JSON块剥离: 数组 {stripped[:60]!r}")
|
||||||
|
continue
|
||||||
|
|
||||||
|
cleaned.append(line)
|
||||||
|
|
||||||
|
return '\n'.join(cleaned)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _is_markdown_document(text: str) -> bool:
|
def _is_markdown_document(text: str) -> bool:
|
||||||
"""检测是否为 Markdown 格式的文档内容。
|
"""检测是否为 Markdown 格式的文档内容。
|
||||||
@@ -2471,6 +2552,15 @@ class MessageMonitor:
|
|||||||
if not re.search(r'[\u4e00-\u9fff]', ts) and len(ts) > 15 and not ts.startswith('/'):
|
if not re.search(r'[\u4e00-\u9fff]', ts) and len(ts) > 15 and not ts.startswith('/'):
|
||||||
logger.debug(f"[{platform}] Poll过滤: 无中文乱码 ts={ts!r}")
|
logger.debug(f"[{platform}] Poll过滤: 无中文乱码 ts={ts!r}")
|
||||||
continue
|
continue
|
||||||
|
# === JSON/YAML 碎片兜底:OCR 截屏混入配置面板 ===
|
||||||
|
if re.match(r'^["\']?[a-zA-Z_][\w]*["\']?\s*:\s*["\d\[\{tfn]', ts):
|
||||||
|
logger.debug(f"[{platform}] Poll过滤: JSON行 ts={ts!r}")
|
||||||
|
continue
|
||||||
|
if re.match(r'^[a-zA-Z_][\w]*\s*:\s*["\w\d]', ts) and \
|
||||||
|
not re.match(r'^(https?|ftp)://', ts) and \
|
||||||
|
not re.match(r'^[a-zA-Z_][\w]*\s*:\s*/', ts):
|
||||||
|
logger.debug(f"[{platform}] Poll过滤: YAML行 ts={ts!r}")
|
||||||
|
continue
|
||||||
# === 安全阀:UI 子串过滤(兜底,防任何路径漏过)===
|
# === 安全阀:UI 子串过滤(兜底,防任何路径漏过)===
|
||||||
if any(sub in ts for sub in _UI_SUBSTR_BLOCKLIST):
|
if any(sub in ts for sub in _UI_SUBSTR_BLOCKLIST):
|
||||||
logger.debug(f"[{platform}] Poll过滤: UI子串 ts={ts!r}")
|
logger.debug(f"[{platform}] Poll过滤: UI子串 ts={ts!r}")
|
||||||
|
|||||||
Reference in New Issue
Block a user