import tkinter as tk from tkinter import ttk, messagebox, scrolledtext, filedialog from controlador import CorreoControlador import threading import time class CorreoVista: def __init__(self, root, controlador): self.root = root self.controlador = controlador self.root.title("📬 Gestor de Correos") self.root.geometry("900x600") self.root.configure(bg="#f4f4f4") self.archivos_adjuntos = [] # Frame del menú izquierdo self.menu_frame = tk.Frame(self.root, bg="#333333", width=200) self.menu_frame.pack(side=tk.LEFT, fill=tk.Y) # Botones del menú self.btn_f1 = tk.Button(self.menu_frame, text="📋 Listado", font=("Arial", 12), bg="#555555", fg="white", relief=tk.FLAT, command=self.mostrar_frame_f1) self.btn_f1.pack(fill=tk.X, pady=5, padx=5) self.btn_f2 = tk.Button(self.menu_frame, text="⚙️ Configuración", font=("Arial", 12), bg="#555555", fg="white", relief=tk.FLAT, command=self.mostrar_frame_f2) self.btn_f2.pack(fill=tk.X, pady=5, padx=5) self.btn_f3 = tk.Button(self.menu_frame, text="📤 Enviar Correo", font=("Arial", 12), bg="#555555", fg="white", relief=tk.FLAT, command=self.mostrar_frame_f3) self.btn_f3.pack(fill=tk.X, pady=5, padx=5) # Frame principal derecho self.main_frame = tk.Frame(self.root, bg="#f4f4f4") self.main_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True) # Barra inferior self.footer_frame = tk.Frame(self.root, bg="#1E90FF", height=30) self.footer_frame.place(relx=0, rely=1.0, relwidth=1, anchor="sw") self.footer_label = tk.Label(self.footer_frame, text="Gestor de Correos - 2025", bg="#1E90FF", fg="white", font=("Arial", 10)) self.footer_label.pack(side=tk.RIGHT, padx=10) # Frames individuales para cada sección self.frame_f1 = tk.Frame(self.main_frame, bg="#f4f4f4") self.frame_f2 = tk.Frame(self.main_frame, bg="#f4f4f4") self.frame_f3 = tk.Frame(self.main_frame, bg="#f4f4f4") self.crear_frame_f1() self.crear_frame_f2() self.crear_frame_f3() # Mostrar el primer frame por defecto self.frame_f1.pack(fill=tk.BOTH, expand=True) # Iniciar el hilo de actualización de la barra self.ejecutar_hilo_actualizacion_barra() def mostrar_frame_f1(self): self.frame_f2.pack_forget() self.frame_f3.pack_forget() self.frame_f1.pack(fill=tk.BOTH, expand=True) def mostrar_frame_f2(self): self.frame_f1.pack_forget() self.frame_f3.pack_forget() self.frame_f2.pack(fill=tk.BOTH, expand=True) def mostrar_frame_f3(self): self.frame_f1.pack_forget() self.frame_f2.pack_forget() self.frame_f3.pack(fill=tk.BOTH, expand=True) def crear_frame_f1(self): frame_top = tk.Frame(self.frame_f1, bg="#f4f4f4") frame_top.pack(pady=10, fill=tk.X) btn_descargar = ttk.Button(frame_top, text="📥 Descargar Correos", command=self.controlador.descargar_correos) btn_descargar.pack(side=tk.LEFT, padx=10) btn_mostrar = ttk.Button(frame_top, text="🔍 Mostrar Correo", command=self.mostrar_correo) btn_mostrar.pack(side=tk.LEFT, padx=10) btn_descargar_archivo = ttk.Button(frame_top, text="📥 Descargar Archivo", command=self.descargar_archivo_adjunto) btn_descargar_archivo.pack(side=tk.LEFT, padx=10) # Agregado el nuevo botón frame_list = tk.Frame(self.frame_f1, bg="#ffffff", bd=2, relief=tk.GROOVE) frame_list.pack(fill=tk.BOTH, expand=True, padx=10, pady=5) self.tree = ttk.Treeview(frame_list, columns=("Remitente", "Asunto", "Fecha", "Cuerpo"), show="headings") self.tree.heading("Remitente", text="✉️ Remitente") self.tree.heading("Asunto", text="📌 Asunto") self.tree.heading("Fecha", text="📅 Fecha") self.tree.heading("Cuerpo", text="📝 Cuerpo") self.tree.pack(fill=tk.BOTH, expand=True) frame_details = tk.Frame(self.frame_f1, bg="#ffffff", bd=2, relief=tk.GROOVE) frame_details.pack(fill=tk.BOTH, expand=True, padx=10, pady=5) self.detalle_text = scrolledtext.ScrolledText(frame_details, wrap=tk.WORD, height=10, font=("Arial", 10)) self.detalle_text.pack(fill=tk.BOTH, expand=True) def crear_frame_f2(self): label_config = tk.Label(self.frame_f2, text="⚙️ Configuración de Usuario", font=("Arial", 16), bg="#f4f4f4") label_config.pack(pady=20) tk.Label(self.frame_f2, text="Usuario (correo):", font=("Arial", 12), bg="#f4f4f4").pack() self.entry_usuario = tk.Entry(self.frame_f2, font=("Arial", 12), width=50) self.entry_usuario.pack(pady=5) tk.Label(self.frame_f2, text="Contraseña:", font=("Arial", 12), bg="#f4f4f4").pack() self.entry_contraseña = tk.Entry(self.frame_f2, font=("Arial", 12), width=50, show="*") self.entry_contraseña.pack(pady=5) 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) frame_inputs = tk.Frame(self.frame_f3, bg="#f4f4f4") frame_inputs.pack(pady=10, padx=10, fill=tk.X) tk.Label(frame_inputs, text="Para:", font=("Arial", 12), bg="#f4f4f4").grid(row=0, column=0, sticky="w", padx=5) self.entry_destinatario = tk.Entry(frame_inputs, font=("Arial", 12), width=50) self.entry_destinatario.grid(row=0, column=1, pady=5) tk.Label(frame_inputs, text="Asunto:", font=("Arial", 12), bg="#f4f4f4").grid(row=1, column=0, sticky="w", padx=5) self.entry_asunto = tk.Entry(frame_inputs, font=("Arial", 12), width=50) self.entry_asunto.grid(row=1, column=1, pady=5) tk.Label(self.frame_f3, text="Mensaje:", font=("Arial", 12), bg="#f4f4f4").pack(anchor="w", padx=10) 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): archivo = filedialog.askopenfilename(title="Seleccionar un archivo adjunto") # Permitir solo un archivo if archivo: self.archivos_adjuntos = [archivo] # Solo un archivo en la lista self.label_archivos.config(text=f"Archivo adjunto: {archivo}") else: self.label_archivos.config(text="No hay archivo adjunto") def enviar_correo(self): destinatario = self.entry_destinatario.get().strip() asunto = self.entry_asunto.get().strip() mensaje = self.text_mensaje.get("1.0", tk.END).strip() if not destinatario or not asunto or not mensaje: messagebox.showwarning("⚠️ Advertencia", "Todos los campos son obligatorios.") return self.controlador.enviar_correo(destinatario, asunto, mensaje, self.archivos_adjuntos) def mostrar_correo(self): seleccionado = self.tree.selection() if not seleccionado: messagebox.showwarning("⚠️ Advertencia", "Seleccione un correo") return correo_id = seleccionado[0] correo = self.tree.item(correo_id, "values") # Obtener el correo desde la base de datos correo_db = self.controlador.modelo.collection.find_one( {"remitente": correo[0], "asunto": correo[1], "fecha": correo[2]} ) if correo_db is None: messagebox.showerror("Error", "No se encontró el correo en la base de datos") return archivos_adjuntos = correo_db.get("archivos_adjuntos", []) # Asegurar que siempre exista la clave self.detalle_text.delete("1.0", tk.END) self.detalle_text.insert(tk.END, f"📧 Remitente: {correo[0]}\n") self.detalle_text.insert(tk.END, f"📌 Asunto: {correo[1]}\n") self.detalle_text.insert(tk.END, f"📅 Fecha: {correo[2]}\n\n") self.detalle_text.insert(tk.END, f"📝 Mensaje:\n{correo[3]}\n\n") if archivos_adjuntos: self.detalle_text.insert(tk.END, "📎 Archivos Adjuntos:\n") for archivo in archivos_adjuntos: self.detalle_text.insert(tk.END, f" - {archivo}\n") else: self.detalle_text.insert(tk.END, "📎 No hay archivos adjuntos.\n") def actualizar_lista(self): self.tree.delete(*self.tree.get_children()) for correo in self.controlador.obtener_correos(): self.tree.insert("", "end", values=(correo["remitente"], correo["asunto"], correo["fecha"], correo["cuerpo"])) def ejecutar_hilo_actualizacion_barra(self): """ Inicia un hilo para actualizar el color de la barra inferior cada 5 segundos. """ hilo = threading.Thread(target=self.actualizar_barra_periodicamente, daemon=True) hilo.start() def actualizar_barra_periodicamente(self): """ Cambia el color de la barra inferior cada 5 segundos según si hay nuevos correos. """ while True: hay_nuevos = self.controlador.modelo.hay_mensajes_nuevos() # Cambiar color de la barra en el hilo principal de Tkinter self.root.after(0, self.cambiar_color_barra, "#FF0000" if hay_nuevos else "#1E90FF") time.sleep(2) # Esperar 5 segundos antes de verificar nuevamente def cambiar_color_barra(self, color): """ Cambia el color de la barra inferior. """ self.footer_frame.configure(bg=color) self.footer_label.configure(bg=color) def actualizar_footer(self, mensaje): """ Cambia el texto de la barra inferior """ self.footer_label.config(text=mensaje) def cambiar_credenciales(self): nuevo_usuario = self.entry_usuario.get().strip() nueva_contraseña = self.entry_contraseña.get().strip() if not nuevo_usuario or not nueva_contraseña: messagebox.showwarning("⚠️ Advertencia", "Usuario y contraseña no pueden estar vacíos.") return self.controlador.cambiar_credenciales(nuevo_usuario, nueva_contraseña) messagebox.showinfo("✅ Éxito", "Credenciales actualizadas correctamente.") def descargar_archivo_adjunto(self): seleccionado = self.tree.selection() if not seleccionado: messagebox.showwarning("⚠️ Advertencia", "Seleccione un correo para descargar el archivo adjunto.") return correo_id = seleccionado[0] correo = self.tree.item(correo_id, "values") correo_db = self.controlador.modelo.collection.find_one( {"remitente": correo[0], "asunto": correo[1], "fecha": correo[2]} ) if correo_db: self.controlador.descargar_archivo_adjunto(correo_db["_id"]) else: messagebox.showerror("❌ Error", "No se encontró el correo en la base de datos.")