Files
HangmanLab.Backend/api/tree.py

122 lines
3.6 KiB
Python

from flask import Blueprint, jsonify
from sqlalchemy.orm import Session
from sqlalchemy import or_
import api
from api import etag_response, is_user_admin
from db import get_db
from db.models.Markdown import Markdown
from db.models.Path import Path
from db.models.MarkdownSetting import MarkdownSetting
from db.models.MarkdownPermissionSetting import MarkdownPermissionSetting
from api import limiter
import logging
logger = logging.getLogger(__name__)
tree_bp = Blueprint('tree', __name__, url_prefix='/api/tree')
def build_tree(db: Session, parent_id: int = None, is_admin=False):
path_nodes = db.query(Path).filter(Path.parent_id == parent_id).all()
markdown_query = db.query(
Markdown.id,
Markdown.title,
Markdown.order,
Markdown.shortcut,
Markdown.setting_id
).filter(Markdown.path_id == parent_id)
if not is_admin:
markdown_query = markdown_query.outerjoin(
MarkdownSetting,
Markdown.setting_id == MarkdownSetting.id
).outerjoin(
MarkdownPermissionSetting,
MarkdownSetting.permission_setting_id == MarkdownPermissionSetting.id
).filter(
or_(
MarkdownPermissionSetting.permission != 'private',
MarkdownPermissionSetting.permission == None
)
)
md_nodes = markdown_query.all()
t0 = [
{
"id": node.id,
"title": node.title,
"order": node.order,
"setting_id": node.setting_id,
"type": "markdown"
} for node in md_nodes
]
t1 = [
{**node.to_dict(), "type": "path", "children": build_tree(db, node.id, is_admin)} for node in path_nodes
]
for node in t1:
for child in node["children"]:
if "title" in child.keys() and child["title"] == "index":
node["index"] = True
break
return t0 + t1
@tree_bp.route('/', methods=['GET'])
@limiter.limit(api.get_rate_limit)
@etag_response
def get_tree():
"""
Get the complete tree structure of paths and markdowns.
This endpoint retrieves the hierarchical tree structure of all paths and markdowns.
For non-admin users, markdowns with 'private' permission settings are filtered out.
Returns:
A JSON object representing the tree structure with the following format:
{
"id": 1,
"name": "",
"parent_id": null,
"order": "...",
"setting_id": null,
"type": "path",
"index": true/false,
"children": [
{
"id": ...,
"title": "...",
"order": "...",
"setting_id": null,
"type": "markdown"
},
{
"id": ...,
"name": "...",
"parent_id": 1,
"order": "...",
"setting_id": null,
"type": "path",
"children": [...]
}
]
}
Response Codes:
- 200: Success
"""
is_admin = is_user_admin()
with get_db() as session:
children = build_tree(session, 1, is_admin)
root = session.query(Path).get(1)
return jsonify(
{
**root.to_dict(),
"type": "path",
"index": any("title" in child.keys() and child["title"] == "index" for child in children),
"children": children
}
), 200