Uecko_ERP_FactuGES_sync/app/utils/mails_helper.py
2025-11-05 18:43:40 +01:00

54 lines
1.6 KiB
Python

import re
from typing import Any, Optional, Tuple
# Regex práctico (no RFC completo) para validar emails
_EMAIL_RE = re.compile(
r"""^(?=.{3,254}$) # longitud total razonable
(?=.{1,64}@) # parte local máx. 64
[A-Za-z0-9!#$%&'*+/=?^_`{|}~-]+
(?:\.[A-Za-z0-9!#$%&'*+/=?^_`{|}~-]+)* # puntos en la parte local
@
(?:[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?\.)+ # labels dominio
[A-Za-z]{2,63}$ # TLD
""",
re.X,
)
def corregir_y_validar_email(texto: Any) -> Tuple[bool, Optional[str]]:
"""
Normaliza y valida un email.
Correcciones aplicadas:
- Reemplaza comas por puntos.
- Elimina espacios alrededor y dentro (p. ej. 'a @ b . com' -> 'a@b.com').
- Convierte el dominio a minúsculas.
- Colapsa puntos consecutivos en el dominio ('..' -> '.').
Devuelve (es_valido, email_corregido | None).
"""
if texto is None:
return False, None
s = str(texto).strip()
# 1) comas -> puntos
s = s.replace(",", ".")
# 2) quita espacios
s = re.sub(r"\s+", "", s)
# 3) separar local y dominio (si es posible)
if s.count("@") != 1:
# no intentamos correcciones más agresivas si hay 0 o >1 '@'
return False, s or None
local, domain = s.split("@", 1)
# 4) normalizaciones de dominio
domain = domain.lower()
domain = re.sub(r"\.{2,}", ".", domain) # colapsar puntos dobles
candidato = f"{local}@{domain}"
# 5) validar
es_valido = _EMAIL_RE.match(candidato) is not None
return es_valido, (candidato if candidato else None)