From 4a6c0401bea92bbe93ea39c7e6728867258d221d Mon Sep 17 00:00:00 2001 From: brutsalvadi Date: Mon, 11 May 2026 14:57:13 +0200 Subject: [PATCH] Add GET /api/diff/:hash endpoint; WikiLog collapsible diffs --- edit/server.py | 17 +++++++++++++++++ site | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/edit/server.py b/edit/server.py index 080f6d2..a35ea02 100644 --- a/edit/server.py +++ b/edit/server.py @@ -43,6 +43,7 @@ _SESSION_COOKIE = "bincio_session" _SAFE_SLUG = re.compile(r"^[a-zA-Z0-9_][a-zA-Z0-9_\-/]*$") _SAFE_HANDLE = re.compile(r"^[a-z][a-z0-9_-]{1,19}$") +_SAFE_HASH = re.compile(r"^[0-9a-f]{4,40}$") _ALLOWED_IMAGE_TYPES = {"image/jpeg", "image/png", "image/webp", "image/gif"} _MAX_IMAGE_BYTES = 10 * 1024 * 1024 # 10 MB @@ -286,6 +287,22 @@ async def get_wiki_log(user: User = Depends(require_auth)) -> JSONResponse: return JSONResponse({"log": entries}) +@app.get("/api/diff/{commit_hash}") +async def get_diff(commit_hash: str, user: User = Depends(require_auth)) -> JSONResponse: + if not _SAFE_HASH.match(commit_hash): + raise HTTPException(status_code=400, detail="invalid hash") + env = _git_env() + proc = await asyncio.create_subprocess_exec( + "git", "show", commit_hash, "-p", "--no-color", "--format=", "--", "pages/", "blog/", + cwd=str(_ROOT), env=env, + stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE, + ) + stdout, _ = await proc.communicate() + if proc.returncode != 0: + raise HTTPException(status_code=404, detail="commit not found") + return JSONResponse({"diff": stdout.decode(errors="replace")}) + + @app.get("/api/me") async def me(user: User = Depends(require_auth)) -> JSONResponse: return JSONResponse({ diff --git a/site b/site index 5341988..b78af43 160000 --- a/site +++ b/site @@ -1 +1 @@ -Subproject commit 5341988e8d40ec8a9866b4682098f4805e792d56 +Subproject commit b78af4312211d9f68e73e9d250857e90d636217e