#!/usr/bin/env python3 """Minimal HTTP server for digital-psychology — serves static files + mindmap persistence.""" import json, os, sys from http.server import HTTPServer, SimpleHTTPRequestHandler ROOT = os.path.dirname(os.path.abspath(__file__)) MINDMAP_FILE = os.path.join(ROOT, "mindmap_data.json") class Handler(SimpleHTTPRequestHandler): def __init__(self, *args, **kwargs): super().__init__(*args, directory=ROOT, **kwargs) def end_headers(self): # no-cache for HTML and JSON endpoints if self.path == '/' or self.path.endswith('.html') or self.path == '/load': self.send_header("Cache-Control", "no-cache, no-store, must-revalidate") self.send_header("Pragma", "no-cache") self.send_header("Expires", "0") super().end_headers() def do_GET(self): if self.path == "/load": if os.path.exists(MINDMAP_FILE): with open(MINDMAP_FILE, "r", encoding="utf-8") as f: data = f.read() self.send_response(200) self.send_header("Content-Type", "application/json") self.end_headers() self.wfile.write(data.encode()) else: self.send_response(200) self.send_header("Content-Type", "application/json") self.end_headers() self.wfile.write(b"{}") else: super().do_GET() def do_POST(self): if self.path == "/save": length = int(self.headers.get("Content-Length", 0)) data = self.rfile.read(length) try: json.loads(data) except json.JSONDecodeError: self.send_error(400, "Invalid JSON") return with open(MINDMAP_FILE, "w", encoding="utf-8") as f: f.write(data.decode()) self.send_response(200) self.send_header("Content-Type", "application/json") self.end_headers() self.wfile.write(b'{"ok":true}') elif self.path == "/load": if os.path.exists(MINDMAP_FILE): with open(MINDMAP_FILE, "r", encoding="utf-8") as f: data = f.read() self.send_response(200) self.send_header("Content-Type", "application/json") self.end_headers() self.wfile.write(data.encode()) else: self.send_response(200) self.send_header("Content-Type", "application/json") self.end_headers() self.wfile.write(b"{}") else: self.send_error(404) def log_message(self, format, *args): if "/save" in str(args) or "/load" in str(args): print(f"[{self.log_date_time_string()}] {args[0]}") if __name__ == "__main__": port = int(sys.argv[1]) if len(sys.argv) > 1 else 8001 server = HTTPServer(("127.0.0.1", port), Handler) server.socket.settimeout(30) # 30s timeout so hung clients don't block the single-thread server print(f"Serving {ROOT} on port {port} (save/load enabled)") try: server.serve_forever() except KeyboardInterrupt: server.shutdown()