diff --git a/src/services/__pycache__/processes_manager.cpython-312.pyc b/src/services/__pycache__/processes_manager.cpython-312.pyc new file mode 100644 index 0000000..7e006a2 Binary files /dev/null and b/src/services/__pycache__/processes_manager.cpython-312.pyc differ diff --git a/src/services/__pycache__/threads_manager.cpython-312.pyc b/src/services/__pycache__/threads_manager.cpython-312.pyc new file mode 100644 index 0000000..d7623ae Binary files /dev/null and b/src/services/__pycache__/threads_manager.cpython-312.pyc differ diff --git a/src/services/processes_manager.py b/src/services/processes_manager.py new file mode 100644 index 0000000..24cc16a --- /dev/null +++ b/src/services/processes_manager.py @@ -0,0 +1,28 @@ +import subprocess +import webbrowser + +class ProcessManager: + def open_resource(self, resource_type, path_or_url, fallback_message="Resource not found"): + """ + Método genérico para abrir programas, archivos o URLs. + + Args: + resource_type (str): Tipo de recurso ("program" para programas/archivos o "browser" para URLs). + path_or_url (str): Ruta del programa/archivo o URL a abrir. + fallback_message (str): Mensaje a mostrar en caso de error. Por defecto, "Resource not found". + """ + try: + if resource_type == "program": + subprocess.Popen([path_or_url]) # Abre un programa o archivo + elif resource_type == "browser": + webbrowser.get('chrome').open(path_or_url) # Intenta abrir con Chrome + else: + print("Unknown resource type") + except FileNotFoundError: + print(fallback_message) + except Exception as e: + if resource_type == "browser": + # Fallback al navegador por defecto si Chrome falla + webbrowser.open(path_or_url) + else: + print(f"Error: {e}") \ No newline at end of file diff --git a/src/services/threads_manager.py b/src/services/threads_manager.py new file mode 100644 index 0000000..e3dcaa1 --- /dev/null +++ b/src/services/threads_manager.py @@ -0,0 +1,62 @@ +import threading +import datetime +import time +import requests +import random + +class ThreadsManager: + def __init__(self, ui_instance): + self.ui_instance = ui_instance + + def start_threads(self): + # Hilo para actualizar el reloj + threading.Thread(target=self.update_time, daemon=True).start() + + # Hilo para actualizar la temperatura + threading.Thread(target=self.update_temperature, daemon=True).start() + + # Hilo para actualizar correos (simulado) + threading.Thread(target=self.update_emails, daemon=True).start() + + def update_time(self): + while True: + 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}")) + time.sleep(1) + + def update_temperature(self): + API_KEY = "4ba2b87d7fa32934530b5b4a5a83ebf7" # Reemplaza con tu clave de OpenWeatherMap + CITY = "Madrid" # Cambia por tu ciudad + while True: + try: + temperature = self.get_real_temperature(API_KEY, CITY) + if temperature is not None: + self.ui_instance.after( + 0, + 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}") + time.sleep(600) # Actualiza cada 10 minutos + + def get_real_temperature(self, api_key, city): + url = f"http://api.openweathermap.org/data/2.5/weather?q={city}&appid={api_key}&units=metric" + response = requests.get(url) + if response.status_code == 200: + data = response.json() + return data['main']['temp'] # Retorna la temperatura en °C + else: + print(f"Error al obtener la temperatura: {response.status_code}") + return None + + def update_emails(self): + count = 0 + while True: + count += random.randint(0, 2) # Simula la llegada de 0-2 correos + self.ui_instance.after( + 0, + lambda: self.ui_instance.info_labels["emails"].configure(text=f"Correos sin leer: {count}") + ) + time.sleep(10) # Actualiza cada 10 segundos diff --git a/src/ui/__pycache__/centered_window.cpython-312.pyc b/src/ui/__pycache__/centered_window.cpython-312.pyc index 2e12d8b..678a6b6 100644 Binary files a/src/ui/__pycache__/centered_window.cpython-312.pyc and b/src/ui/__pycache__/centered_window.cpython-312.pyc differ diff --git a/src/ui/centered_window.py b/src/ui/centered_window.py index f59afa7..53bec22 100644 --- a/src/ui/centered_window.py +++ b/src/ui/centered_window.py @@ -2,11 +2,10 @@ import customtkinter as ctk import webbrowser import subprocess import os -import threading -import random -import datetime -import time -import requests + +from services.threads_manager import ThreadsManager +from services.processes_manager import ProcessManager + class CenteredWindow(ctk.CTk): def __init__(self, title="MultiApp", width_percentage=0.8, height_percentage=0.8): @@ -16,6 +15,9 @@ class CenteredWindow(ctk.CTk): # Titulo de la ventana: self.title(title) + self.thread_manager = ThreadsManager(self) + self.process_manager = ProcessManager() + # Obtener la resolucion de la pantalla: screen_width = self.winfo_screenwidth() screen_height = self.winfo_screenheight() @@ -36,34 +38,11 @@ class CenteredWindow(ctk.CTk): def configure_window(self): # Configuracion de la ventana: self.configure(bg_color="lightgray") - - #Barra superior con Botones: - #self.create_menuBar() self.create_left_panel() self.create_right_panel() self.create_center_panel() self.create_bottom_bar() - self.start_threads() - - - def create_menuBar(self): - menu_bar = ctk.CTkFrame(self, height=25) - menu_bar.pack(side=ctk.TOP, fill=ctk.X) - - #Botones del menuBar: - # Agregar botones de menú - menus = ["Procesos", "T2.Threads", "T3.Sockets", "T4.Servicios", "T5.Seguridad", "Configuración"] - for menu in menus: - btn = ctk.CTkButton( - menu_bar, - text=menu, - command=lambda m=menu: self.on_menu_click(m), - width=100, - height=20, - fg_color="blue", - hover_color="lightblue" - ) - btn.pack(side=ctk.LEFT, padx=5, pady=5) + self.thread_manager.start_threads() def create_left_panel(self): # Panel izquierdo @@ -71,12 +50,12 @@ class CenteredWindow(ctk.CTk): left_panel.pack(side=ctk.LEFT, fill=ctk.Y, padx=10, pady=10) # Secciones y botones sections = { - "": [("Extraer datos", self.dummy_action), - ("Navegar", self.open_chrome), - ("Buscar API Google", self.dummy_action)], - "Aplicaciones": [("Visual Code", self.open_visual_studio_code), - ("Windows Explorer", self.open_explorer), ("Notepad++", self.open_notepad_plus)], - "Procesos batch": [("Copias de seguridad", self.dummy_action)], + "Aplicaciones": [ + ("Abrir Chrome", lambda: self.process_manager.open_resource("browser", "https://google.com", "Cannot open browser")), + ("Visual Studio Code", lambda: self.process_manager.open_resource("program", r"C:\Program Files\Microsoft VS Code\Code.exe", "Can't find VSCode")), + ("Explorador de Windows", lambda: self.process_manager.open_resource("program", "explorer.exe", "Can't open Windows Explorer")), + ("Notepad++", lambda: self.process_manager.open_resource("program", r"C:\Program Files\Notepad++\notepad++.exe", "Can't open Notepad++")) + ] } for section, buttons in sections.items(): @@ -88,7 +67,6 @@ class CenteredWindow(ctk.CTk): btn = ctk.CTkButton(left_panel, text=text, command=command, width=150) btn.pack(pady=5, padx=10) - def create_center_panel(self): # Panel central con pestañas center_panel = ctk.CTkFrame(self) @@ -106,8 +84,6 @@ class CenteredWindow(ctk.CTk): label = ctk.CTkLabel(tab_view.tab(tab), text=f"Contenido de {tab}", font=("Arial", 12)) label.pack(pady=10) - - def create_right_panel(self): # Panel derecho right_panel = ctk.CTkFrame(self, width=250) @@ -136,7 +112,6 @@ class CenteredWindow(ctk.CTk): ) student_info.pack(anchor=ctk.W, padx=10) - def create_bottom_bar(self): # Crear la barra inferior self.bottom_bar = ctk.CTkFrame(self, fg_color="lightblue", height=40) @@ -154,102 +129,5 @@ class CenteredWindow(ctk.CTk): for label in self.info_labels.values(): label.pack(side=ctk.LEFT, padx=10, pady=5) - - - def start_threads(self): - # Hilo para actualizar el reloj - threading.Thread(target=self.update_time, daemon=True).start() - - # Hilo para actualizar la temperatura - threading.Thread(target=self.update_temperature, daemon=True).start() - - # Hilo para actualizar correos (simulado) - threading.Thread(target=self.update_emails, daemon=True).start() - - def update_time(self): - # Obtén la hora y la fecha actual - current_time = datetime.datetime.now().strftime('%H:%M:%S') - current_date = datetime.datetime.now().strftime('%d/%m/%Y') - - # Actualiza las etiquetas en el hilo principal - self.info_labels["hora"].configure(text=f"Hora: {current_time}") - self.info_labels["fecha"].configure(text=f"Fecha: {current_date}") - - # Programa la próxima ejecución en 1000 ms (1 segundo) - self.after(1000, self.update_time) - - - - def update_temperature(self): - # Actualiza la temperatura real cada 10 minutos usando la API de OpenWeatherMap - API_KEY = "4ba2b87d7fa32934530b5b4a5a83ebf7" # Reemplaza con tu clave de OpenWeatherMap - CITY = "Madrid" # Cambia por tu ciudad - while True: - try: - temperature = self.get_real_temperature(API_KEY, CITY) - if temperature is not None: - self.info_labels["temperatura"].configure(text=f"Temperatura local: {temperature}°C") - except Exception as e: - print(f"Error al obtener la temperatura: {e}") - threading.Event().wait(600) # Actualiza cada 10 minutos - - def get_real_temperature(self, api_key, city): - # Función para obtener la temperatura real desde OpenWeatherMap - url = f"http://api.openweathermap.org/data/2.5/weather?q={city}&appid={api_key}&units=metric" - response = requests.get(url) - if response.status_code == 200: - data = response.json() - return data['main']['temp'] # Retorna la temperatura en °C - else: - print(f"Error al obtener la temperatura: {response.status_code}") - return None - - def update_emails(self): - # Simula la actualización de correos no leídos cada 10 segundos - count = 0 - while True: - count += random.randint(0, 2) # Simula la llegada de 0-2 correos - self.info_labels["emails"].configure(text=f"Correos sin leer: {count}") - self.after(1000, self.update_time) # Actualiza cada 10 segundos - threading.Event().wait(1) - def dummy_action(self): - print("Acción no implementada") - - - def open_chrome(self): - try: - webbrowser.get('chrome').open('https://google.es') - except: - webbrowser.open('https://google.es') - - - def open_visual_studio_code(self): - try: - vs_code_path = r"C:\Program Files\Microsoft VS Code\Code.exe" - subprocess.Popen([vs_code_path]) - except FileNotFoundError: - print ("Can't find VSCode") - - - def open_explorer(self): - try: - subprocess.Popen(['explorer.exe']) - except: - print("Can't open Windows Explorer") - - - def open_notepad_plus(self): - try: - notepad_path = r"C:\Program Files\Notepad++\notepad++.exe" - subprocess.Popen([notepad_path]) - except: - print("Can't open NotePad++") - - - - - - - - + print("Acción no implementada") \ No newline at end of file