ParamManagerScripts/backend/script_groups/EmailCrono/utils/attachment_handler.py

76 lines
2.2 KiB
Python

# utils/attachment_handler.py
import os
import hashlib
import re
def _contenido_hash(parte):
contenido = parte.get_payload(decode=True) or b""
return hashlib.md5(contenido).hexdigest()
def guardar_adjunto(parte, dir_adjuntos):
nombre = parte.get_filename()
if not nombre:
return None
nombre = re.sub(r'[<>:"/\\|?*]', "_", nombre)
ruta = os.path.join(dir_adjuntos, nombre)
if os.path.exists(ruta):
hash_nuevo = _contenido_hash(parte)
with open(ruta, "rb") as f:
hash_existente = hashlib.md5(f.read()).hexdigest()
if hash_nuevo == hash_existente:
return ruta
base, ext = os.path.splitext(nombre)
i = 1
while os.path.exists(ruta):
ruta = os.path.join(dir_adjuntos, f"{base}_{i}{ext}")
i += 1
with open(ruta, "wb") as f:
f.write(parte.get_payload(decode=True))
return ruta
def guardar_imagen(parte, dir_adjuntos):
"""
Guarda una imagen (inline o adjunta). Si no tiene filename, genera uno
basado en Content-ID o hash, preservando la extensión según el subtype.
Devuelve la ruta completa del archivo guardado.
"""
nombre = parte.get_filename()
if not nombre:
# Intentar usar Content-ID
content_id = parte.get("Content-ID", "") or parte.get("Content-Id", "")
content_id = content_id.strip("<>") if content_id else ""
ext = f".{parte.get_content_subtype() or 'bin'}"
base = (
re.sub(r"[^\w\-]+", "_", content_id)
if content_id
else _contenido_hash(parte)
)
nombre = f"img_{base}{ext}"
nombre = re.sub(r'[<>:"/\\|?*]', "_", nombre)
ruta = os.path.join(dir_adjuntos, nombre)
if os.path.exists(ruta):
hash_nuevo = _contenido_hash(parte)
with open(ruta, "rb") as f:
hash_existente = hashlib.md5(f.read()).hexdigest()
if hash_nuevo == hash_existente:
return ruta
base, ext = os.path.splitext(nombre)
i = 1
while os.path.exists(ruta):
ruta = os.path.join(dir_adjuntos, f"{base}_{i}{ext}")
i += 1
with open(ruta, "wb") as f:
f.write(parte.get_payload(decode=True))
return ruta