Spaces:
Sleeping
Sleeping
File size: 1,968 Bytes
0a367ef | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | import base64
import logging
from pathlib import Path
import aiosqlite
from app.config import settings
from app.database import update_notification_status
from app.lib.graph.client import GraphClient
from app.lib.utils.storage import write_email
logger = logging.getLogger(__name__)
_LARGE_ATTACHMENT_THRESHOLD = 3 * 1024 * 1024 # 3 MB
async def fetch_and_store(
client: GraphClient,
message_id: str,
notif_db_id: int,
storage_path: Path,
conn: aiosqlite.Connection,
) -> Path:
email_data = await client.get(
f"/users/{settings.mailbox_user}/messages/{message_id}",
params={"$expand": "attachments", "$select": (
"id,subject,from,toRecipients,ccRecipients,receivedDateTime,"
"body,uniqueBody,hasAttachments,attachments,webLink"
)},
)
attachment_bytes: list[tuple[str, str, bytes]] = []
for att in email_data.get("attachments", []):
if att.get("@odata.type") != "#microsoft.graph.fileAttachment":
continue
filename = att.get("name", "attachment")
content_type = att.get("contentType", "application/octet-stream")
size = att.get("size", 0)
if size > _LARGE_ATTACHMENT_THRESHOLD or not att.get("contentBytes"):
raw = await _fetch_large_attachment(client, message_id, att["id"])
else:
raw = base64.b64decode(att["contentBytes"])
attachment_bytes.append((filename, content_type, raw))
dest = await write_email(email_data, attachment_bytes, storage_path)
await update_notification_status(
conn, notif_db_id, "fetched", storage_path=str(dest)
)
logger.info("Stored email %s at %s", message_id, dest)
return dest
async def _fetch_large_attachment(
client: GraphClient, message_id: str, attachment_id: str
) -> bytes:
return await client.get_raw(
f"/users/{settings.mailbox_user}/messages/{message_id}/attachments/{attachment_id}/$value"
)
|