zcbot/scripts/diag_svgguard_breakdown.py

70 lines
2.5 KiB
Python

"""拆 #1 SVG 质检门 exit-1 的 ERROR 具体子类,定位治本靶点。"""
import os
import re
from collections import Counter
from pathlib import Path
env = Path(__file__).resolve().parent.parent / ".env"
for line in env.read_text(encoding="utf-8").splitlines():
s = line.strip()
if s.startswith("ZCBOT_DB_URL=") and not s.startswith("#"):
os.environ["ZCBOT_DB_URL"] = s.split("=", 1)[1].strip()
from sqlalchemy import create_engine, text # noqa: E402
eng = create_engine(os.environ["ZCBOT_DB_URL"])
with eng.connect() as c:
rows = c.execute(text(
"select m.payload->>'content' content "
"from messages m "
"where m.created_at >= now() - interval '7 days' "
" and m.payload->>'role'='tool' and m.payload->>'name'='shell' "
" and m.payload->>'content' like '%[SCAN] Checking%SVG%' "
" and m.payload->>'content' like '%[exit 1]%'"
)).fetchall()
print(f"SVG 质检门 exit-1 结果:{len(rows)}\n")
def classify(line: str) -> str:
if "off the locked footer_y" in line:
return "footer_y 近失(footer/页码 baseline 差2-16px)"
if "spills past the locked content_bottom" in line:
return "content_bottom 溢出(内容装不下)"
if "off the locked margin_x" in line:
return "margin_x 近失(卡片/文本左缘)"
if "off the locked content_top" in line:
return "content_top 近失(卡片/图标顶)"
if "below" in line and "baseline" in line:
return "出画布(baseline 超底边)"
if "overlap" in line or "叠压" in line or "overlaps" in line:
return "CJK/元素叠压"
if "icon" in line.lower() and ("text" in line.lower() or "文字" in line):
return "图标压字"
if "px off the" in line and "px" in line:
return "其他网格近失"
return "其他: " + line[:60]
cat = Counter()
per_result_hit = Counter()
for (content,) in rows:
if not content:
continue
hits = set()
for m in re.finditer(r"\[ERROR\]\s*([^\n]+)", content):
line = m.group(1).strip()
if not line or line.startswith("With errors") or "Failed" in line:
continue
k = classify(line)
cat[k] += 1
hits.add(k)
for k in hits:
per_result_hit[k] += 1
print("=== 每类 ERROR 出现的结果数(一条结果可命中多类)===")
for k, n in per_result_hit.most_common():
print(f" {n:>3} 条结果 {k}")
print("\n=== ERROR 行总数(含同结果多行)===")
for k, n in cat.most_common():
print(f" {n:>3} {k}")