"""Resolve a draft's compose-attachment ids into raw (filename, mime, data) tuples.""" from __future__ import annotations import uuid from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession from app.indexer import blobstore from app.models import ComposeAttachment, Draft async def load_attachments( session: AsyncSession, user_id: uuid.UUID, draft: Draft ) -> list[tuple[str, str, bytes]]: """Return each of the draft's compose attachments as ``(filename, mime, data)``.""" raw_ids = draft.payload.get("attachment_ids") or [] if not isinstance(raw_ids, list) or not raw_ids: return [] ids: list[uuid.UUID] = [] for value in raw_ids: try: ids.append(uuid.UUID(str(value))) except ValueError: continue if not ids: return [] rows = await session.scalars( select(ComposeAttachment).where( ComposeAttachment.id.in_(ids), ComposeAttachment.user_id == user_id ) ) by_id = {r.id: r for r in rows} out: list[tuple[str, str, bytes]] = [] for i in ids: att = by_id.get(i) if att is not None: out.append((att.filename, att.mime_type, blobstore.load(user_id, att.blob_sha256))) return out