144 lines
4.8 KiB
Python
144 lines
4.8 KiB
Python
# utils/forward_handler.py
|
|
import re
|
|
import os
|
|
from datetime import datetime
|
|
from email.utils import parseaddr
|
|
from models.mensaje_email import MensajeEmail
|
|
|
|
# Patrones de inicio de mensaje reenviado en diferentes idiomas
|
|
FORWARD_PATTERNS = [
|
|
r"[-]{3,}\s*Messaggio originale\s*[-]{3,}", # Italiano
|
|
r"[-]{3,}\s*Original Message\s*[-]{3,}", # Inglés
|
|
r"[-]{3,}\s*Mensaje original\s*[-]{3,}", # Español
|
|
r"[-]{3,}\s*Message d'origine\s*[-]{3,}", # Francés
|
|
r"[-]{3,}\s*Ursprüngliche Nachricht\s*[-]{3,}", # Alemán
|
|
# Variantes más flexibles
|
|
r"[-]{3,}\s*Forwarded message\s*[-]{3,}",
|
|
r"[-]{3,}\s*Mensaje reenviado\s*[-]{3,}",
|
|
r"[-]{3,}\s*Messaggio inoltrato\s*[-]{3,}",
|
|
# Patrones con > que suelen aparecer en texto plano
|
|
r"(?m)^>\s*[-]{3,}\s*Messaggio originale\s*[-]{3,}",
|
|
r"(?m)^>\s*[-]{3,}\s*Original Message\s*[-]{3,}"
|
|
]
|
|
|
|
# Patrones de headers en diferentes idiomas
|
|
HEADER_PATTERNS = {
|
|
'from': [
|
|
r"Da:\s*(.*)", # Italiano
|
|
r"From:\s*(.*)", # Inglés
|
|
r"De:\s*(.*)", # Español
|
|
r"Von:\s*(.*)", # Alemán
|
|
r"De :\s*(.*)" # Francés
|
|
],
|
|
'date': [
|
|
r"Inviato:\s*(.*)", # Italiano
|
|
r"Sent:\s*(.*)", # Inglés
|
|
r"Enviado:\s*(.*)", # Español
|
|
r"Gesendet:\s*(.*)", # Alemán
|
|
r"Envoyé :\s*(.*)" # Francés
|
|
],
|
|
'subject': [
|
|
r"Oggetto:\s*(.*)", # Italiano
|
|
r"Subject:\s*(.*)", # Inglés
|
|
r"Asunto:\s*(.*)", # Español
|
|
r"Betreff:\s*(.*)", # Alemán
|
|
r"Sujet :\s*(.*)" # Francés
|
|
]
|
|
}
|
|
|
|
def extract_forwarded_messages(contenido):
|
|
"""
|
|
Extrae mensajes reenviados del contenido del email
|
|
Retorna una lista de objetos MensajeEmail
|
|
"""
|
|
mensajes = []
|
|
|
|
# Crear el patrón de división combinando todos los patrones de reenvío
|
|
split_pattern = '|'.join(f"({pattern})" for pattern in FORWARD_PATTERNS)
|
|
|
|
# Dividir el contenido usando el patrón combinado
|
|
partes = re.split(split_pattern, contenido)
|
|
|
|
# El primer elemento es el contenido original del email
|
|
contenido_original = partes[0].strip()
|
|
|
|
# Procesar cada parte que coincide con un patrón de reenvío
|
|
for i in range(1, len(partes), len(FORWARD_PATTERNS) + 1):
|
|
# Encontrar qué patrón coincidió
|
|
patron_encontrado = next((p for p in partes[i:i+len(FORWARD_PATTERNS)] if p), None)
|
|
if patron_encontrado and i + len(FORWARD_PATTERNS) < len(partes):
|
|
contenido_reenviado = partes[i + len(FORWARD_PATTERNS)].strip()
|
|
if contenido_reenviado:
|
|
mensaje = _procesar_contenido_reenviado(contenido_reenviado)
|
|
if mensaje:
|
|
mensajes.append(mensaje)
|
|
|
|
return contenido_original, mensajes
|
|
|
|
def _procesar_contenido_reenviado(contenido):
|
|
"""
|
|
Procesa el contenido de un mensaje reenviado y extrae la información relevante
|
|
"""
|
|
# Extraer headers
|
|
remitente = None
|
|
fecha_str = None
|
|
subject = None
|
|
cuerpo = contenido
|
|
|
|
# Buscar headers al inicio del mensaje
|
|
lineas = contenido.split('\n')
|
|
headers_encontrados = 0
|
|
i = 0
|
|
|
|
while i < len(lineas) and headers_encontrados < 3:
|
|
linea = lineas[i].strip()
|
|
|
|
# Buscar remitente
|
|
if not remitente:
|
|
for pattern in HEADER_PATTERNS['from']:
|
|
match = re.match(pattern, linea)
|
|
if match:
|
|
remitente = match.group(1).strip()
|
|
headers_encontrados += 1
|
|
break
|
|
|
|
# Buscar fecha
|
|
if not fecha_str:
|
|
for pattern in HEADER_PATTERNS['date']:
|
|
match = re.match(pattern, linea)
|
|
if match:
|
|
fecha_str = match.group(1).strip()
|
|
headers_encontrados += 1
|
|
break
|
|
|
|
# Buscar asunto
|
|
if not subject:
|
|
for pattern in HEADER_PATTERNS['subject']:
|
|
match = re.match(pattern, linea)
|
|
if match:
|
|
subject = match.group(1).strip()
|
|
headers_encontrados += 1
|
|
break
|
|
|
|
i += 1
|
|
|
|
# Si encontramos headers, el cuerpo comienza después de ellos
|
|
if headers_encontrados > 0:
|
|
cuerpo = '\n'.join(lineas[i:]).strip()
|
|
|
|
# Si no tenemos la información mínima necesaria, retornar None
|
|
if not (remitente or fecha_str or cuerpo):
|
|
return None
|
|
|
|
# Crear el objeto MensajeEmail
|
|
try:
|
|
return MensajeEmail(
|
|
remitente=remitente or "Remitente Desconocido",
|
|
fecha=fecha_str or datetime.now(),
|
|
contenido=cuerpo,
|
|
subject=subject,
|
|
adjuntos=[]
|
|
)
|
|
except Exception as e:
|
|
print(f"Error creando mensaje reenviado: {str(e)}")
|
|
return None |