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:
		
							parent
							
								
									0884f98a50
								
							
						
					
					
						commit
						877c95cead
					
				
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							| 
						 | 
					@ -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:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										25
									
								
								modelo.py
								
								
								
								
							
							
						
						
									
										25
									
								
								modelo.py
								
								
								
								
							| 
						 | 
					@ -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-.]+$"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										25
									
								
								vista.py
								
								
								
								
							
							
						
						
									
										25
									
								
								vista.py
								
								
								
								
							| 
						 | 
					@ -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()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue