diff --git a/__pycache__/controlador.cpython-313.pyc b/__pycache__/controlador.cpython-313.pyc index 2efa4c8..b21b685 100644 Binary files a/__pycache__/controlador.cpython-313.pyc and b/__pycache__/controlador.cpython-313.pyc differ diff --git a/__pycache__/modelo.cpython-313.pyc b/__pycache__/modelo.cpython-313.pyc index 9a44d12..20fd2c9 100644 Binary files a/__pycache__/modelo.cpython-313.pyc and b/__pycache__/modelo.cpython-313.pyc differ diff --git a/__pycache__/vista.cpython-313.pyc b/__pycache__/vista.cpython-313.pyc index 11f572a..b7f8ca2 100644 Binary files a/__pycache__/vista.cpython-313.pyc and b/__pycache__/vista.cpython-313.pyc differ diff --git a/controlador.py b/controlador.py index a4bb3cb..bd5b751 100644 --- a/controlador.py +++ b/controlador.py @@ -23,13 +23,13 @@ class CorreoControlador: def obtener_correos(self): return self.modelo.obtener_correos() - def enviar_correo(self, destinatario, asunto, mensaje): - hilo = threading.Thread(target=self._enviar_correo(destinatario,asunto,mensaje)) - hilo.start(); + def enviar_correo(self, destinatario, asunto, mensaje, archivos_adjuntos=[]): + hilo = threading.Thread(target=self._enviar_correo, args=(destinatario, asunto, mensaje, archivos_adjuntos)) + hilo.start() - def _enviar_correo(self, destinatario, asunto, mensaje): + def _enviar_correo(self, destinatario, asunto, mensaje, archivos_adjuntos): 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: messagebox.showinfo("Éxito", mensaje_respuesta) else: diff --git a/modelo.py b/modelo.py index 61c598d..7425b2f 100644 --- a/modelo.py +++ b/modelo.py @@ -5,8 +5,12 @@ from email.utils import parsedate_to_datetime import smtplib from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText +from email.mime.base import MIMEBase +from email import encoders from datetime import datetime import re +import os + class CorreoModelo: POP3_SERVER = "s1.ieslamar.org" #192.168.120.103 @@ -115,7 +119,7 @@ class CorreoModelo: return False @staticmethod - def enviar_correo(destinatario, asunto, mensaje): + def enviar_correo(destinatario, asunto, mensaje, archivos_adjuntos=[]): try: if not CorreoModelo.validar_correo(destinatario): return False, "Dirección de correo inválida" @@ -128,11 +132,22 @@ class CorreoModelo: msg["Subject"] = asunto msg["Date"] = fecha_envio - mensaje_completo = f""" - {mensaje} - """ + mensaje_completo = f"{mensaje}" 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.ehlo() server.login(CorreoModelo.EMAIL_USER, CorreoModelo.EMAIL_PASS) @@ -143,7 +158,7 @@ class CorreoModelo: except Exception as e: return False, f"Error enviando correo: {e}" - + @staticmethod def validar_correo(destinatario): patron = r"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$" diff --git a/vista.py b/vista.py index b7a834c..08f2fb1 100644 --- a/vista.py +++ b/vista.py @@ -1,5 +1,5 @@ import tkinter as tk -from tkinter import ttk, messagebox, scrolledtext +from tkinter import ttk, messagebox, scrolledtext, filedialog from controlador import CorreoControlador import threading import time @@ -109,7 +109,6 @@ class CorreoVista: btn_cambiar = ttk.Button(self.frame_f2, text="🔄 Cambiar", command=self.cambiar_credenciales) btn_cambiar.pack(pady=10) - def crear_frame_f3(self): label_envio = tk.Label(self.frame_f3, text="📤 Enviar Correo", font=("Arial", 16), bg="#f4f4f4") 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.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.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): destinatario = self.entry_destinatario.get().strip() asunto = self.entry_asunto.get().strip() @@ -141,7 +157,8 @@ class CorreoVista: messagebox.showwarning("⚠️ Advertencia", "Todos los campos son obligatorios.") return - self.controlador.enviar_correo(destinatario, asunto, mensaje) + self.controlador.enviar_correo(destinatario, asunto, mensaje, self.archivos_adjuntos) + def mostrar_correo(self): seleccionado = self.tree.selection()