From edd0b14f6c89fcd3beb0ec944673c714cc46248d Mon Sep 17 00:00:00 2001 From: Floke Date: Mon, 18 Aug 2025 08:28:26 +0000 Subject: [PATCH] app.py aktualisiert --- app.py | 87 +++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 68 insertions(+), 19 deletions(-) diff --git a/app.py b/app.py index 01b6e19d..130b4173 100644 --- a/app.py +++ b/app.py @@ -1,20 +1,29 @@ -# app.py (Version mit pyngrok) -from flask import Flask, jsonify, request +# app.py (v2.0 - Autark & Transparent) + +from flask import Flask, jsonify, request, render_template_string import subprocess import sys import os import logging +import uuid +import json +from datetime import datetime from pyngrok import ngrok, conf from config import Config +# --- Konfiguration --- logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') 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 = { "run_duplicate_check": {"script": "duplicate_checker.py", "args": []}, - "run_reclassify_branches": {"script": "brancheneinstufung2.py", "args": ["--mode", "reclassify_branches"]}, - "run_predict_technicians": {"script": "brancheneinstufung2.py", "args": ["--mode", "predict_technicians"]}, + "run_reclassify_branches": {"script": "brancheneinstufung.py", "args": ["--mode", "reclassify_branches"]}, + "run_predict_technicians": {"script": "brancheneinstufung.py", "args": ["--mode", "predict_technicians"]}, } def setup_ngrok(): @@ -30,30 +39,70 @@ def setup_ngrok(): return None conf.get_default().auth_token = authtoken - # Starte den Tunnel zum Port, auf dem Flask laufen wird (8080) public_url = ngrok.connect(8080, "http") 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 except Exception as e: logging.error(f"Fehler beim Starten von ngrok: {e}") - # Beende das Programm, wenn ngrok nicht starten kann sys.exit(1) @app.route('/run-script', methods=['POST']) def run_script(): - # ... (Ihre run_script Logik bleibt unverändert) ... - data = request.get_json() - action = data.get('action') - if not action or action not in SCRIPT_MAP: - return jsonify({"status": "error", "message": "Ungültige Aktion."}), 400 - script_config = SCRIPT_MAP[action] - command = [sys.executable, script_config["script"]] + script_config["args"] - subprocess.Popen(command) - return jsonify({"status": "success", "message": f"Aktion '{action}' gestartet."}), 200 + """Startet ein Skript als Hintergrundprozess und verfolgt es über eine Job-ID.""" + try: + data = request.get_json() + action = data.get('action') + + if not action or action not in SCRIPT_MAP: + return jsonify({"status": "error", "message": "Ungültige Aktion."}), 400 + + script_config = SCRIPT_MAP[action] + script_name = script_config["script"] + + # 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__': - # Starte zuerst ngrok setup_ngrok() - # Starte dann den Flask-Server app.run(host='0.0.0.0', port=8080) \ No newline at end of file