This commit is contained in:
schmeeve
2026-09-26 22:06:28 -07:00
parent bc365267d0
commit 0758095046
14 changed files with 1392 additions and 0 deletions

View File

@@ -1,6 +1,7 @@
from __future__ import annotations
from contextlib import asynccontextmanager
from pathlib import Path
import structlog
from fastapi import Depends, FastAPI, File, Form, HTTPException, Request, Response, UploadFile
@@ -17,6 +18,7 @@ logger = structlog.get_logger()
@asynccontextmanager
async def lifespan(app: FastAPI):
await database.init_db()
await notes.backfill_templates()
yield
@@ -145,6 +147,14 @@ async def recent(request: Request, _: None = Depends(require_access)):
return await notes.list_recent(current_user(request))
@app.get("/api/notes/lookup")
async def lookup_note(request: Request, title: str, _: None = Depends(require_access)):
note = await notes.lookup_by_title(current_user(request), title)
if note is None:
raise HTTPException(status_code=404, detail="note not found")
return note
@app.get("/api/notes/{note_id}")
async def get_note(note_id: str, _: None = Depends(require_access)):
note = await notes.get_note(note_id)
@@ -234,6 +244,24 @@ async def search(q: str, _: None = Depends(require_access)):
return await notes.search_notes(q)
# ---------------------------------------------------------------------------
# Templates
# ---------------------------------------------------------------------------
@app.get("/api/templates")
async def list_templates(request: Request, _: None = Depends(require_access)):
return await notes.list_templates(current_user(request))
@app.get("/api/templates/{name}")
async def get_template(name: str, request: Request, _: None = Depends(require_access)):
template = await notes.get_template(current_user(request), name)
if template is None:
raise HTTPException(status_code=404, detail="template not found")
return template
@app.get("/api/homepage")
async def homepage_stats(_: None = Depends(require_access)):
return await notes.get_homepage_stats()
@@ -247,5 +275,27 @@ async def extension_xpi() -> FileResponse:
)
# ---------------------------------------------------------------------------
# CLI distribution
# ---------------------------------------------------------------------------
@app.get("/cli/snotes.py", include_in_schema=False)
async def cli_script() -> FileResponse:
return FileResponse("cli/snotes.py", media_type="text/x-python")
@app.get("/{username}/cli", include_in_schema=False)
async def cli_install(username: str, request: Request) -> Response:
if username not in settings.user_list and username != settings.common_space:
raise HTTPException(status_code=404, detail="unknown user")
script = Path("cli/install.sh").read_text(encoding="utf-8")
scheme = request.headers.get("x-forwarded-proto", request.url.scheme)
host = request.headers.get("x-forwarded-host", request.headers.get("host", "localhost"))
url = f"{scheme}://{host}"
body = script.replace("__SNOTES_URL__", url).replace("__SNOTES_USER__", username)
return Response(content=body, media_type="text/plain")
# Mount static assets last so /api routes take precedence
app.mount("/static", StaticFiles(directory="static"), name="static")