#!/usr/bin/env python3 """ Minimaler Entwicklungs-Server für die Prompt Templates Webansicht. Startet auf Port 8080 und dient die statischen Dateien aus. """ import http.server import socketserver import os import socket import json DIRECTORY = os.path.dirname(os.path.abspath(__file__)) ROOT_DIR = os.path.abspath(os.path.join(DIRECTORY, '..')) def find_free_port(start_port=9000): """Finde einen freien Port ab start_port""" port = start_port while port < 10000: try: with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.bind(('', port)) return port except OSError: port += 1 return None class Handler(http.server.SimpleHTTPRequestHandler): def __init__(self, *args, **kwargs): super().__init__(*args, directory=DIRECTORY, **kwargs) def do_PUT(self): # Nur PUT auf /templates/* Pfade erlauben if not self.path.startswith('/templates'): self.send_error(403, "Method not allowed for this path") return # /templates.json liegt im web/-Verzeichnis (Katalog), alles andere unter ROOT if self.path == '/templates.json': file_path = os.path.join(DIRECTORY, 'templates.json') else: rel_path = self.path[1:] # '/templates/system/test.json' → 'templates/system/test.json' file_path = os.path.join(ROOT_DIR, rel_path) # Verzeichnis prüfen - muss existieren file_dir = os.path.dirname(file_path) if not os.path.exists(file_dir) or not os.path.isdir(file_dir): self.send_error(404, "Directory not found") return # Content-Type prüfen content_type = self.headers.get('Content-Type', '') if 'text/plain' not in content_type and not content_type.startswith('text/'): self.send_error(400, "Unsupported content type") return # Inhalt lesen und speichern content_length = int(self.headers.get('Content-Length', 0)) if content_length <= 0: self.send_error(400, "No content provided") return try: file_content = self.rfile.read(content_length) # Datei schreiben with open(file_path, 'wb') as f: f.write(file_content) self.send_response(200) self.send_header('Content-type', 'text/plain') self.end_headers() self.wfile.write(b"File saved successfully") except Exception as e: self.send_error(500, f"Failed to save file: {e}") def do_GET(self): # Für Root-Pfad: index.html servieren if self.path == '/' or self.path == '/index.html': self.path = '/index.html' return super().do_GET() # Anfragen für /templates.json oder /templates/* umleiten if self.path.startswith('/templates'): # /templates.json ist der Katalog und liegt im web/-Verzeichnis, # /templates/... verweist auf Template-Dateien im Projekt-Root if self.path == '/templates.json': file_path = os.path.join(DIRECTORY, 'templates.json') else: rel_path = self.path[1:] # '/templates/system/x.json' → 'templates/system/x.json' file_path = os.path.join(ROOT_DIR, rel_path) if os.path.exists(file_path) and not os.path.isdir(file_path): try: self.path = file_path # Einfach die Datei senden with open(file_path, 'rb') as f: self.send_response(200) self.send_header('Content-type', 'text/plain' if file_path.endswith('.md') else 'application/json') self.end_headers() self.wfile.write(f.read()) return except Exception as e: self.send_error(500, f"Error serving file: {e}") return else: self.send_error(404, "File not found") return return super().do_GET() def main(): PORT = 8081 print(f"Serving on http://localhost:{PORT}") with socketserver.TCPServer(("", PORT), Handler) as httpd: print(f"Serving Prompt Templates on http://localhost:{PORT}") print(f"Press Ctrl+C to stop") print(f"Directory: {DIRECTORY}") try: httpd.serve_forever() except KeyboardInterrupt: print("\nServer stopped") if __name__ == "__main__": main()