mirror of
https://github.com/idrainformatica/PecFlow.git
synced 2026-06-16 12:45:42 +02:00
97 lines
3.2 KiB
Python
97 lines
3.2 KiB
Python
"""
|
||
Job arq: sync_mailbox – trigger manuale per forzare la sincronizzazione di una casella.
|
||
|
||
Questo job viene usato per:
|
||
- Forzare una sync immediata dopo la creazione di una nuova casella
|
||
- Resync manuale da parte dell'admin
|
||
- Retry dopo un errore (called dal pool monitor)
|
||
|
||
Non sostituisce il loop IMAP continuo (IMAPConnection); è un one-shot job.
|
||
|
||
Sincronizza sia INBOX (per rilevare ricevute PEC e messaggi in arrivo)
|
||
sia la cartella Sent (per aggiornare imap_uid sul record send_pec ed
|
||
evitare duplicati outbound che rompono il binding delle ricevute).
|
||
"""
|
||
|
||
import logging
|
||
from typing import Any
|
||
|
||
from app.database import AsyncSessionLocal
|
||
from app.imap.sync import sync_new_messages, sync_sent_messages
|
||
from app.models import Mailbox
|
||
|
||
logger = logging.getLogger(__name__)
|
||
|
||
|
||
async def sync_mailbox(ctx: dict[str, Any], mailbox_id: str) -> dict:
|
||
"""
|
||
Job arq: sincronizza una singola casella PEC (INBOX + Sent).
|
||
|
||
Args:
|
||
ctx: contesto arq (contiene redis, pool reference)
|
||
mailbox_id: UUID della casella da sincronizzare
|
||
|
||
Returns:
|
||
dict con risultato del job
|
||
"""
|
||
redis_client = ctx.get("redis")
|
||
|
||
async with AsyncSessionLocal() as db:
|
||
mailbox = await db.get(Mailbox, mailbox_id)
|
||
|
||
if not mailbox:
|
||
return {"status": "error", "message": f"Mailbox {mailbox_id} non trovata"}
|
||
|
||
if mailbox.status not in ("active", "error"):
|
||
return {
|
||
"status": "skipped",
|
||
"message": f"Mailbox status={mailbox.status}, skip",
|
||
}
|
||
|
||
from app.imap.connection import IMAPConnection
|
||
|
||
creds = IMAPConnection._decrypt_creds(mailbox)
|
||
|
||
try:
|
||
conn = IMAPConnection(mailbox_id=mailbox_id, redis_client=redis_client)
|
||
client = await conn._connect(creds)
|
||
|
||
# Sync INBOX: ricevute PEC e messaggi in arrivo
|
||
n_inbox = await sync_new_messages(client, mailbox, db, redis_client)
|
||
|
||
# Sync Sent: aggiorna imap_uid sui record send_pec e previene duplicati.
|
||
# Fondamentale per il corretto binding delle ricevute PEC successive.
|
||
n_sent = 0
|
||
try:
|
||
n_sent = await sync_sent_messages(client, mailbox, db, redis_client)
|
||
except Exception as sent_err:
|
||
logger.warning(
|
||
f"[sync_mailbox] {mailbox.email_address} errore sync Sent "
|
||
f"(non critico): {sent_err}"
|
||
)
|
||
|
||
try:
|
||
await client.logout()
|
||
except Exception:
|
||
pass
|
||
|
||
logger.info(
|
||
f"[sync_mailbox] {mailbox.email_address}: "
|
||
f"INBOX={n_inbox} nuovi, Sent={n_sent} nuovi"
|
||
)
|
||
|
||
return {
|
||
"status": "ok",
|
||
"mailbox": mailbox.email_address,
|
||
"new_messages_inbox": n_inbox,
|
||
"new_messages_sent": n_sent,
|
||
}
|
||
|
||
except Exception as e:
|
||
logger.error(f"[sync_mailbox] {mailbox_id} errore: {e}", exc_info=True)
|
||
return {
|
||
"status": "error",
|
||
"mailbox": mailbox.email_address if mailbox else mailbox_id,
|
||
"message": str(e),
|
||
}
|