Corregido error de acentos para los script del LAD a SCL

This commit is contained in:
Miguel 2025-05-03 15:31:44 +02:00
parent eacce5d8bd
commit 6d021b8211
8 changed files with 1801 additions and 7978 deletions

110
app.py
View File

@ -1,9 +1,18 @@
from flask import Flask, render_template, request, jsonify, url_for
from flask_sock import Sock
from config_manager import ConfigurationManager
from datetime import datetime
import os
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(
__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
websocket_connections = set()
# --- Globals for Tray Icon ---
tray_icon = None
@sock.route("/ws")
def handle_websocket(ws):
@ -227,5 +239,99 @@ def get_directory_history(group):
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__":
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

View File

@ -23,15 +23,8 @@ script_root = os.path.dirname(
sys.path.append(script_root)
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 = get_console_encoding()
CONSOLE_ENCODING = "utf-8"
# <-- NUEVO: Importar format_variable_name (necesario para predecir nombre de salida) -->
try:

File diff suppressed because it is too large Load Diff

BIN
icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

View File

@ -1,15 +1,16 @@
flask
flask-sock
lxml
pandas
google-cloud-translate
openai
ollama
langid
openpyxl
beautifulsoup4
requests
mammoth
html2text
pypandoc
# siemens-tia-scripting # Requiere instalación especial de TIA Portal Openness
beautifulsoup4==4.13.4
Flask==3.1.0
flask_sock==0.7.0
html2text==2025.4.15
langid==1.1.6
lxml==5.4.0
mammoth==1.9.0
ollama==0.4.8
openai==1.77.0
openpyxl==3.1.5
pandas==2.2.3
protobuf==6.30.2
pypandoc==1.15
Requests==2.32.3
siemens_tia_scripting==1.0.7
sympy==1.13.3

View File

@ -960,6 +960,81 @@ function collectFormData(level) {
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
async function saveConfig(level) {
const saveButton = document.getElementById(`save-config-${level}`);

View File

@ -68,6 +68,13 @@
</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>