122 lines
3.6 KiB
Python
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
|