Improve activity response metadata

This commit is contained in:
Space-Banane
2026-06-03 13:23:04 +02:00
parent 16761bb82d
commit 490f053c64
3 changed files with 97 additions and 24 deletions
+56 -24
View File
@@ -1,3 +1,4 @@
import asyncio
import hashlib
import json
import logging
@@ -128,31 +129,50 @@ async def collect_merged_activity(
github_stale = False
gitea_stale = False
fetch_names: list[str] = []
fetch_tasks: list[asyncio.Task[tuple[dict[str, int], bool]]] = []
if options.source in ("all", "github"):
github_data, github_stale = await _fetch_with_cache(
cache,
gh_key,
lambda: fetch_github_activity(
username=settings.github_username,
token=settings.github_token,
from_date=from_date,
to_date=to_date,
),
fetch_names.append("github")
fetch_tasks.append(
asyncio.create_task(
_fetch_with_cache(
cache,
gh_key,
lambda: fetch_github_activity(
username=settings.github_username,
token=settings.github_token,
from_date=from_date,
to_date=to_date,
),
),
)
)
if options.source in ("all", "gitea"):
gitea_data, gitea_stale = await _fetch_with_cache(
cache,
gt_key,
lambda: fetch_gitea_activity(
base_url=settings.gitea_base_url,
username=settings.gitea_username,
token=settings.gitea_token,
from_date=from_date,
to_date=to_date,
),
fetch_names.append("gitea")
fetch_tasks.append(
asyncio.create_task(
_fetch_with_cache(
cache,
gt_key,
lambda: fetch_gitea_activity(
base_url=settings.gitea_base_url,
username=settings.gitea_username,
token=settings.gitea_token,
from_date=from_date,
to_date=to_date,
),
),
)
)
for name, (data, stale) in zip(fetch_names, await asyncio.gather(*fetch_tasks), strict=True):
if name == "github":
github_data, github_stale = data, stale
else:
gitea_data, gitea_stale = data, stale
merged = merge_activity(github_data, gitea_data, dates=_date_keys(from_date, to_date))
merged = filter_activity_source(merged, options.source)
@@ -169,6 +189,10 @@ def _daily_totals(merged: dict[str, dict[str, int]]) -> dict[str, int]:
return {day: int(payload.get("total", 0)) for day, payload in merged.items()}
def _activity_headers(result: ActivityResult) -> dict[str, str]:
return {"X-Activity-Stale": "true" if result.stale else "false"}
def _image_cache_key(prefix: str, options: QueryOptions, result: ActivityResult) -> str:
digest = hashlib.sha1(
json.dumps(result.merged, sort_keys=True, separators=(",", ":")).encode("utf-8")
@@ -203,7 +227,7 @@ async def activity_json(
"stale": result.stale,
"activity": result.merged,
}
return JSONResponse(content=payload)
return JSONResponse(content=payload, headers=_activity_headers(result))
@app.get("/activity.svg")
@@ -222,7 +246,11 @@ async def activity_svg(
if cache is not None:
cached = cache.get_json(cache_key)
if cached is not None:
return Response(content=str(cached.value), media_type="image/svg+xml")
return Response(
content=str(cached.value),
media_type="image/svg+xml",
headers=_activity_headers(result),
)
daily_totals = _daily_totals(result.merged)
total = sum(daily_totals.values())
@@ -236,7 +264,7 @@ async def activity_svg(
)
if cache is not None:
cache.set_json(cache_key, svg)
return Response(content=svg, media_type="image/svg+xml")
return Response(content=svg, media_type="image/svg+xml", headers=_activity_headers(result))
@app.get("/activity.png")
@@ -256,7 +284,11 @@ async def activity_png(
cached = cache.get_json(cache_key)
if cached is not None:
png_data = bytes.fromhex(str(cached.value))
return Response(content=png_data, media_type="image/png")
return Response(
content=png_data,
media_type="image/png",
headers=_activity_headers(result),
)
daily_totals = _daily_totals(result.merged)
total = sum(daily_totals.values())
@@ -275,4 +307,4 @@ async def activity_png(
raise HTTPException(status_code=500, detail="PNG rendering failed") from exc
if cache is not None:
cache.set_json(cache_key, png_data.hex())
return Response(content=png_data, media_type="image/png")
return Response(content=png_data, media_type="image/png", headers=_activity_headers(result))