import subprocess import sys import os import json from datetime import datetime # -------------------------------------------------- # 🔧 Auto-install Flask if missing # -------------------------------------------------- def install_if_missing(package): try: __import__(package) except ImportError: print(f"⚡ Installing missing package: {package}") subprocess.check_call([sys.executable, "-m", "pip", "install", package]) install_if_missing("flask") # -------------------------------------------------- # 📦 Imports # -------------------------------------------------- from flask import Flask, render_template, request, jsonify, send_from_directory # -------------------------------------------------- # ⚙️ CONFIGURATION GLOBALE # -------------------------------------------------- PORT = int(os.environ.get("PORT", 7860)) BASE_DIR = os.path.dirname(os.path.abspath(__file__)) CROSS_READING_DIR = os.path.join(BASE_DIR, "cross_reading") TEMPLATES_DIR = os.path.join(BASE_DIR, "templates") STATIC_DIR = os.path.join(BASE_DIR, "static") DATA_DIR = os.path.join(BASE_DIR, "data") SCENARIOS_FILE = os.path.join(CROSS_READING_DIR, "scenarios.json") STATS_FILE = os.path.join(CROSS_READING_DIR, "trust_stats.json") REVIEW_FILE = os.path.join(CROSS_READING_DIR, "review.json") CROSS_HTML = "cross_readers.html" CROSS_JS = "cross_readers.js" app = Flask( __name__, template_folder=TEMPLATES_DIR, static_folder=STATIC_DIR ) # -------------------------------------------------- # 🌐 ROUTES UI # -------------------------------------------------- @app.route("/") def index(): return render_template("index.html") @app.route("/cross_readers.html") @app.route("/cross_reading/cross_readers.html") def cross_readers(): """Page Cross Reading""" if os.path.exists(os.path.join(CROSS_READING_DIR, CROSS_HTML)): return send_from_directory(CROSS_READING_DIR, CROSS_HTML) return "cross_readers.html introuvable", 404 @app.route("/cross_reading/cross_readers.js") def cross_readers_js(): return send_from_directory(CROSS_READING_DIR, CROSS_JS) # -------------------------------------------------- # 💾 API – TRUST (quantitatif) # -------------------------------------------------- @app.route("/save_trust", methods=["POST"]) def save_trust(): data = request.json record = { "scenario_id": data.get("scenario_id"), "trust_metrics": data.get("trust_metrics", {}), "trust_score": data.get("trust_score"), "comment": data.get("comment"), "timestamp": datetime.now().isoformat() } with open(STATS_FILE, "r+", encoding="utf-8") as f: content = json.load(f) content["evaluations"].append(record) f.seek(0) json.dump(content, f, indent=2, ensure_ascii=False) return jsonify({"status": "ok"}) @app.route("/api/evaluations") def get_evaluations(): with open(STATS_FILE, "r", encoding="utf-8") as f: data = json.load(f) # Normalisation métriques for e in data.get("evaluations", []): if "trust_metrics" in e: m = {} for k, v in e["trust_metrics"].items(): mapping = { "RA": "AR", "EA": "AE", "RE": "ESR", "MCS": "SDM", "MS": "SM" } m[mapping.get(k, k)] = v e["trust_metrics"] = m return jsonify(data) # -------------------------------------------------- # 📘 API – SCÉNARIOS # -------------------------------------------------- @app.route("/api/scenarios") def get_scenarios(): with open(SCENARIOS_FILE, "r", encoding="utf-8") as f: return jsonify(json.load(f)) # -------------------------------------------------- # 📝 API – REVIEWS (qualitatif) # -------------------------------------------------- @app.route("/api/reviews") def get_reviews(): with open(REVIEW_FILE, "r", encoding="utf-8") as f: return jsonify(json.load(f)) @app.route("/save_review", methods=["POST"]) def save_review(): data = request.json review = { "scenario_id": data.get("scenario_id"), "reader": data.get("reader"), "review": data.get("review"), "timestamp": datetime.now().isoformat() } with open(REVIEW_FILE, "r+", encoding="utf-8") as f: content = json.load(f) content["reviews"].append(review) f.seek(0) json.dump(content, f, indent=2, ensure_ascii=False) return jsonify({"status": "ok"}) # -------------------------------------------------- # 📂 ROUTES FICHIERS STATIQUES # -------------------------------------------------- @app.route("/cross_reading/") def serve_cross_reading(filename): return send_from_directory(CROSS_READING_DIR, filename) # -------------------------------------------------- # 🚀 MAIN # -------------------------------------------------- if __name__ == "__main__": print(f"🚀 Application : http://0.0.0.0:{PORT}") print(f"📈 Cross Reading : http://0.0.0.0:{PORT}/cross_readers.html") # Création dossiers for folder in [CROSS_READING_DIR, TEMPLATES_DIR, STATIC_DIR, DATA_DIR]: os.makedirs(folder, exist_ok=True) # Initialisation fichiers defaults = { SCENARIOS_FILE: {"scenarios": []}, STATS_FILE: {"evaluations": []}, REVIEW_FILE: {"reviews": []} } for path, content in defaults.items(): if not os.path.exists(path): with open(path, "w", encoding="utf-8") as f: json.dump(content, f, indent=2, ensure_ascii=False) print(f"📄 Créé : {path}") app.run( host="0.0.0.0", port=PORT, debug=True, use_reloader=False )