115 lines
4.3 KiB
Python
115 lines
4.3 KiB
Python
# models/mensaje_email.py
|
|
import re
|
|
import hashlib
|
|
from datetime import datetime
|
|
from email.utils import parseaddr, parsedate_to_datetime
|
|
|
|
class MensajeEmail:
|
|
def __init__(self, remitente, fecha, contenido, subject=None, adjuntos=None):
|
|
self.remitente = self._estandarizar_remitente(remitente)
|
|
self.fecha = self._estandarizar_fecha(fecha)
|
|
self.subject = subject
|
|
self.contenido = self._limpiar_contenido(contenido)
|
|
self.adjuntos = adjuntos if adjuntos else []
|
|
self.hash = self._generar_hash()
|
|
|
|
def _limpiar_contenido(self, contenido):
|
|
if not contenido:
|
|
return ""
|
|
|
|
# Eliminar líneas de metadatos
|
|
lines = contenido.split('\n')
|
|
cleaned_lines = []
|
|
|
|
for line in lines:
|
|
# Skip metadata lines
|
|
if line.strip().startswith(('Da: ', 'Inviato: ', 'A: ', 'From: ', 'Sent: ', 'To: ')) or line.strip().startswith('Oggetto: '):
|
|
continue
|
|
# Limpiar espacios múltiples dentro de cada línea, pero mantener la línea completa
|
|
cleaned_line = re.sub(r' +', ' ', line)
|
|
cleaned_lines.append(cleaned_line)
|
|
|
|
# Unir las líneas preservando los saltos de línea
|
|
text = '\n'.join(cleaned_lines)
|
|
|
|
# Limpiar la combinación específica de CRLF+NBSP+CRLF
|
|
text = re.sub(r'\r?\n\xa0\r?\n', '\n', text)
|
|
|
|
# Reemplazar CRLF por LF
|
|
text = text.replace('\r\n', '\n')
|
|
|
|
# Reemplazar CR por LF
|
|
text = text.replace('\r', '\n')
|
|
|
|
# Reemplazar 3 o más saltos de línea por dos
|
|
text = re.sub(r'\n{3,}', '\n\n', text)
|
|
|
|
# Eliminar espacios al inicio y final del texto completo
|
|
return text.strip()
|
|
|
|
def to_markdown(self):
|
|
fecha_formato = self.fecha.strftime('%Y%m%d%H%M%S')
|
|
md = f"## {fecha_formato}|{self.remitente}\n\n"
|
|
if self.subject:
|
|
md += f"**Asunto**: {self.subject}\n\n"
|
|
md += self.contenido + "\n\n"
|
|
if self.adjuntos:
|
|
md += "### Adjuntos\n"
|
|
for adj in self.adjuntos:
|
|
md += f"- [[{adj}]]\n"
|
|
md += "---\n\n"
|
|
return md
|
|
|
|
def _estandarizar_remitente(self, remitente):
|
|
if 'Da:' in remitente:
|
|
remitente = remitente.split('Da:')[1].split('Inviato:')[0]
|
|
elif 'From:' in remitente:
|
|
remitente = remitente.split('From:')[1].split('Sent:')[0]
|
|
|
|
nombre, email = parseaddr(remitente)
|
|
if not nombre and email:
|
|
nombre = email.split('@')[0]
|
|
elif not nombre and not email:
|
|
nombre_match = re.search(r'([A-Za-z\s]+)\s*<', remitente)
|
|
if nombre_match:
|
|
nombre = nombre_match.group(1)
|
|
else:
|
|
return "Remitente Desconocido"
|
|
|
|
nombre = re.sub(r'[<>:"/\\|?*]', '', nombre.strip())
|
|
nombre = nombre.encode('ascii', 'ignore').decode('ascii')
|
|
return nombre
|
|
|
|
def _estandarizar_fecha(self, fecha):
|
|
if isinstance(fecha, str):
|
|
try:
|
|
return parsedate_to_datetime(fecha)
|
|
except:
|
|
return datetime.now()
|
|
return fecha
|
|
|
|
def _generar_hash(self):
|
|
"""
|
|
Genera un hash único para el mensaje basado en una combinación de campos
|
|
que identifican únicamente el mensaje
|
|
"""
|
|
# Limpiar y normalizar el contenido para el hash
|
|
# Para el hash, sí normalizamos completamente los espacios
|
|
contenido_hash = re.sub(r'\s+', ' ', self.contenido).strip()
|
|
|
|
# Normalizar el subject
|
|
subject_normalizado = re.sub(r'\s+', ' ', self.subject if self.subject else '').strip()
|
|
|
|
# Crear una cadena con los elementos clave del mensaje
|
|
elementos_hash = [
|
|
self.remitente.strip(),
|
|
self.fecha.strftime('%Y%m%d%H%M'), # Solo hasta minutos para permitir pequeñas variaciones
|
|
subject_normalizado,
|
|
contenido_hash[:500] # Usar solo los primeros 500 caracteres del contenido normalizado
|
|
]
|
|
|
|
# Unir todos los elementos con un separador único
|
|
texto_hash = '|'.join(elementos_hash)
|
|
|
|
# Generar el hash
|
|
return hashlib.md5(texto_hash.encode()).hexdigest() |