app.py aktualisiert

This commit is contained in:
2025-08-18 08:28:26 +00:00
parent 00f3dde9e0
commit ae78da320a

77
app.py
View File

@@ -1,20 +1,29 @@
# app.py (Version mit pyngrok) # app.py (v2.0 - Autark & Transparent)
from flask import Flask, jsonify, request
from flask import Flask, jsonify, request, render_template_string
import subprocess import subprocess
import sys import sys
import os import os
import logging import logging
import uuid
import json
from datetime import datetime
from pyngrok import ngrok, conf from pyngrok import ngrok, conf
from config import Config from config import Config
# --- Konfiguration ---
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
app = Flask(__name__) app = Flask(__name__)
# SCRIPT MAP bleibt unverändert # Verzeichnis für Statusdateien der laufenden Jobs
STATUS_DIR = "job_status"
os.makedirs(STATUS_DIR, exist_ok=True)
# SCRIPT MAP (Passen Sie hier bei Bedarf die Skriptnamen an, z.B. auf brancheneinstufung2.py)
SCRIPT_MAP = { SCRIPT_MAP = {
"run_duplicate_check": {"script": "duplicate_checker.py", "args": []}, "run_duplicate_check": {"script": "duplicate_checker.py", "args": []},
"run_reclassify_branches": {"script": "brancheneinstufung2.py", "args": ["--mode", "reclassify_branches"]}, "run_reclassify_branches": {"script": "brancheneinstufung.py", "args": ["--mode", "reclassify_branches"]},
"run_predict_technicians": {"script": "brancheneinstufung2.py", "args": ["--mode", "predict_technicians"]}, "run_predict_technicians": {"script": "brancheneinstufung.py", "args": ["--mode", "predict_technicians"]},
} }
def setup_ngrok(): def setup_ngrok():
@@ -30,30 +39,70 @@ def setup_ngrok():
return None return None
conf.get_default().auth_token = authtoken conf.get_default().auth_token = authtoken
# Starte den Tunnel zum Port, auf dem Flask laufen wird (8080)
public_url = ngrok.connect(8080, "http") public_url = ngrok.connect(8080, "http")
logging.info(f"!!! Ngrok-Tunnel gestartet: {public_url} !!!") logging.info(f"!!! Ngrok-Tunnel gestartet: {public_url} !!!")
logging.info("!!! Bitte diese URL im Google Apps Script eintragen (falls sie sich geändert hat). !!!") logging.info("!!! Bitte diese URL im Google Apps Script eintragen. !!!")
return public_url return public_url
except Exception as e: except Exception as e:
logging.error(f"Fehler beim Starten von ngrok: {e}") logging.error(f"Fehler beim Starten von ngrok: {e}")
# Beende das Programm, wenn ngrok nicht starten kann
sys.exit(1) sys.exit(1)
@app.route('/run-script', methods=['POST']) @app.route('/run-script', methods=['POST'])
def run_script(): def run_script():
# ... (Ihre run_script Logik bleibt unverändert) ... """Startet ein Skript als Hintergrundprozess und verfolgt es über eine Job-ID."""
try:
data = request.get_json() data = request.get_json()
action = data.get('action') action = data.get('action')
if not action or action not in SCRIPT_MAP: if not action or action not in SCRIPT_MAP:
return jsonify({"status": "error", "message": "Ungültige Aktion."}), 400 return jsonify({"status": "error", "message": "Ungültige Aktion."}), 400
script_config = SCRIPT_MAP[action] script_config = SCRIPT_MAP[action]
command = [sys.executable, script_config["script"]] + script_config["args"] script_name = script_config["script"]
subprocess.Popen(command)
return jsonify({"status": "success", "message": f"Aktion '{action}' gestartet."}), 200 # NEU: Job-ID generieren und als Argument übergeben
job_id = str(uuid.uuid4())
command = [sys.executable, script_name] + script_config["args"] + ["--job-id", job_id]
# ENTSCHEIDENDER FIX: Setze das Arbeitsverzeichnis explizit
script_dir = os.path.dirname(os.path.abspath(__file__))
logging.info(f"Starte Job {job_id} für Aktion '{action}' im Verzeichnis '{script_dir}'...")
subprocess.Popen(command, cwd=script_dir)
# Erstelle eine initiale Statusdatei
status_file = os.path.join(STATUS_DIR, f"{job_id}.json")
with open(status_file, 'w') as f:
json.dump({
"action": action,
"status": "Gestartet",
"start_time": datetime.now().isoformat(),
"progress": "Prozess wird initialisiert..."
}, f)
return jsonify({"status": "success", "message": f"Aktion '{action}' mit Job-ID {job_id} gestartet."}), 200
except Exception as e:
logging.error(f"Fehler in run_script: {e}")
return jsonify({"status": "error", "message": str(e)}), 500
@app.route('/get-status', methods=['GET'])
def get_status():
"""Liest alle Job-Status-Dateien und gibt den aktuellen Stand zurück."""
all_statuses = []
for filename in os.listdir(STATUS_DIR):
if filename.endswith(".json"):
try:
with open(os.path.join(STATUS_DIR, filename), 'r') as f:
status_data = json.load(f)
status_data['job_id'] = filename.replace('.json', '')
all_statuses.append(status_data)
except Exception as e:
logging.warning(f"Konnte Statusdatei {filename} nicht lesen: {e}")
# Sortiere nach Startzeit, neuester Job zuerst
all_statuses.sort(key=lambda x: x.get('start_time', ''), reverse=True)
return jsonify(all_statuses)
if __name__ == '__main__': if __name__ == '__main__':
# Starte zuerst ngrok
setup_ngrok() setup_ngrok()
# Starte dann den Flask-Server
app.run(host='0.0.0.0', port=8080) app.run(host='0.0.0.0', port=8080)