Enviar correos con archivos adjuntos

Ahoar nos permite enviar correos con archivos adjuntos,
Pero a la hora de recibirlos no podemos recuperar esos archivos, eso
sera la ampliacion d la sigueinte version.
This commit is contained in:
Kevin William Olarte Braun 2025-02-13 11:03:54 +01:00
parent 0884f98a50
commit 877c95cead
6 changed files with 46 additions and 14 deletions

Binary file not shown.

Binary file not shown.

View File

@ -23,13 +23,13 @@ class CorreoControlador:
def obtener_correos(self): def obtener_correos(self):
return self.modelo.obtener_correos() return self.modelo.obtener_correos()
def enviar_correo(self, destinatario, asunto, mensaje): def enviar_correo(self, destinatario, asunto, mensaje, archivos_adjuntos=[]):
hilo = threading.Thread(target=self._enviar_correo(destinatario,asunto,mensaje)) hilo = threading.Thread(target=self._enviar_correo, args=(destinatario, asunto, mensaje, archivos_adjuntos))
hilo.start(); hilo.start()
def _enviar_correo(self, destinatario, asunto, mensaje): def _enviar_correo(self, destinatario, asunto, mensaje, archivos_adjuntos):
self.vista.actualizar_footer("📨 Enviando correo...") self.vista.actualizar_footer("📨 Enviando correo...")
resultado, mensaje_respuesta = CorreoModelo.enviar_correo(destinatario, asunto, mensaje) resultado, mensaje_respuesta = CorreoModelo.enviar_correo(destinatario, asunto, mensaje, archivos_adjuntos)
if resultado: if resultado:
messagebox.showinfo("Éxito", mensaje_respuesta) messagebox.showinfo("Éxito", mensaje_respuesta)
else: else:

View File

@ -5,8 +5,12 @@ from email.utils import parsedate_to_datetime
import smtplib import smtplib
from email.mime.multipart import MIMEMultipart from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders
from datetime import datetime from datetime import datetime
import re import re
import os
class CorreoModelo: class CorreoModelo:
POP3_SERVER = "s1.ieslamar.org" #192.168.120.103 POP3_SERVER = "s1.ieslamar.org" #192.168.120.103
@ -115,7 +119,7 @@ class CorreoModelo:
return False return False
@staticmethod @staticmethod
def enviar_correo(destinatario, asunto, mensaje): def enviar_correo(destinatario, asunto, mensaje, archivos_adjuntos=[]):
try: try:
if not CorreoModelo.validar_correo(destinatario): if not CorreoModelo.validar_correo(destinatario):
return False, "Dirección de correo inválida" return False, "Dirección de correo inválida"
@ -128,11 +132,22 @@ class CorreoModelo:
msg["Subject"] = asunto msg["Subject"] = asunto
msg["Date"] = fecha_envio msg["Date"] = fecha_envio
mensaje_completo = f""" mensaje_completo = f"{mensaje}"
{mensaje}
"""
msg.attach(MIMEText(mensaje_completo, "plain")) msg.attach(MIMEText(mensaje_completo, "plain"))
# Agregar archivos adjuntos
for archivo in archivos_adjuntos:
if os.path.exists(archivo):
with open(archivo, "rb") as adjunto:
part = MIMEBase("application", "octet-stream")
part.set_payload(adjunto.read())
encoders.encode_base64(part)
part.add_header(
"Content-Disposition",
f"attachment; filename={os.path.basename(archivo)}",
)
msg.attach(part)
server = smtplib.SMTP(CorreoModelo.SMTP_SERVER, CorreoModelo.SMTP_PORT) server = smtplib.SMTP(CorreoModelo.SMTP_SERVER, CorreoModelo.SMTP_PORT)
server.ehlo() server.ehlo()
server.login(CorreoModelo.EMAIL_USER, CorreoModelo.EMAIL_PASS) server.login(CorreoModelo.EMAIL_USER, CorreoModelo.EMAIL_PASS)
@ -143,7 +158,7 @@ class CorreoModelo:
except Exception as e: except Exception as e:
return False, f"Error enviando correo: {e}" return False, f"Error enviando correo: {e}"
@staticmethod @staticmethod
def validar_correo(destinatario): def validar_correo(destinatario):
patron = r"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$" patron = r"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$"

