feat: implement Phase 2 (Pulse, Admin, RC2)
This commit is contained in:
91
app/routers/docs_reader.py
Normal file
91
app/routers/docs_reader.py
Normal file
@@ -0,0 +1,91 @@
|
||||
import os
|
||||
import markdown
|
||||
from fastapi import APIRouter, Request, HTTPException, Depends
|
||||
from fastapi.responses import HTMLResponse
|
||||
|
||||
from deps import current_user
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
# Whitelist allowed files.
|
||||
# We look for them in the root directory relative to 'app' parent.
|
||||
# Since app is in /app inside docker, the root volume mount is usually at /app or mapped.
|
||||
# Code Tour Step 828 shows 'app/main.py' path analysis.
|
||||
# If workdir is /app (docker), and files are in /app (root of repo mapped to /app), then "README.md" is at "./README.md".
|
||||
|
||||
ALLOWED_DOCS = {
|
||||
"README.md": "Start Guide (Readme)",
|
||||
"QUICKSTART.md": "Schnellstart",
|
||||
"HANDBUCH.md": "Benutzerhandbuch",
|
||||
"CODE_TOUR.md": "Code Tour (Dev)",
|
||||
"ARCHITECTURE_ROLES_GROUPS.md": "Architektur",
|
||||
"DIARY_RAG_README.md": "Tagebuch & RAG Info",
|
||||
"CrumbTech.md": "Technische Details",
|
||||
"QDRANT_ACCESS.md": "Vektor DB Access",
|
||||
"deploy_security_fixes.sh": "Security Script (Source)" # Maybe viewing scripts is cool too? Let's stick to MD for now.
|
||||
}
|
||||
|
||||
@router.get("/docs", response_class=HTMLResponse)
|
||||
async def list_docs(req: Request):
|
||||
"""
|
||||
List available documentation files.
|
||||
"""
|
||||
# Check which exist
|
||||
available = []
|
||||
|
||||
# We use /docs_root/ inside the container (see Dockerfile)
|
||||
# Fallback to "." if running locally without container
|
||||
if os.path.exists("/docs_root"):
|
||||
base_path = "/docs_root"
|
||||
else:
|
||||
base_path = "."
|
||||
|
||||
for filename, title in ALLOWED_DOCS.items():
|
||||
if os.path.exists(os.path.join(base_path, filename)):
|
||||
available.append({"name": title, "file": filename})
|
||||
|
||||
return req.app.state.render(
|
||||
req,
|
||||
"pages/docs_index.html",
|
||||
docs=available,
|
||||
page_title="Dokumentation"
|
||||
)
|
||||
|
||||
@router.get("/docs/{filename}", response_class=HTMLResponse)
|
||||
async def view_doc(req: Request, filename: str):
|
||||
"""
|
||||
Render a specific markdown file.
|
||||
"""
|
||||
if filename not in ALLOWED_DOCS:
|
||||
raise HTTPException(404, "File not found or not allowed.")
|
||||
|
||||
base_path = "."
|
||||
if os.path.exists("/docs_root"):
|
||||
base_path = "/docs_root"
|
||||
|
||||
file_path = os.path.join(base_path, filename)
|
||||
|
||||
if not os.path.exists(file_path):
|
||||
raise HTTPException(404, "File not on server.")
|
||||
|
||||
try:
|
||||
with open(file_path, "r", encoding="utf-8") as f:
|
||||
content = f.read()
|
||||
|
||||
# Convert Markdown to HTML
|
||||
# Extensions for better rendering: tables, fenced_code
|
||||
html_content = markdown.markdown(
|
||||
content,
|
||||
extensions=['tables', 'fenced_code', 'nl2br']
|
||||
)
|
||||
|
||||
return req.app.state.render(
|
||||
req,
|
||||
"pages/doc_viewer.html",
|
||||
doc_title=ALLOWED_DOCS[filename],
|
||||
doc_content=html_content,
|
||||
filename=filename
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
raise HTTPException(500, f"Error rendering document: {e}")
|
||||
Reference in New Issue
Block a user