新的樹狀管理器
This commit is contained in:
70
main.py
70
main.py
@@ -137,9 +137,74 @@ def _copy_blank_template(dest: Path) -> None:
|
||||
)
|
||||
|
||||
|
||||
def _flatten_tree_items(items: list[dict[str, Any]], file_names: set[str]) -> None:
|
||||
for item in items:
|
||||
if item.get("type") == "file" and isinstance(item.get("name"), str):
|
||||
file_names.add(item["name"])
|
||||
if isinstance(item.get("children"), list):
|
||||
_flatten_tree_items(item["children"], file_names)
|
||||
|
||||
|
||||
def _normalize_page_tree(slug: str, tree: dict[str, Any]) -> dict[str, Any]:
|
||||
"""將已儲存的 page_tree 與實際檔案同步並補齊新頁面。"""
|
||||
pages = set(_list_pages(slug))
|
||||
existing_files: set[str] = set()
|
||||
root_items = tree.get("root") if isinstance(tree.get("root"), list) else []
|
||||
_flatten_tree_items(root_items, existing_files)
|
||||
|
||||
def filter_valid_items(items: list[dict[str, Any]]) -> list[dict[str, Any]]:
|
||||
result: list[dict[str, Any]] = []
|
||||
for item in items:
|
||||
item_type = item.get("type")
|
||||
if item_type == "file":
|
||||
name = item.get("name")
|
||||
if isinstance(name, str) and name in pages:
|
||||
existing_files.add(name)
|
||||
result.append({
|
||||
"type": "file",
|
||||
"name": name,
|
||||
"title": item.get("title", Path(name).stem.replace("-", " ").title()),
|
||||
"show_in_nav": bool(item.get("show_in_nav", True)),
|
||||
"is_homepage": bool(item.get("is_homepage", False)),
|
||||
"requires_password": bool(item.get("requires_password", False)),
|
||||
})
|
||||
elif item_type == "folder":
|
||||
name = item.get("name")
|
||||
if isinstance(name, str):
|
||||
children = filter_valid_items(item.get("children", []) if isinstance(item.get("children"), list) else [])
|
||||
result.append({
|
||||
"type": "folder",
|
||||
"name": name,
|
||||
"title": item.get("title", name.replace("-", " ").title()),
|
||||
"show_in_nav": bool(item.get("show_in_nav", True)),
|
||||
"children": children,
|
||||
})
|
||||
else:
|
||||
continue
|
||||
return result
|
||||
|
||||
normalized = {"root": filter_valid_items(root_items)}
|
||||
missing_pages = sorted(pages - existing_files)
|
||||
if missing_pages:
|
||||
for rel in missing_pages:
|
||||
normalized["root"].append({
|
||||
"type": "file",
|
||||
"name": rel,
|
||||
"title": Path(rel).stem.replace("-", " ").title(),
|
||||
"show_in_nav": True,
|
||||
"is_homepage": rel == "index.html",
|
||||
"requires_password": False,
|
||||
})
|
||||
return normalized
|
||||
|
||||
|
||||
def build_page_tree(slug: str, max_depth: int = 3) -> dict[str, Any]:
|
||||
"""遞歸建構專案的頁面樹狀結構(根據資料夾結構)。"""
|
||||
"""遞歸建構專案的頁面樹狀結構。"""
|
||||
proj_dir = _project_dir(slug)
|
||||
data = _load_project(slug)
|
||||
page_tree = data.get("page_tree")
|
||||
if isinstance(page_tree, dict) and isinstance(page_tree.get("root"), list):
|
||||
return _normalize_page_tree(slug, page_tree)
|
||||
|
||||
def scan_folder(folder: Path, current_depth: int = 0):
|
||||
items: list[dict[str, Any]] = []
|
||||
@@ -168,6 +233,9 @@ def build_page_tree(slug: str, max_depth: int = 3) -> dict[str, Any]:
|
||||
"type": "file",
|
||||
"name": rel,
|
||||
"title": Path(name).stem.replace("-", " ").title(),
|
||||
"show_in_nav": True,
|
||||
"is_homepage": rel == "index.html",
|
||||
"requires_password": False,
|
||||
})
|
||||
return items
|
||||
|
||||
|
||||
Reference in New Issue
Block a user