feat: 1-to-1 message render + web data-lake backend

This commit is contained in:
h
2026-05-31 01:27:40 +02:00
parent f0afb7ec5b
commit 75425d1bee
110 changed files with 10199 additions and 54 deletions
+40
View File
@@ -0,0 +1,40 @@
from typing import Annotated
import asyncpg
from dishka.integrations.fastapi import DishkaRoute, FromDishka
from fastapi import APIRouter, HTTPException, Query
from fastapi.responses import FileResponse
from utils.jobs import enqueue
from utils.read.avatars import current_avatar
from utils.storage import ContentAddressedStorage
router = APIRouter(prefix="/api/avatars", tags=["avatars"], route_class=DishkaRoute)
@router.get("/{owner_kind}/{owner_id}")
async def serve_avatar(
pool: FromDishka[asyncpg.Pool],
storage: FromDishka[ContentAddressedStorage],
owner_kind: str,
owner_id: int,
account_id: Annotated[int, Query()],
) -> FileResponse:
avatar = await current_avatar(pool, account_id, owner_kind, owner_id)
if avatar is None:
raise HTTPException(status_code=404, detail="avatar not found")
if not avatar.downloaded or avatar.storage_key is None:
await enqueue(
pool,
account_id,
"fetch_avatar",
{
"owner_kind": owner_kind,
"owner_id": owner_id,
"unique_id": avatar.unique_id,
},
)
raise HTTPException(status_code=409, detail="avatar not downloaded; fetching")
return FileResponse(
storage.url(avatar.storage_key), media_type=avatar.mime or "image/jpeg"
)