132 lines
4.3 KiB
Python
132 lines
4.3 KiB
Python
#!/usr/bin/env python3
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
from collections import Counter, defaultdict
|
|
from pathlib import Path
|
|
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
MANIFEST_PATH = ROOT / "deep-action-manifest-hc-pos.sqygj.cn.json"
|
|
MIRROR_MANIFEST_PATH = ROOT / "mirror-manifest-hc-pos.sqygj.cn.json"
|
|
REPORT_PATH = ROOT / "deep-action-report.md"
|
|
SUMMARY_PATH = ROOT / "deep-action-summary.json"
|
|
GAPS_PATH = ROOT / "deep-action-gaps.txt"
|
|
|
|
|
|
def classify(label: str) -> str:
|
|
pairs = [
|
|
("统计", "统计"),
|
|
("详情", "详情"),
|
|
("查看", "查看"),
|
|
("编辑", "编辑"),
|
|
("新增", "新增"),
|
|
("新建", "新建"),
|
|
("创建", "创建"),
|
|
("添加", "添加"),
|
|
("记录", "记录"),
|
|
("工单", "工单"),
|
|
("复制", "复制"),
|
|
("绑定", "绑定"),
|
|
("确认", "确认"),
|
|
]
|
|
for needle, category in pairs:
|
|
if needle in label:
|
|
return category
|
|
return "其他"
|
|
|
|
|
|
def route_key(url: str) -> str:
|
|
return url.split("#/", 1)[1] if "#/" in url else url
|
|
|
|
|
|
def main() -> int:
|
|
manifest = json.loads(MANIFEST_PATH.read_text(encoding="utf-8"))
|
|
items = manifest["items"]
|
|
mirror_manifest = json.loads(MIRROR_MANIFEST_PATH.read_text(encoding="utf-8"))
|
|
|
|
by_route: dict[str, list[dict]] = defaultdict(list)
|
|
for item in items:
|
|
by_route[item["source_url"]].append(item)
|
|
|
|
route_rows = []
|
|
category_counter: Counter[str] = Counter()
|
|
for source_url, route_items in sorted(by_route.items(), key=lambda kv: route_key(kv[0])):
|
|
labels = [item["label"] for item in route_items]
|
|
categories = Counter(classify(label) for label in labels)
|
|
category_counter.update(categories)
|
|
route_rows.append(
|
|
{
|
|
"source_url": source_url,
|
|
"route": route_key(source_url),
|
|
"count": len(route_items),
|
|
"categories": dict(sorted(categories.items())),
|
|
"labels": labels,
|
|
"html_paths": [item["html_path"] for item in route_items],
|
|
}
|
|
)
|
|
|
|
summary = {
|
|
"captured_deep_states": manifest["captured_deep_states"],
|
|
"route_count": len(route_rows),
|
|
"category_counts": dict(sorted(category_counter.items())),
|
|
"routes": route_rows,
|
|
}
|
|
SUMMARY_PATH.write_text(json.dumps(summary, ensure_ascii=False, indent=2), encoding="utf-8")
|
|
|
|
deep_urls = {item["source_url"] for item in items}
|
|
gap_urls = sorted(
|
|
page["source_url"]
|
|
for page in mirror_manifest.get("pages", [])
|
|
if page.get("source_url") not in deep_urls
|
|
)
|
|
GAPS_PATH.write_text("\n".join(gap_urls) + ("\n" if gap_urls else ""), encoding="utf-8")
|
|
|
|
lines = [
|
|
"# Deep Action Report",
|
|
"",
|
|
f"- Captured deep states: `{manifest['captured_deep_states']}`",
|
|
f"- Source routes: `{len(route_rows)}`",
|
|
f"- Uncaptured mirrored routes: `{len(gap_urls)}`",
|
|
f"- Asset failures: `{len(manifest.get('asset_failures', []))}`",
|
|
f"- Remaining failures: `{len(manifest.get('failures', []))}`",
|
|
"",
|
|
"## Category Counts",
|
|
"",
|
|
]
|
|
for category, count in sorted(category_counter.items()):
|
|
lines.append(f"- {category}: `{count}`")
|
|
|
|
lines.extend(["", "## Routes", ""])
|
|
for row in route_rows:
|
|
lines.append(f"### `{row['route']}`")
|
|
lines.append("")
|
|
lines.append(f"- Source URL: `{row['source_url']}`")
|
|
lines.append(f"- Captured states: `{row['count']}`")
|
|
lines.append(f"- Categories: `{json.dumps(row['categories'], ensure_ascii=False)}`")
|
|
lines.append("- Labels:")
|
|
for label in row["labels"]:
|
|
lines.append(f" - {label}")
|
|
lines.append("")
|
|
|
|
REPORT_PATH.write_text("\n".join(lines) + "\n", encoding="utf-8")
|
|
print(
|
|
json.dumps(
|
|
{
|
|
"report": str(REPORT_PATH),
|
|
"summary": str(SUMMARY_PATH),
|
|
"gaps": str(GAPS_PATH),
|
|
"captured": manifest["captured_deep_states"],
|
|
"routes": len(route_rows),
|
|
"uncaptured_mirror_routes": len(gap_urls),
|
|
},
|
|
ensure_ascii=False,
|
|
indent=2,
|
|
)
|
|
)
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|