Restructured classes and separated threads and processes

This commit is contained in:
Dennis Eckerskorn 2024-12-04 18:49:17 +01:00
parent ebbb42911a
commit 7221395724
6 changed files with 105 additions and 137 deletions

View File

@ -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}")

View File

@ -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

View File

@ -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++")