Corregido error de acentos para los script del LAD a SCL
This commit is contained in:
parent
eacce5d8bd
commit
6d021b8211
110
app.py
110
app.py
|
@ -1,9 +1,18 @@
|
||||||
from flask import Flask, render_template, request, jsonify, url_for
|
from flask import Flask, render_template, request, jsonify, url_for
|
||||||
from flask_sock import Sock
|
from flask_sock import Sock
|
||||||
from config_manager import ConfigurationManager
|
from config_manager import ConfigurationManager
|
||||||
from datetime import datetime
|
|
||||||
import os
|
import os
|
||||||
import json # Added import
|
import json # Added import
|
||||||
|
from datetime import datetime
|
||||||
|
import time # Added for shutdown delay
|
||||||
|
|
||||||
|
# --- Imports for System Tray Icon ---
|
||||||
|
import threading
|
||||||
|
import webbrowser
|
||||||
|
import sys
|
||||||
|
import requests # To send shutdown request
|
||||||
|
from PIL import Image
|
||||||
|
import pystray
|
||||||
|
|
||||||
app = Flask(
|
app = Flask(
|
||||||
__name__, static_url_path="", static_folder="static", template_folder="templates"
|
__name__, static_url_path="", static_folder="static", template_folder="templates"
|
||||||
|
@ -14,6 +23,9 @@ config_manager = ConfigurationManager()
|
||||||
# Lista global para mantener las conexiones WebSocket activas
|
# Lista global para mantener las conexiones WebSocket activas
|
||||||
websocket_connections = set()
|
websocket_connections = set()
|
||||||
|
|
||||||
|
# --- Globals for Tray Icon ---
|
||||||
|
tray_icon = None
|
||||||
|
|
||||||
|
|
||||||
@sock.route("/ws")
|
@sock.route("/ws")
|
||||||
def handle_websocket(ws):
|
def handle_websocket(ws):
|
||||||
|
@ -227,5 +239,99 @@ def get_directory_history(group):
|
||||||
return jsonify(history)
|
return jsonify(history)
|
||||||
|
|
||||||
|
|
||||||
|
# --- System Tray Icon Functions ---
|
||||||
|
|
||||||
|
def run_flask():
|
||||||
|
"""Runs the Flask app."""
|
||||||
|
print("Starting Flask server on http://127.0.0.1:5000/")
|
||||||
|
try:
|
||||||
|
# use_reloader=False is important when running in a thread
|
||||||
|
# For production, consider using waitress or gunicorn instead of app.run
|
||||||
|
app.run(host='127.0.0.1', port=5000, debug=True, use_reloader=False)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error running Flask app: {e}")
|
||||||
|
# Optionally try to stop the tray icon if Flask fails critically
|
||||||
|
if tray_icon:
|
||||||
|
print("Attempting to stop tray icon due to Flask error.")
|
||||||
|
tray_icon.stop()
|
||||||
|
|
||||||
|
def open_app_browser(icon, item):
|
||||||
|
"""Callback function to open the browser."""
|
||||||
|
print("Opening application in browser...")
|
||||||
|
webbrowser.open("http://127.0.0.1:5000/")
|
||||||
|
|
||||||
|
def shutdown_flask_server():
|
||||||
|
"""Attempts to gracefully shut down the Werkzeug server."""
|
||||||
|
try:
|
||||||
|
# This requires the development server (werkzeug)
|
||||||
|
# Send a request to a special shutdown route
|
||||||
|
requests.post("http://127.0.0.1:5000/_shutdown", timeout=1)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Could not send shutdown request to Flask server: {e}")
|
||||||
|
print("Flask server might need to be closed manually.")
|
||||||
|
|
||||||
|
def stop_icon_thread():
|
||||||
|
"""Helper function to stop the icon after a delay, allowing HTTP response."""
|
||||||
|
time.sleep(0.1) # Small delay to allow the HTTP response to be sent
|
||||||
|
if tray_icon:
|
||||||
|
print("Stopping tray icon from shutdown route...")
|
||||||
|
tray_icon.stop()
|
||||||
|
else:
|
||||||
|
print("Tray icon not available to stop.")
|
||||||
|
# As a last resort if the icon isn't running for some reason
|
||||||
|
# print("Attempting os._exit(0) as fallback.")
|
||||||
|
# os._exit(0) # Force exit - use with caution
|
||||||
|
|
||||||
|
@app.route('/_shutdown', methods=['POST'])
|
||||||
|
def shutdown_route():
|
||||||
|
"""Internal route to shut down the application via the tray icon."""
|
||||||
|
print("Shutdown endpoint called.")
|
||||||
|
# Stop the main application thread by stopping the tray icon.
|
||||||
|
# Do this in a separate thread to allow the HTTP response to return first.
|
||||||
|
stopper = threading.Thread(target=stop_icon_thread, daemon=True)
|
||||||
|
stopper.start()
|
||||||
|
print("Shutdown signal sent to tray icon thread.")
|
||||||
|
return jsonify(status="success", message="Application shutdown initiated..."), 200
|
||||||
|
|
||||||
|
def exit_application(icon, item):
|
||||||
|
"""Callback function to exit the application."""
|
||||||
|
print("Exit requested via tray menu.")
|
||||||
|
# Just stop the icon. This will end the main thread, and the daemon Flask thread will exit.
|
||||||
|
print("Stopping tray icon...")
|
||||||
|
if icon: # pystray passes the icon object
|
||||||
|
icon.stop()
|
||||||
|
elif tray_icon: # Fallback just in case
|
||||||
|
tray_icon.stop()
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
app.run(debug=True)
|
# --- Start Flask in a background thread ---
|
||||||
|
flask_thread = threading.Thread(target=run_flask, daemon=True)
|
||||||
|
flask_thread.start()
|
||||||
|
|
||||||
|
# --- Setup and run the system tray icon ---
|
||||||
|
icon_path = r"d:\Proyectos\Scripts\ParamManagerScripts\icon.png" # Use absolute path
|
||||||
|
try:
|
||||||
|
image = Image.open(icon_path)
|
||||||
|
menu = pystray.Menu(
|
||||||
|
pystray.MenuItem("Abrir ParamManager", open_app_browser, default=True),
|
||||||
|
pystray.MenuItem("Salir", exit_application)
|
||||||
|
)
|
||||||
|
tray_icon = pystray.Icon("ParamManager", image, "ParamManager", menu)
|
||||||
|
print("Starting system tray icon...")
|
||||||
|
tray_icon.run() # This blocks the main thread until icon.stop() is called
|
||||||
|
except FileNotFoundError:
|
||||||
|
print(f"Error: Icono no encontrado en '{icon_path}'. El icono de notificación no se iniciará.", file=sys.stderr)
|
||||||
|
print("La aplicación Flask seguirá ejecutándose en segundo plano. Presiona Ctrl+C para detenerla si es necesario.")
|
||||||
|
# Keep the main thread alive so the Flask thread doesn't exit immediately
|
||||||
|
# This allows Flask to continue running even without the tray icon.
|
||||||
|
try:
|
||||||
|
while flask_thread.is_alive():
|
||||||
|
flask_thread.join(timeout=1.0) # Wait indefinitely
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print("\nCtrl+C detectado. Intentando detener Flask...")
|
||||||
|
shutdown_flask_server() # Try to shutdown Flask on Ctrl+C too
|
||||||
|
print("Saliendo.")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error al iniciar el icono de notificación: {e}", file=sys.stderr)
|
||||||
|
|
||||||
|
print("Aplicación finalizada.")
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -23,15 +23,8 @@ script_root = os.path.dirname(
|
||||||
sys.path.append(script_root)
|
sys.path.append(script_root)
|
||||||
from backend.script_utils import load_configuration
|
from backend.script_utils import load_configuration
|
||||||
|
|
||||||
# --- Funciones (get_console_encoding - sin cambios) ---
|
|
||||||
def get_console_encoding():
|
|
||||||
try:
|
|
||||||
return locale.getpreferredencoding(False)
|
|
||||||
except Exception:
|
|
||||||
return "cp1252"
|
|
||||||
|
|
||||||
|
CONSOLE_ENCODING = "utf-8"
|
||||||
CONSOLE_ENCODING = get_console_encoding()
|
|
||||||
|
|
||||||
# <-- NUEVO: Importar format_variable_name (necesario para predecir nombre de salida) -->
|
# <-- NUEVO: Importar format_variable_name (necesario para predecir nombre de salida) -->
|
||||||
try:
|
try:
|
||||||
|
|
4580
data/log.txt
4580
data/log.txt
File diff suppressed because it is too large
Load Diff
|
@ -1,15 +1,16 @@
|
||||||
flask
|
beautifulsoup4==4.13.4
|
||||||
flask-sock
|
Flask==3.1.0
|
||||||
lxml
|
flask_sock==0.7.0
|
||||||
pandas
|
html2text==2025.4.15
|
||||||
google-cloud-translate
|
langid==1.1.6
|
||||||
openai
|
lxml==5.4.0
|
||||||
ollama
|
mammoth==1.9.0
|
||||||
langid
|
ollama==0.4.8
|
||||||
openpyxl
|
openai==1.77.0
|
||||||
beautifulsoup4
|
openpyxl==3.1.5
|
||||||
requests
|
pandas==2.2.3
|
||||||
mammoth
|
protobuf==6.30.2
|
||||||
html2text
|
pypandoc==1.15
|
||||||
pypandoc
|
Requests==2.32.3
|
||||||
# siemens-tia-scripting # Requiere instalación especial de TIA Portal Openness
|
siemens_tia_scripting==1.0.7
|
||||||
|
sympy==1.13.3
|
||||||
|
|
|
@ -960,6 +960,81 @@ function collectFormData(level) {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Añade esta función al final de tu archivo static/js/script.js
|
||||||
|
|
||||||
|
function shutdownServer() {
|
||||||
|
if (confirm("¿Estás seguro de que quieres detener el servidor? La aplicación se cerrará.")) {
|
||||||
|
fetch('/_shutdown', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
if (data.status === 'success') {
|
||||||
|
alert("El servidor se está deteniendo. Puede que necesites cerrar esta pestaña manualmente.");
|
||||||
|
// Opcionalmente, puedes intentar cerrar la ventana/pestaña
|
||||||
|
// window.close(); // Esto puede no funcionar en todos los navegadores por seguridad
|
||||||
|
document.body.innerHTML = '<div class="alert alert-info">El servidor se ha detenido. Cierra esta ventana.</div>';
|
||||||
|
} else {
|
||||||
|
alert("Error al intentar detener el servidor: " + data.message);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
// Es normal recibir un error de red aquí porque el servidor se está apagando
|
||||||
|
console.warn("Error esperado al detener el servidor (puede que ya se haya detenido):", error);
|
||||||
|
alert("Solicitud de detención enviada. El servidor debería detenerse. Cierra esta ventana.");
|
||||||
|
document.body.innerHTML = '<div class="alert alert-info">El servidor se está deteniendo. Cierra esta ventana.</div>';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Asegúrate de que las funciones fetchLogs y clearLogs también estén definidas en este archivo si las usas.
|
||||||
|
// Ejemplo de fetchLogs y clearLogs (si no las tienes ya):
|
||||||
|
|
||||||
|
function fetchLogs() {
|
||||||
|
fetch('/api/logs')
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
const logOutput = document.getElementById('log-output');
|
||||||
|
logOutput.textContent = data.logs || 'No hay logs.';
|
||||||
|
logOutput.scrollTop = logOutput.scrollHeight; // Scroll to bottom
|
||||||
|
})
|
||||||
|
.catch(error => console.error('Error fetching logs:', error));
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearLogs() {
|
||||||
|
if (confirm("¿Estás seguro de que quieres borrar los logs?")) {
|
||||||
|
fetch('/api/logs', { method: 'DELETE' })
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
if (data.status === 'success') {
|
||||||
|
fetchLogs(); // Refresh logs after clearing
|
||||||
|
showToast('Logs borrados correctamente.');
|
||||||
|
} else {
|
||||||
|
showToast('Error al borrar los logs.', 'error');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('Error clearing logs:', error);
|
||||||
|
showToast('Error de red al borrar los logs.', 'error');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Necesitarás una función showToast o similar si la usas
|
||||||
|
function showToast(message, type = 'success') {
|
||||||
|
// Implementa tu lógica de Toast aquí
|
||||||
|
console.log(`Toast (${type}): ${message}`);
|
||||||
|
alert(`Toast (${type}): ${message}`); // Simple alert como placeholder
|
||||||
|
}
|
||||||
|
|
||||||
|
// Llama a fetchLogs al cargar la página si es necesario
|
||||||
|
// document.addEventListener('DOMContentLoaded', fetchLogs);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Agregar función para guardar configuración
|
// Agregar función para guardar configuración
|
||||||
async function saveConfig(level) {
|
async function saveConfig(level) {
|
||||||
const saveButton = document.getElementById(`save-config-${level}`);
|
const saveButton = document.getElementById(`save-config-${level}`);
|
||||||
|
|
|
@ -68,6 +68,13 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Botón para detener el servidor -->
|
||||||
|
<div class="mt-8 pt-4 border-t border-gray-300">
|
||||||
|
<button class="w-full bg-red-600 hover:bg-red-700 text-white px-4 py-2 rounded shadow" onclick="shutdownServer()">
|
||||||
|
Detener Servidor
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue