CLI
This commit is contained in:
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user