From 9e52887ebbf285b3e968e9dd1d9f4ec784671b0d Mon Sep 17 00:00:00 2001 From: DennisEckerskorn Date: Wed, 15 Jan 2025 16:04:00 +0100 Subject: [PATCH] Tried some more to close conections --- .idea/MutiFunctionProgramProject.iml | 2 +- .idea/misc.xml | 2 +- .../email_client_pop.cpython-312.pyc | Bin 0 -> 12652 bytes .../threads_manager.cpython-312.pyc | Bin 11789 -> 12003 bytes src/services/email_client_pop.py | 32 +++++-- src/services/threads_manager.py | 85 +++++++++--------- .../centered_window.cpython-312.pyc | Bin 17888 -> 23181 bytes src/ui/centered_window.py | 45 ++++++---- 8 files changed, 96 insertions(+), 70 deletions(-) create mode 100644 src/services/__pycache__/email_client_pop.cpython-312.pyc diff --git a/.idea/MutiFunctionProgramProject.iml b/.idea/MutiFunctionProgramProject.iml index d8b3f6c..f571432 100644 --- a/.idea/MutiFunctionProgramProject.iml +++ b/.idea/MutiFunctionProgramProject.iml @@ -2,7 +2,7 @@ - + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 1d3ce46..153e9c5 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -3,5 +3,5 @@ - + \ No newline at end of file diff --git a/src/services/__pycache__/email_client_pop.cpython-312.pyc b/src/services/__pycache__/email_client_pop.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..61845b61dfc6f0903113c915695fe90d276812da GIT binary patch literal 12652 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 literal 0 HcmV?d00001 diff --git a/src/services/__pycache__/threads_manager.cpython-312.pyc b/src/services/__pycache__/threads_manager.cpython-312.pyc index 08978d390542bdd662c7579a01d57b2aecb065f2..78e9a4f4d8d59165ca23d8f501e14d3903fe7a12 100644 GIT binary patch delta 1818 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 diff --git a/src/services/email_client_pop.py b/src/services/email_client_pop.py index 11cc23d..3689b66 100644 --- a/src/services/email_client_pop.py +++ b/src/services/email_client_pop.py @@ -19,6 +19,7 @@ class EmailClientPOP: self.smtp_port = smtp_port self.pop_conn = None self.smtp_conn = None + self.running = True # Ruta del archivo SQLite: self.db_file = os.path.join("resources/db_email", "emails.db") @@ -59,7 +60,7 @@ class EmailClientPOP: def connect_pop(self): """Conexión al servidor POP""" try: - self.pop_conn = poplib.POP3(self.pop_server, self.pop_port) + self.pop_conn = poplib.POP3(self.pop_server, self.pop_port, timeout=10) self.pop_conn.user(self.email) self.pop_conn.pass_(self.password) print("Conexión POP exitosa") @@ -70,7 +71,7 @@ class EmailClientPOP: def connect_smtp(self): """Conexión al servidor SMTP""" try: - self.smtp_conn = smtplib.SMTP(self.smtp_server, self.smtp_port) + self.smtp_conn = smtplib.SMTP(self.smtp_server, self.smtp_port, timeout=10) self.smtp_conn.login(self.email, self.password) print("Conexión SMTP exitosa") except Exception as e: @@ -84,8 +85,12 @@ class EmailClientPOP: def reconnect(self): """Intenta reconectar a los servidores POP y SMTP""" print("Intentando reconectar al servidor de correo...") - self.connect_pop() - self.connect_smtp() + if not self.running: + return + if self.pop_conn is None: + self.connect_pop() + if self.smtp_conn is None: + self.connect_smtp() def fetch_unread_count(self): """Obtener el número de correos (POP3 no distingue entre leídos y no leídos)""" @@ -203,7 +208,18 @@ class EmailClientPOP: def close_connections(self): """Cierra las conexiones POP y SMTP""" - if self.pop_conn: - self.pop_conn.quit() - if self.smtp_conn: - self.smtp_conn.quit() + try: + if self.pop_conn: + self.pop_conn.quit() + self.pop_conn = None + print("Conexión POP cerrada.") + except Exception as e: + print(f"Error al cerrar conexión POP: {e}") + + try: + if self.smtp_conn: + self.smtp_conn.quit() + self.smtp_conn = None + print("Conexión SMTP cerrada.") + except Exception as e: + print(f"Error al cerrar conexión SMTP: {e}") diff --git a/src/services/threads_manager.py b/src/services/threads_manager.py index 77b5605..caae0a1 100644 --- a/src/services/threads_manager.py +++ b/src/services/threads_manager.py @@ -9,6 +9,7 @@ from src.services.threaden_task import ThreadenTask class ThreadsManager: """Constructor""" + def __init__(self, ui_instance, email_client): self.ui_instance = ui_instance self.email_client = email_client @@ -16,23 +17,23 @@ class ThreadsManager: self.radio_player = RadioPlayer() self.tasks = { "time": ThreadenTask(), - "temperature": ThreadenTask(), - "emails":ThreadenTask(), - "email_client":ThreadenTask(), - "tetris_game":ThreadenTask(), - "scrapper":ThreadenTask(), + "temperature": ThreadenTask(), + "emails": ThreadenTask(), + "email_client": ThreadenTask(), + "tetris_game": ThreadenTask(), + "scrapper": ThreadenTask(), "radio_player": ThreadenTask(), } self.system_monitor_tasks = {} self.scrapper = Scrapper(ui_instance) - - def play_radio(self, url): - """Inicia la reproducción de radio en un hilo.""" - if not self.tasks["radio_player"].running: - self.tasks["radio_player"].start(self.radio_player.play, url) - def stop_radio(self): - """Detiene la reproducción de radio.""" + def play_radio(self, url): + """Inicia la reproducción de radio en un hilo.""" + if not self.tasks["radio_player"].running: + self.tasks["radio_player"].start(self.radio_player.play, url) + + def stop_radio(self): + """Detiene la reproducción de radio.""" self.radio_player.stop() def set_system_monitor(self, system_monitor): @@ -58,13 +59,13 @@ class ThreadsManager: if hasattr(self.ui_instance, "tetris_game"): self.tasks["tetris_game"].start(self.update_tetris_game) - - def stop_threads(self): - """Recorre tasks y para los hilos""" + """Detiene todos los hilos y cierra las conexiones.""" for name, task in self.tasks.items(): task.stop() print(f"Hilo '{name}' detenido") + if name == "email_client" and hasattr(self.email_client, "close_connections"): + self.email_client.close_connections() for name, task in self.system_monitor_tasks.items(): task.stop() @@ -73,7 +74,6 @@ class ThreadsManager: if self.system_monitor: self.system_monitor.running = False - def update_tetris_game(self): """Ciclo de actualizacion del tetris game""" while self.tasks["tetris_game"].running: @@ -84,25 +84,24 @@ class ThreadsManager: except Exception as e: print(f"Error en update_tetris_game: {e}") break - - def update_system_metric(self, metric): - """Actualiza una métrica específica del monitor del sistema.""" - while self.system_monitor_tasks[metric].running: - try: - self.system_monitor.update_metric(metric) - time.sleep(self.system_monitor.metrics[metric]["interval"]) - except Exception as e: - print(f"Error updating metric {metric}: {e}") + def update_system_metric(self, metric): + """Actualiza una métrica específica del monitor del sistema.""" + while self.system_monitor_tasks[metric].running: + try: + self.system_monitor.update_metric(metric) + time.sleep(self.system_monitor.metrics[metric]["interval"]) + except Exception as e: + print(f"Error updating metric {metric}: {e}") - - def update_time(self): while self.tasks["time"].running: current_time = datetime.datetime.now().strftime('%H:%M:%S') current_date = datetime.datetime.now().strftime('%d/%m/%Y') - self.ui_instance.after(0, lambda: self.ui_instance.info_labels["hora"].configure(text=f"Hora: {current_time}")) - self.ui_instance.after(0, lambda: self.ui_instance.info_labels["fecha"].configure(text=f"Fecha: {current_date}")) + self.ui_instance.after(0, + lambda: self.ui_instance.info_labels["hora"].configure(text=f"Hora: {current_time}")) + self.ui_instance.after(0, lambda: self.ui_instance.info_labels["fecha"].configure( + text=f"Fecha: {current_date}")) time.sleep(1) def update_temperature(self): @@ -114,7 +113,8 @@ class ThreadsManager: if temperature is not None: self.ui_instance.after( 0, - lambda: self.ui_instance.info_labels["temperatura"].configure(text=f"Temperatura local: {temperature}°C") + lambda: self.ui_instance.info_labels["temperatura"].configure( + text=f"Temperatura local: {temperature}°C") ) except Exception as e: print(f"Error al obtener la temperatura: {e}") @@ -139,9 +139,12 @@ class ThreadsManager: except Exception as e: print(f"Error en el EmailClient: {e}") time.sleep(10) + finally: + self.email_client.close_connections() + print("Cliente de correo detenido y conexiones cerradas") def update_emails(self): - """Actualiza la cantidad de correos no leidos en tiempo real""" + """Actualiza la cantidad de correos no leídos en tiempo real.""" while self.tasks["emails"].running: try: if not self.email_client.is_connected(): @@ -149,24 +152,16 @@ class ThreadsManager: if self.email_client.is_connected(): unread_count = self.email_client.fetch_unread_count() - self.ui_instance.after( - 0, - lambda: self.ui_instance.info_labels["emails"].configure( - text=f"Correos sin leer: {unread_count}" + if self.ui_instance.winfo_exists(): # Verifica si la ventana aún existe + self.ui_instance.after( + 0, + lambda: self.ui_instance.info_labels["emails"].configure( + text=f"Correos sin leer: {unread_count}" + ) ) - ) else: print("No hay conexión al servidor de correo") - self.ui_instance.after( - 0, - lambda: self.ui_instance.info_labels["emails"].configure( - text="Servidor no disponible" - ) - ) except Exception as e: print(f"Error en el hilo de correos: {e}") time.sleep(60) - - - diff --git a/src/ui/__pycache__/centered_window.cpython-312.pyc b/src/ui/__pycache__/centered_window.cpython-312.pyc index 30dbfa13748cd2fc01bbc8bdd2ea1b618b157e41..5f3a0c86979fdf34abc66962629114dd094d8d24 100644 GIT binary patch delta 7581 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 diff --git a/src/ui/centered_window.py b/src/ui/centered_window.py index 555ff3d..6cde708 100644 --- a/src/ui/centered_window.py +++ b/src/ui/centered_window.py @@ -64,24 +64,37 @@ class CenteredWindow(ctk.CTk): def on_close(self): """Maneja el cierre de la ventana""" - self.thread_manager.stop_threads() + try: + # Establecer bandera de cierre para el cliente de correo + if hasattr(self, "email_client") and self.email_client: + self.email_client.running = False - if hasattr(self, "tetris_game") and self.tetris_game.running: - self.tetris_game.stop_game() + # Detener todos los hilos + self.thread_manager.stop_threads() - if "tetris_game" in self.thread_manager.tasks: - self.thread_manager.tasks["tetris_game"].stop() + # Cancelar tareas programadas en Tkinter + for task in self.after_tasks: + try: + self.after_cancel(task) + except Exception as e: + print(f"Error al cancelar tarea programada: {e}") - if hasattr(self.thread_manager, "scrapper"): - self.thread_manager.scrapper.stop_scraping() + # Cerrar conexiones del cliente POP/SMTP + if hasattr(self, "email_client") and self.email_client: + self.email_client.close_connections() - if self.system_monitor: - self.system_monitor.running = False + # Detener tareas adicionales (Tetris, scraping) + if hasattr(self, "tetris_game") and self.tetris_game.running: + self.tetris_game.stop_game() - for task in self.after_tasks: - self.after_cancel(task) + if hasattr(self.thread_manager, "scrapper") and self.thread_manager.scrapper: + self.thread_manager.scrapper.stop_scraping() - self.destroy() + # Destruir la ventana principal + self.destroy() + print("Aplicación cerrada correctamente.") + except Exception as e: + print(f"Error al cerrar la aplicación: {e}") def create_left_panel(self): # Panel izquierdo @@ -335,7 +348,7 @@ class CenteredWindow(ctk.CTk): listbox_frame.grid(row=0, column=0, sticky="nsew", padx=10, pady=10) # Crear una lista de correos con un scrollbar - self.email_listbox = ctk.CTkTextbox(listbox_frame, width=800, height=800) + self.email_listbox = ctk.CTkTextbox(listbox_frame, width=600, height=600) self.email_listbox.grid(row=0, column=0, sticky="nsew", padx=10, pady=10) self.email_listbox.configure(state="disabled") # Inicialmente deshabilitada @@ -375,9 +388,11 @@ class CenteredWindow(ctk.CTk): if self.email_client.is_connected(): emails = self.email_client.fetch_emails() - self.email_listbox.delete(0, tk.END) + self.email_listbox.configure(state="normal") + self.email_listbox.delete("1.0", tk.END) # Borra todo el contenido actual for email in emails: - self.email_listbox.insert(tk.END, f"{email['subject']} - {email['from']}") + self.email_listbox.insert(tk.END, f"De: {email['sender']}\nAsunto: {email['subject']}\n\n") + self.email_listbox.configure(state="disabled") else: print("No hay conexión al servidor de correo.") except Exception as e: