feat: preview mobile review diffs (#123)
This commit is contained in:
1 parent
f662361b09
commit
6c4ce5cf48
5 files changed
+220
-3
No files matched your search
@@ -1,10 +1,13 @@
|
||||
import os
|
||||
import shlex
|
||||
from typing import Any
|
||||
|
||||
import httpx
|
||||
|
||||
GITEA_URL = os.getenv("GITEA_URL", "http://127.0.0.1:3000").rstrip("/")
|
||||
GITEA_TOKEN = os.getenv("GITEA_TOKEN", "")
|
||||
REVIEW_DIFF_MAX_BYTES = 64 * 1024
|
||||
REVIEW_DIFF_MAX_LINES = 400
|
||||
|
||||
|
||||
def _auth() -> dict[str, str]:
|
||||
@@ -21,6 +24,66 @@ async def fetch(path: str) -> Any:
|
||||
return r.json()
|
||||
|
||||
|
||||
async def fetch_text(path: str, max_bytes: int) -> tuple[str, bool]:
|
||||
chunks: list[bytes] = []
|
||||
size = 0
|
||||
truncated = False
|
||||
async with httpx.AsyncClient(base_url=GITEA_URL, timeout=10) as client:
|
||||
async with client.stream(
|
||||
"GET", f"/api/v1/{path}", headers={**_auth(), "Accept": "text/plain"}
|
||||
) as response:
|
||||
response.raise_for_status()
|
||||
async for chunk in response.aiter_bytes():
|
||||
remaining = max_bytes - size
|
||||
if len(chunk) > remaining:
|
||||
chunks.append(chunk[:remaining])
|
||||
truncated = True
|
||||
break
|
||||
chunks.append(chunk)
|
||||
size += len(chunk)
|
||||
return b"".join(chunks).decode("utf-8", errors="replace"), truncated
|
||||
|
||||
|
||||
def _diff_previews(diff: str, stream_truncated: bool) -> dict[str, dict]:
|
||||
previews: dict[str, dict] = {}
|
||||
current: dict | None = None
|
||||
in_hunk = False
|
||||
remaining = REVIEW_DIFF_MAX_LINES
|
||||
for line in diff.splitlines():
|
||||
if line.startswith("diff --git "):
|
||||
try:
|
||||
target = shlex.split(line)[3]
|
||||
filename = target[2:] if target.startswith("b/") else target
|
||||
except (IndexError, ValueError):
|
||||
current = None
|
||||
continue
|
||||
current = {
|
||||
"diff_lines": [],
|
||||
"diff_available": False,
|
||||
"diff_binary": False,
|
||||
"diff_truncated": stream_truncated,
|
||||
}
|
||||
previews[filename] = current
|
||||
in_hunk = False
|
||||
continue
|
||||
if current is None:
|
||||
continue
|
||||
if line.startswith("Binary files ") or line == "GIT binary patch":
|
||||
current["diff_binary"] = True
|
||||
in_hunk = False
|
||||
continue
|
||||
if line.startswith("@@"):
|
||||
in_hunk = True
|
||||
if in_hunk and not line.startswith("\\ No newline at end of file"):
|
||||
if remaining:
|
||||
current["diff_lines"].append(line)
|
||||
current["diff_available"] = True
|
||||
remaining -= 1
|
||||
else:
|
||||
current["diff_truncated"] = True
|
||||
return previews
|
||||
|
||||
|
||||
async def current_user() -> dict:
|
||||
return await fetch("user")
|
||||
|
||||
@@ -79,6 +142,10 @@ async def pull_review_detail(repository: str, number: int) -> dict:
|
||||
sha = sha_value if isinstance(sha_value, str) else ""
|
||||
status = await fetch(f"repos/{repository}/commits/{sha}/status")
|
||||
reviews = await fetch(f"{base}/reviews")
|
||||
diff, diff_truncated = await fetch_text(
|
||||
f"repos/{repository}/pulls/{number}.diff", REVIEW_DIFF_MAX_BYTES
|
||||
)
|
||||
previews = _diff_previews(diff, diff_truncated)
|
||||
user_value = pull.get("user")
|
||||
user: dict = user_value if isinstance(user_value, dict) else {}
|
||||
normalized_files = [
|
||||
@@ -87,6 +154,15 @@ async def pull_review_detail(repository: str, number: int) -> dict:
|
||||
"status": file.get("status") or "changed",
|
||||
"additions": file.get("additions") or 0,
|
||||
"deletions": file.get("deletions") or 0,
|
||||
**previews.get(
|
||||
file["filename"],
|
||||
{
|
||||
"diff_lines": [],
|
||||
"diff_available": False,
|
||||
"diff_binary": False,
|
||||
"diff_truncated": diff_truncated,
|
||||
},
|
||||
),
|
||||
}
|
||||
for file in (files if isinstance(files, list) else [])[:100]
|
||||
if isinstance(file, dict) and isinstance(file.get("filename"), str)
|
||||
|
||||
Reference in new issue
Block a user