Files
contentm_agent/执行会话/目标-调研5个开源内容工作台项目并生成分析文档-5199a6/取证/_opencreator_tree_stat.py
T

139 lines
4.7 KiB
Python
Raw Normal View History

# -*- coding: utf-8 -*-
"""OpenCreator 文件树统计(可复算)
输入:取证/opencreator/tree_*.json(本棒分片拉取)+ 取证/api/opencreator.tree.top.json(第 1 棒顶层)
输出:取证/opencreator/opencreator.tree.stat.json + 控制台摘要
口径:只数 type=='blob';顶层目录取 path 第一段。
"""
import json, os, collections
HERE = os.path.dirname(os.path.abspath(__file__))
OC = os.path.join(HERE, "opencreator")
API = os.path.join(HERE, "api")
# 切片树里的 path 是相对「该切片根」的,必须补回前缀才是仓根相对路径
SLICES = {
"tree_.github.json": ".github",
"tree_apps.json": "apps",
"tree_assets.json": "assets",
"tree_packages.json": "packages",
"tree_resources.json": "resources",
"tree_runtime.json": "runtime",
"tree_scripts.json": "scripts",
"tree_skills.json": "skills",
"tree_template.json": "template",
"tree_docs.json": "docs",
}
blobs = [] # (path, size)
trees = 0
for f, prefix in SLICES.items():
d = json.load(open(os.path.join(OC, f), encoding="utf-8"))
assert not d.get("truncated"), f + " truncated"
for e in d["tree"]:
if e["type"] == "blob":
blobs.append((prefix + "/" + e["path"], e.get("size", 0)))
else:
trees += 1
root = json.load(open(os.path.join(API, "opencreator.tree.top.json"), encoding="utf-8"))
for e in root["tree"]:
if e["type"] == "blob":
blobs.append((e["path"], e.get("size", 0)))
else:
trees += 1
# 去重(docs/specs 在 docs 整树里已含)
seen, uniq = set(), []
for p, s in blobs:
if p in seen:
continue
seen.add(p)
uniq.append((p, s))
blobs = uniq
by_top = collections.Counter()
for p, _ in blobs:
by_top[p.split("/")[0]] += 1
def sub(prefix, n=2):
c = collections.Counter()
for p, _ in blobs:
if p.startswith(prefix + "/"):
parts = p.split("/")
c["/".join(parts[:n])] += 1
return c
ext = collections.Counter()
for p, _ in blobs:
ext[os.path.splitext(p)[1].lower() or "(noext)"] += 1
apps = sub("apps", 3)
daemon_src = collections.Counter()
for p, _ in blobs:
if p.startswith("apps/daemon/src/"):
parts = p.split("/")
daemon_src["/".join(parts[:4]) if len(parts) > 3 else "/".join(parts[:3])] += 1
web_src = collections.Counter()
for p, _ in blobs:
if p.startswith("apps/web/src/"):
parts = p.split("/")
web_src["/".join(parts[:4]) if len(parts) > 3 else "/".join(parts[:3])] += 1
rt = sub("runtime/krillinai", 3)
tpl = collections.Counter()
for p, _ in blobs:
if p.startswith("template/"):
parts = p.split("/")
tpl[parts[1]] += 1
# 模板条目数(二级目录)
tpl_entries = collections.Counter()
for p, _ in blobs:
if p.startswith("template/") and len(p.split("/")) >= 3:
tpl_entries["/".join(p.split("/")[:2])] += 1
# writing-templates 模板条目
wt = collections.Counter()
for p, _ in blobs:
if p.startswith("packages/writing-templates/templates/"):
wt["/".join(p.split("/")[:4])] += 1
test_files = [p for p, _ in blobs if ".test." in p or ".spec." in p]
out = {
"repo": "krillinai/OpenCreator",
"branch": "master",
"total_blobs": len(blobs),
"total_trees": trees,
"total_bytes": sum(s for _, s in blobs),
"blobs_by_top_dir": dict(by_top.most_common()),
"ext_top20": dict(ext.most_common(20)),
"apps_by_3": dict(apps.most_common()),
"apps_daemon_src": dict(daemon_src.most_common()),
"apps_web_src": dict(web_src.most_common()),
"runtime_krillinai": dict(rt.most_common()),
"template_by_category": dict(tpl.most_common()),
"template_entries_by_category": {k: sum(1 for p, _ in blobs if p.startswith(k + "/"))
for k in tpl},
"writing_templates_entries": dict(wt.most_common()),
"test_file_count": len(test_files),
"test_files_sample": test_files[:15],
}
with open(os.path.join(OC, "opencreator.tree.stat.json"), "w", encoding="utf-8") as f:
json.dump(out, f, ensure_ascii=False, indent=1)
print("total_blobs=%d total_trees=%d total_bytes=%d test_files=%d"
% (len(blobs), trees, out["total_bytes"], len(test_files)))
print("顶层目录 blob 数:", dict(by_top.most_common()))
print()
print("apps 三层:", dict(apps.most_common(12)))
print()
print("daemon/src 四层:", dict(daemon_src.most_common(15)))
print()
print("web/src 四层:", dict(web_src.most_common(15)))
print()
print("runtime/krillinai 三层:", dict(rt.most_common(20)))
print()
print("template 分类 blob 数:", dict(tpl.most_common()))
print("template 条目数(二级目录):", dict(out["template_entries_by_category"]))
print()
print("writing-templates 条目:", dict(wt.most_common()))
print()
print("扩展名 top20:", dict(ext.most_common(20)))