View File

@ -1,5 +1,5 @@
import tkinter as tk import tkinter as tk
from tkinter import ttk, messagebox, scrolledtext from tkinter import ttk, messagebox, scrolledtext, filedialog
from controlador import CorreoControlador from controlador import CorreoControlador
import threading import threading
import time import time
@ -109,7 +109,6 @@ class CorreoVista:
btn_cambiar = ttk.Button(self.frame_f2, text="🔄 Cambiar", command=self.cambiar_credenciales) btn_cambiar = ttk.Button(self.frame_f2, text="🔄 Cambiar", command=self.cambiar_credenciales)
btn_cambiar.pack(pady=10) btn_cambiar.pack(pady=10)
def crear_frame_f3(self): def crear_frame_f3(self):
label_envio = tk.Label(self.frame_f3, text="📤 Enviar Correo", font=("Arial", 16), bg="#f4f4f4") label_envio = tk.Label(self.frame_f3, text="📤 Enviar Correo", font=("Arial", 16), bg="#f4f4f4")
label_envio.pack(pady=20) label_envio.pack(pady=20)
@ -129,9 +128,26 @@ class CorreoVista:
self.text_mensaje = scrolledtext.ScrolledText(self.frame_f3, wrap=tk.WORD, height=10, font=("Arial", 12)) self.text_mensaje = scrolledtext.ScrolledText(self.frame_f3, wrap=tk.WORD, height=10, font=("Arial", 12))
self.text_mensaje.pack(fill=tk.BOTH, expand=True, padx=10, pady=5) self.text_mensaje.pack(fill=tk.BOTH, expand=True, padx=10, pady=5)
# Botón para seleccionar archivos
btn_adjuntar = ttk.Button(self.frame_f3, text="📎 Adjuntar Archivos", command=self.seleccionar_archivos)
btn_adjuntar.pack(pady=5)
# Lista de archivos seleccionados
self.label_archivos = tk.Label(self.frame_f3, text="No hay archivos adjuntos", font=("Arial", 10), bg="#f4f4f4")
self.label_archivos.pack(pady=5)
btn_enviar = ttk.Button(self.frame_f3, text="📨 Enviar", command=self.enviar_correo) btn_enviar = ttk.Button(self.frame_f3, text="📨 Enviar", command=self.enviar_correo)
btn_enviar.pack(pady=10) btn_enviar.pack(pady=10)
def seleccionar_archivos(self):
archivos = filedialog.askopenfilenames(title="Seleccionar archivos adjuntos")
if archivos:
self.archivos_adjuntos = list(archivos)
archivos_texto = "\n".join(self.archivos_adjuntos)
self.label_archivos.config(text=f"Archivos adjuntos:\n{archivos_texto}")
else:
self.label_archivos.config(text="No hay archivos adjuntos")
def enviar_correo(self): def enviar_correo(self):
destinatario = self.entry_destinatario.get().strip() destinatario = self.entry_destinatario.get().strip()
asunto = self.entry_asunto.get().strip() asunto = self.entry_asunto.get().strip()
@ -141,7 +157,8 @@ class CorreoVista:
messagebox.showwarning("⚠️ Advertencia", "Todos los campos son obligatorios.") messagebox.showwarning("⚠️ Advertencia", "Todos los campos son obligatorios.")
return return
self.controlador.enviar_correo(destinatario, asunto, mensaje) self.controlador.enviar_correo(destinatario, asunto, mensaje, self.archivos_adjuntos)
def mostrar_correo(self): def mostrar_correo(self):
seleccionado = self.tree.selection() seleccionado = self.tree.selection()