feat: defer Web Push updates until tomorrow (Closes #563)
This commit is contained in:
1 parent
f4a4ed84c3
commit
7ce352553d
5 files changed
+213
-5
No files matched your search
+55
@@ -426,6 +426,10 @@ class LaterOperationBatch(BaseModel):
|
||||
operations: list[LaterOperation] = Field(min_length=1, max_length=50)
|
||||
|
||||
|
||||
class NotificationLaterRequest(BaseModel):
|
||||
wake_at: str = Field(min_length=1, max_length=100)
|
||||
|
||||
|
||||
class NotificationReply(BaseModel):
|
||||
body: str = Field(min_length=1, max_length=10_000)
|
||||
|
||||
@@ -3216,6 +3220,57 @@ async def read_notification(thread_id: int = PathParam(gt=0)) -> JSONResponse:
|
||||
return JSONResponse({"id": thread_id, "status": "read"})
|
||||
|
||||
|
||||
@app.patch("/api/v1/notifications/{thread_id}/later")
|
||||
async def defer_notification(
|
||||
payload: NotificationLaterRequest,
|
||||
thread_id: int = PathParam(gt=0),
|
||||
) -> JSONResponse:
|
||||
login = await _confirmed_login()
|
||||
try:
|
||||
item = await asyncio.wait_for(
|
||||
gitea_proxy.resolve_work_route("update", None, None, thread_id),
|
||||
timeout=NOTIFICATION_DETAIL_TIMEOUT_SECONDS,
|
||||
)
|
||||
repository = item.get("repository")
|
||||
if not isinstance(repository, str) or not repository:
|
||||
raise ValueError("The update has no repository identity")
|
||||
item_id = f"update:{repository}::{thread_id}"
|
||||
result = await asyncio.to_thread(
|
||||
_later_store().apply,
|
||||
login,
|
||||
f"push-tomorrow:{thread_id}:{payload.wake_at}",
|
||||
"defer",
|
||||
item_id,
|
||||
wake_at=payload.wake_at,
|
||||
)
|
||||
except gitea_proxy.WorkRouteUnavailableError:
|
||||
return JSONResponse(
|
||||
{"error": "This update is no longer available to defer."},
|
||||
status_code=409,
|
||||
)
|
||||
except ValueError as error:
|
||||
raise HTTPException(status_code=422, detail=str(error))
|
||||
except TimeoutError:
|
||||
return JSONResponse(
|
||||
{"error": "Deferring the update timed out. Please retry."},
|
||||
status_code=503,
|
||||
headers={"Retry-After": "1"},
|
||||
)
|
||||
except (OSError, sqlite3.Error):
|
||||
return JSONResponse(
|
||||
{"error": "Later synchronization is unavailable. Please retry."},
|
||||
status_code=503,
|
||||
headers={"Retry-After": "1"},
|
||||
)
|
||||
return JSONResponse({
|
||||
"id": thread_id,
|
||||
"status": "deferred",
|
||||
"item_id": item_id,
|
||||
"wake_at": payload.wake_at,
|
||||
"revision": result["revision"],
|
||||
})
|
||||
|
||||
|
||||
@app.post("/api/v1/notifications/{thread_id}/acknowledge")
|
||||
async def acknowledge_notification(thread_id: int = PathParam(gt=0)) -> JSONResponse:
|
||||
try:
|
||||
|
||||
Reference in new issue
Block a user