112 lines
3.7 KiB
Python
112 lines
3.7 KiB
Python
"""Tab de logs y soporte."""
|
|
|
|
import subprocess
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
from PySide6.QtWidgets import (
|
|
QWidget, QVBoxLayout, QHBoxLayout, QPushButton,
|
|
QTextEdit, QComboBox, QLabel, QMessageBox
|
|
)
|
|
|
|
from ..db.event_repository import EventRepository
|
|
from ..constants import LOGS_DIR, LogLevel
|
|
|
|
|
|
class LogsTab(QWidget):
|
|
"""Tab de visualización de logs y soporte."""
|
|
|
|
def __init__(self, engine):
|
|
"""Inicializa el tab."""
|
|
super().__init__()
|
|
self.engine = engine
|
|
self._setup_ui()
|
|
self.refresh_logs()
|
|
|
|
def _setup_ui(self):
|
|
"""Configura la interfaz."""
|
|
layout = QVBoxLayout(self)
|
|
|
|
# Controles
|
|
controls_layout = QHBoxLayout()
|
|
|
|
controls_layout.addWidget(QLabel("Nivel:"))
|
|
|
|
self.level_filter = QComboBox()
|
|
self.level_filter.addItems([
|
|
"Todos",
|
|
LogLevel.DEBUG,
|
|
LogLevel.INFO,
|
|
LogLevel.WARNING,
|
|
LogLevel.ERROR,
|
|
LogLevel.CRITICAL
|
|
])
|
|
self.level_filter.setCurrentText(LogLevel.INFO)
|
|
self.level_filter.currentTextChanged.connect(self.refresh_logs)
|
|
controls_layout.addWidget(self.level_filter)
|
|
|
|
refresh_btn = QPushButton("🔄 Actualizar")
|
|
refresh_btn.clicked.connect(self.refresh_logs)
|
|
controls_layout.addWidget(refresh_btn)
|
|
|
|
controls_layout.addStretch()
|
|
|
|
open_folder_btn = QPushButton("📁 Abrir Carpeta Logs")
|
|
open_folder_btn.clicked.connect(self._open_logs_folder)
|
|
controls_layout.addWidget(open_folder_btn)
|
|
|
|
layout.addLayout(controls_layout)
|
|
|
|
# Área de logs
|
|
self.logs_text = QTextEdit()
|
|
self.logs_text.setReadOnly(True)
|
|
self.logs_text.setLineWrapMode(QTextEdit.LineWrapMode.NoWrap)
|
|
layout.addWidget(self.logs_text)
|
|
|
|
# Info
|
|
info_layout = QHBoxLayout()
|
|
info_label = QLabel("💡 Los logs se rotan automáticamente cada 10MB.")
|
|
info_layout.addWidget(info_label)
|
|
info_layout.addStretch()
|
|
|
|
layout.addLayout(info_layout)
|
|
|
|
def refresh_logs(self):
|
|
"""Refresca los logs desde la base de datos."""
|
|
level = self.level_filter.currentText()
|
|
|
|
if level == "Todos":
|
|
events = EventRepository.get_all(limit=200)
|
|
else:
|
|
events = EventRepository.get_all(level=level, limit=200)
|
|
|
|
# Formatear logs
|
|
log_lines = []
|
|
for event in reversed(events): # Mostrar más recientes primero
|
|
timestamp = event.created_at.replace("T", " ").split(".")[0]
|
|
job_info = f" [Job: {event.job_id[:8]}]" if event.job_id else ""
|
|
log_lines.append(
|
|
f"{timestamp} | {event.level:8s}{job_info} | {event.message}"
|
|
)
|
|
|
|
self.logs_text.setPlainText("\n".join(log_lines))
|
|
|
|
def _open_logs_folder(self):
|
|
"""Abre la carpeta de logs en el explorador de archivos del sistema."""
|
|
try:
|
|
if LOGS_DIR.exists():
|
|
if sys.platform == "win32":
|
|
subprocess.run(["explorer", str(LOGS_DIR)])
|
|
elif sys.platform == "darwin":
|
|
subprocess.run(["open", str(LOGS_DIR)])
|
|
else:
|
|
subprocess.run(["xdg-open", str(LOGS_DIR)])
|
|
else:
|
|
QMessageBox.warning(
|
|
self,
|
|
"Carpeta No Existe",
|
|
f"La carpeta de logs no existe:\n{LOGS_DIR}"
|
|
)
|
|
except Exception as e:
|
|
QMessageBox.critical(self, "Error", f"Error abriendo carpeta: {e}")
|