diff --git a/app/__pycache__/chat.cpython-313.pyc b/app/__pycache__/chat.cpython-313.pyc index 996199c..9414f75 100644 Binary files a/app/__pycache__/chat.cpython-313.pyc and b/app/__pycache__/chat.cpython-313.pyc differ diff --git a/app/__pycache__/emailClient.cpython-313.pyc b/app/__pycache__/emailClient.cpython-313.pyc new file mode 100644 index 0000000..7fba0fa Binary files /dev/null and b/app/__pycache__/emailClient.cpython-313.pyc differ diff --git a/app/__pycache__/emailTab.cpython-313.pyc b/app/__pycache__/emailTab.cpython-313.pyc new file mode 100644 index 0000000..3a44dad Binary files /dev/null and b/app/__pycache__/emailTab.cpython-313.pyc differ diff --git a/app/__pycache__/panel_derecho.cpython-313.pyc b/app/__pycache__/panel_derecho.cpython-313.pyc index 6729e64..86e2c71 100644 Binary files a/app/__pycache__/panel_derecho.cpython-313.pyc and b/app/__pycache__/panel_derecho.cpython-313.pyc differ diff --git a/app/__pycache__/panel_izquierdo.cpython-313.pyc b/app/__pycache__/panel_izquierdo.cpython-313.pyc index 9fb6d70..b9542a7 100644 Binary files a/app/__pycache__/panel_izquierdo.cpython-313.pyc and b/app/__pycache__/panel_izquierdo.cpython-313.pyc differ diff --git a/app/emailClient.py b/app/emailClient.py new file mode 100644 index 0000000..4b8a44c --- /dev/null +++ b/app/emailClient.py @@ -0,0 +1,59 @@ +# emailClient.py +import smtplib +import imaplib +import email +from email.mime.text import MIMEText +from email.mime.multipart import MIMEMultipart +import threading + +class EmailClient: + def __init__(self): + self.server_ip = "192.168.120.103" + self.ports = { + "SMTP": 25, + "SMTP-S": 465, + "SMTP-SUBMISSION": 587, + "IMAP": 143, + "IMAP-S": 993 + } + + def enviar_correo(self, email_user, password, destinatario, asunto, mensaje): + def enviar(): + try: + with smtplib.SMTP(self.server_ip, self.ports["SMTP"]) as smtp: + smtp.login(email_user, password) + msg = MIMEMultipart() + msg["From"] = email_user + msg["To"] = destinatario + msg["Subject"] = asunto + msg.attach(MIMEText(mensaje, "plain")) + smtp.sendmail(email_user, destinatario, msg.as_string()) + print("Correo enviado correctamente.") + except Exception as e: + print(f"Error al enviar el correo: {e}") + + thread = threading.Thread(target=enviar) + thread.start() + + def recibir_correos(self, email_user, password, text_widget): + def recibir(): + try: + with imaplib.IMAP4_SSL(self.server_ip, self.ports["IMAP-S"]) as mail: + mail.login(email_user, password) + mail.select("inbox") + status, mensajes_no_leidos = mail.search(None, 'UNSEEN') + no_leidos = mensajes_no_leidos[0].split() + + text_widget.delete("1.0", "end") + text_widget.insert("end", f"Tienes {len(no_leidos)} correos no leídos.\n") + + for num in no_leidos: + status, data = mail.fetch(num, '(RFC822)') + mensaje = email.message_from_bytes(data[0][1]) + text_widget.insert("end", f"[NO LEÍDO] {mensaje['Subject']}\n") + mail.store(num, '+FLAGS', '\\Seen') + except Exception as e: + text_widget.insert("end", f"Error al recibir correos: {e}\n") + + thread = threading.Thread(target=recibir) + thread.start() diff --git a/app/emailTab.py b/app/emailTab.py new file mode 100644 index 0000000..875fea7 --- /dev/null +++ b/app/emailTab.py @@ -0,0 +1,68 @@ +# emailTab.py +import tkinter as tk +from tkinter import ttk +from app.emailClient import EmailClient + +class EmailTab: + def __init__(self, notebook): + self.email_client = EmailClient() + self.tab = ttk.Frame(notebook) + notebook.add(self.tab, text="Correo") + self.setup_ui() + + def setup_ui(self): + # Campos de entrada para credenciales + tk.Label(self.tab, text="Correo electrónico:").grid(row=0, column=0, sticky="e", padx=5, pady=5) + self.entry_email = tk.Entry(self.tab) + self.entry_email.grid(row=0, column=1, padx=5, pady=5) + + tk.Label(self.tab, text="Contraseña:").grid(row=1, column=0, sticky="e", padx=5, pady=5) + self.entry_password = tk.Entry(self.tab, show="*") + self.entry_password.grid(row=1, column=1, padx=5, pady=5) + + # Campos de entrada para enviar correo + tk.Label(self.tab, text="Destinatario:").grid(row=2, column=0, sticky="e", padx=5, pady=5) + self.entry_destinatario = tk.Entry(self.tab) + self.entry_destinatario.grid(row=2, column=1, padx=5, pady=5) + + tk.Label(self.tab, text="Asunto:").grid(row=3, column=0, sticky="e", padx=5, pady=5) + self.entry_asunto = tk.Entry(self.tab) + self.entry_asunto.grid(row=3, column=1, padx=5, pady=5) + + tk.Label(self.tab, text="Mensaje:").grid(row=4, column=0, sticky="ne", padx=5, pady=5) + self.text_mensaje = tk.Text(self.tab, height=5, width=40) + self.text_mensaje.grid(row=4, column=1, padx=5, pady=5) + + # Botón para enviar correo + tk.Button( + self.tab, + text="Enviar Correo", + command=self.enviar_correo + ).grid(row=5, column=1, pady=10) + + # Área de texto para mostrar correos recibidos + self.text_correos = tk.Text(self.tab, height=10, width=60) + self.text_correos.grid(row=6, column=0, columnspan=2, padx=5, pady=5) + + # Botón para recibir correos + tk.Button( + self.tab, + text="Recibir Correos", + command=self.recibir_correos + ).grid(row=7, column=1, pady=10) + + def enviar_correo(self): + self.email_client.enviar_correo( + self.entry_email.get(), + self.entry_password.get(), + self.entry_destinatario.get(), + self.entry_asunto.get(), + self.text_mensaje.get("1.0", tk.END).strip() + ) + + def recibir_correos(self): + self.email_client.recibir_correos( + self.entry_email.get(), + self.entry_password.get(), + self.text_correos + ) diff --git a/app/panel_derecho.py b/app/panel_derecho.py index 03f13ec..92a076b 100644 --- a/app/panel_derecho.py +++ b/app/panel_derecho.py @@ -2,9 +2,9 @@ import tkinter as tk from tkinter import messagebox from app.chat import Chat import threading +import time import pygame # Para reproducir música - class PanelDerecho: def __init__(self, frame): # Inicializar el cliente de chat @@ -33,7 +33,7 @@ class PanelDerecho: self.entrada_mensaje = tk.Text(self.frame, height=5, bg="lightyellow", wrap="word") self.entrada_mensaje.grid(row=2, column=0, sticky="ew", padx=5, pady=5) - # Botón de enviar + # Botón de enviar boton_enviar = tk.Button(self.frame, text="Enviar", bg="lightgreen", command=self.enviar_mensaje) boton_enviar.grid(row=3, column=0, pady=5, padx=5, sticky="ew") @@ -58,9 +58,11 @@ class PanelDerecho: boton_restart = tk.Button(musica_frame, text="Restart", bg="blue", fg="white", command=self.reiniciar_musica_thread) boton_restart.pack(side="left", padx=5) - self.frame.rowconfigure(4, weight=1) + self.frame.rowconfigure(4, weight=1) + + # Iniciar actualización de mensajes + self.iniciar_actualizacion_mensajes() - # Métodos del chat def enviar_mensaje(self): """Enviar un mensaje al servidor.""" texto = self.entrada_mensaje.get("1.0", tk.END).strip() @@ -73,6 +75,25 @@ class PanelDerecho: else: messagebox.showwarning("Aviso", "El mensaje está vacío.") + def actualizar_lista_mensajes(self): + """Muestra los mensajes en la interfaz.""" + for widget in self.mensajes_frame.winfo_children(): + widget.destroy() + + for mensaje in self.chat_client.mensajes_recibidos: + mensaje_label = tk.Label(self.mensajes_frame, text=mensaje, anchor="w", justify="left", bg="white", wraplength=180) + mensaje_label.pack(fill="x", padx=5, pady=2) + + def iniciar_actualizacion_mensajes(self): + """Inicia un ciclo para actualizar los mensajes en la interfaz.""" + def ciclo(): + while True: + self.actualizar_lista_mensajes() + self.frame.update_idletasks() + time.sleep(0.5) + + threading.Thread(target=ciclo, daemon=True).start() + # Métodos para control de música def reproducir_musica_thread(self): diff --git a/app/panel_izquierdo.py b/app/panel_izquierdo.py index dc072e6..4f18d40 100644 --- a/app/panel_izquierdo.py +++ b/app/panel_izquierdo.py @@ -24,7 +24,7 @@ class PanelIzquierdo: self.weather_label = tk.Label(clima_frame, text="Cargando clima...", bg="white", font=("Helvetica", 10), fg="black") self.weather_label.pack(pady=5) - self.update_weather() + #self.update_weather() Comentado para que no gaste limite de requests en la api # Sección: Scrapping scraping_frame = tk.Frame(self.frame, bg="white", bd=2, relief="sunken") @@ -53,7 +53,7 @@ class PanelIzquierdo: noticias_frame, text="Cargando noticias...", bg="white", font=("Helvetica", 10), fg="black", wraplength=180, justify="left" ) self.news_label.pack(pady=5) - self.update_news() + #self.update_news() Comentado para que no gaste limite de requests en la api # Configuración para que las filas crezcan dinámicamente self.frame.rowconfigure(2, weight=1) diff --git a/main.py b/main.py index 439b739..7d1c09b 100644 --- a/main.py +++ b/main.py @@ -18,6 +18,7 @@ import matplotlib.pyplot as plt import random from app import graphics from app import todo_list +from app.emailTab import EmailTab def update_time(status_bar): while True: @@ -114,7 +115,7 @@ notebook = ttk.Notebook(frame_superior, style="CustomNotebook.TNotebook") notebook.pack(fill="both", expand=True) # Crear cinco solapas en el frame superior -for i in range(1, 6): +for i in range(1, 7): tab = ttk.Frame(notebook) if i == 1: notebook.add(tab, text="Scrapping", padding=4) @@ -134,13 +135,15 @@ for i in range(1, 6): elif i == 5: notebook.add(tab, text='To Do List', padding=4) todo_list.crear_solapa_todo(tab) + elif i == 6: + EmailTab(notebook) else: notebook.add(tab, text=f"Solapa {i}", padding=4) # Añadir un Label en cada solapa para diferenciarla label = ttk.Label(tab, text=f"Contenido de la Solapa {i}") label.pack(pady=10) - + # Notebook para las pestañas en el frame inferior notebook_inferior = ttk.Notebook(frame_inferior, style="CustomNotebook.TNotebook") notebook_inferior.pack(fill="both", expand=True)