feat: GET /transcripts/{filename} — serve transcript content

This commit is contained in:
2026-04-01 14:12:30 +02:00
parent 0bb0975a09
commit aa3eef8fb1
3 changed files with 46 additions and 1 deletions
+11 -1
View File
@@ -6,7 +6,7 @@ from fastapi import APIRouter, WebSocket, WebSocketDisconnect, Depends, HTTPExce
from api.state import state, Status
from config import load as load_config
from output import list_transcripts
from output import list_transcripts, read_transcript
router = APIRouter()
_ws_clients: list[WebSocket] = []
@@ -124,6 +124,16 @@ async def get_transcripts(user: dict = Depends(current_user)):
return list_transcripts(user_dir)
@router.get("/transcripts/{filename}")
async def get_transcript(filename: str, user: dict = Depends(current_user)):
from fastapi.responses import PlainTextResponse
user_dir = os.path.join(user["output_dir"], user["username"])
content = read_transcript(user_dir, filename)
if content is None:
raise HTTPException(status_code=404, detail="Nicht gefunden")
return PlainTextResponse(content)
@router.get("/config")
async def get_config(user: dict = Depends(current_user)):
return load_config()
+11
View File
@@ -35,6 +35,17 @@ def save_transcript(
return path
def read_transcript(output_dir: str, filename: str) -> str | None:
"""Return file content if filename is a plain .md file inside output_dir."""
if os.path.basename(filename) != filename or not filename.endswith(".md"):
return None
path = os.path.join(output_dir, filename)
if not os.path.exists(path):
return None
with open(path, encoding="utf-8") as f:
return f.read()
def list_transcripts(output_dir: str, limit: int = 20) -> list[dict]:
if not os.path.exists(output_dir):
return []
+24
View File
@@ -45,6 +45,30 @@ def test_status_requires_auth():
assert r.status_code == 401
def make_app_for_dir(output_dir: str):
from fastapi import FastAPI
from api.router import router, current_user
app = FastAPI()
app.dependency_overrides[current_user] = lambda: {"username": "", "output_dir": output_dir, "is_admin": False}
app.include_router(router)
return app
def test_get_transcript_returns_content(tmp_path):
f = tmp_path / "2026-01-01-0900-test.md"
f.write_text("# Hello\n\ncontent here\n")
client = TestClient(make_app_for_dir(str(tmp_path)))
r = client.get("/transcripts/2026-01-01-0900-test.md")
assert r.status_code == 200
assert "Hello" in r.text
def test_get_transcript_rejects_path_traversal(tmp_path):
client = TestClient(make_app_for_dir(str(tmp_path)))
r = client.get("/transcripts/..%2Fsecret.md")
assert r.status_code == 404
def test_login_rejects_wrong_credentials():
import tempfile, os
from unittest.mock import patch