diff --git a/yunke-server/app/api/routers/export.py b/yunke-server/app/api/routers/export.py index 33c9a97..bf06787 100644 --- a/yunke-server/app/api/routers/export.py +++ b/yunke-server/app/api/routers/export.py @@ -21,6 +21,13 @@ router = APIRouter(prefix="/api/export", tags=["export"]) SessionDep = Annotated[AsyncSession, Depends(get_session)] +# Hard cap on rows an HTML export will load + render. An account-wide export +# with no date range can match millions of messages; rendering all of them in +# memory risks OOM. The cap is a safety valve, not a tight budget — at 5k rows +# the HTML is already unwieldy in any browser. When hit, the response carries +# a visible warning banner so the operator knows to narrow the date range. +EXPORT_MAX_ROWS = 5000 + def _ts_text(ts: int | None) -> str: if not ts: @@ -73,7 +80,14 @@ def _render_media(m) -> str: return "" -def _render_chat_html(rows: list[Message], channel: str, owner: str, peer: str) -> str: +def _render_chat_html( + rows: list[Message], + channel: str, + owner: str, + peer: str, + *, + warning: str = "", +) -> str: bubbles = [] for m in rows: side = "right" if m.is_send else "left" @@ -90,6 +104,7 @@ def _render_chat_html(rows: list[Message], channel: str, owner: str, peer: str)
暂无消息
'}