# 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()