- Bearbeiten-Button in jeder Template-Karte - Editier-Modal mit Save/Abbrechen-Funktionalität - PUT-Endpoint in serve.py zum Speichern bearbeiteter Dateien
119 lines
4.2 KiB
Python
Executable file
119 lines
4.2 KiB
Python
Executable file
#!/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
|
|
|
|
# Pfad relativ zur ROOT_DIR konstruieren
|
|
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'):
|
|
# Pfad relativ zur ROOT_DIR konstruieren
|
|
rel_path = self.path[1:] # '/templates.json' → 'templates.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()
|