mirror of
https://github.com/idrainformatica/PecFlow.git
synced 2026-06-16 12:45:42 +02:00
130 lines
4.0 KiB
Python
130 lines
4.0 KiB
Python
"""
|
|
Script one-shot: corregge il body_text/body_html delle ricevute PEC gia' in DB.
|
|
|
|
Problema: il parser EML sovrascriveva il body delle ricevute con il contenuto
|
|
di postacert.eml (messaggio originale inviato), invece di mostrare il testo
|
|
della ricevuta stessa.
|
|
|
|
Questo script:
|
|
1. Trova tutti i messaggi in DB con pec_type di tipo ricevuta
|
|
2. Scarica l'EML grezzo da MinIO (raw_eml_path)
|
|
3. Lo ri-parsa con is_receipt=True (parser corretto)
|
|
4. Aggiorna body_text e body_html nel DB
|
|
|
|
Uso:
|
|
cd /opt/pechub
|
|
docker compose exec pechub-worker-1 python /app/scripts/fix_receipt_body.py
|
|
"""
|
|
|
|
import asyncio
|
|
import logging
|
|
import sys
|
|
from datetime import UTC, datetime
|
|
|
|
from sqlalchemy import select, update
|
|
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
|
|
from sqlalchemy.orm import sessionmaker
|
|
|
|
# Aggiungi il path dell'app
|
|
sys.path.insert(0, "/app")
|
|
|
|
from app.config import get_settings
|
|
from app.models import Message
|
|
from app.parsers.eml_parser import parse_eml
|
|
from app.storage.minio_client import download_attachment
|
|
|
|
logging.basicConfig(
|
|
level=logging.INFO,
|
|
format="%(asctime)s %(levelname)s %(message)s",
|
|
)
|
|
logger = logging.getLogger(__name__)
|
|
|
|
# Tipi di ricevuta che potrebbero avere il body sbagliato
|
|
RECEIPT_TYPES = {
|
|
"accettazione",
|
|
"non_accettazione",
|
|
"presa_in_carico",
|
|
"avvenuta_consegna",
|
|
"mancata_consegna",
|
|
"errore_consegna",
|
|
"preavviso_mancata_consegna",
|
|
"rilevazione_virus",
|
|
}
|
|
|
|
|
|
async def fix_receipt_bodies() -> None:
|
|
settings = get_settings()
|
|
|
|
engine = create_async_engine(settings.database_url, echo=False)
|
|
async_session = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
|
|
|
|
async with async_session() as db:
|
|
# Trova tutti i messaggi ricevuta con raw_eml_path
|
|
result = await db.execute(
|
|
select(Message).where(
|
|
Message.pec_type.in_(RECEIPT_TYPES),
|
|
Message.raw_eml_path.is_not(None),
|
|
).order_by(Message.created_at)
|
|
)
|
|
messages = result.scalars().all()
|
|
|
|
logger.info(f"Trovate {len(messages)} ricevute da verificare")
|
|
|
|
fixed = 0
|
|
skipped = 0
|
|
errors = 0
|
|
|
|
for msg in messages:
|
|
try:
|
|
# Scarica EML grezzo da MinIO (download_attachment funziona per qualsiasi path)
|
|
raw_eml = await download_attachment(msg.raw_eml_path)
|
|
if not raw_eml:
|
|
logger.warning(f"EML non trovato su MinIO per messaggio {msg.id} (path={msg.raw_eml_path!r})")
|
|
skipped += 1
|
|
continue
|
|
|
|
# Re-parsing con is_receipt=True (parser corretto)
|
|
parsed = parse_eml(raw_eml, is_receipt=True)
|
|
|
|
# Controlla se il body e' cambiato
|
|
new_body_text = parsed.body_text
|
|
new_body_html = parsed.body_html
|
|
|
|
if new_body_text == msg.body_text and new_body_html == msg.body_html:
|
|
logger.debug(f"Messaggio {msg.id} ({msg.pec_type}): body invariato, skip")
|
|
skipped += 1
|
|
continue
|
|
|
|
# Aggiorna nel DB
|
|
msg.body_text = new_body_text
|
|
msg.body_html = new_body_html
|
|
msg.updated_at = datetime.now(UTC)
|
|
|
|
logger.info(
|
|
f"Fixato: id={msg.id} pec_type={msg.pec_type!r} subject={msg.subject!r} "
|
|
f"body_text_len={len(new_body_text or '')}"
|
|
)
|
|
fixed += 1
|
|
|
|
except Exception as e:
|
|
logger.error(f"Errore su messaggio {msg.id}: {e}", exc_info=True)
|
|
errors += 1
|
|
continue
|
|
|
|
if fixed > 0:
|
|
await db.commit()
|
|
logger.info(f"Commit eseguito: {fixed} messaggi aggiornati")
|
|
else:
|
|
logger.info("Nessun messaggio da aggiornare")
|
|
|
|
logger.info(
|
|
f"Completato: fixed={fixed} skipped={skipped} errors={errors} "
|
|
f"totale={len(messages)}"
|
|
)
|
|
|
|
await engine.dispose()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
asyncio.run(fix_receipt_bodies())
|