chore(hq): daily sync 2026-02-19
This commit is contained in:
73
hq/mission-control/serve.py
Normal file
73
hq/mission-control/serve.py
Normal file
@@ -0,0 +1,73 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Simple HTTP server with save API for Mission Control."""
|
||||
import http.server
|
||||
import json
|
||||
import os
|
||||
import shutil
|
||||
from datetime import datetime
|
||||
|
||||
PORT = 8091
|
||||
os.chdir(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
class MissionControlHandler(http.server.SimpleHTTPRequestHandler):
|
||||
def end_headers(self):
|
||||
self.send_header('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0')
|
||||
self.send_header('Pragma', 'no-cache')
|
||||
self.send_header('Expires', '0')
|
||||
self.send_header('Access-Control-Allow-Origin', '*')
|
||||
self.send_header('Access-Control-Allow-Methods', 'GET, PUT, OPTIONS')
|
||||
self.send_header('Access-Control-Allow-Headers', 'Content-Type')
|
||||
super().end_headers()
|
||||
|
||||
def do_OPTIONS(self):
|
||||
self.send_response(200)
|
||||
self.end_headers()
|
||||
|
||||
def do_PUT(self):
|
||||
path = self.path.lstrip('/')
|
||||
if not path.startswith('data/') or not path.endswith('.json'):
|
||||
self.send_response(403)
|
||||
self.end_headers()
|
||||
self.wfile.write(b'{"error":"Only data/*.json writes allowed"}')
|
||||
return
|
||||
|
||||
content_length = int(self.headers.get('Content-Length', 0))
|
||||
body = self.rfile.read(content_length)
|
||||
|
||||
try:
|
||||
data = json.loads(body)
|
||||
except json.JSONDecodeError as e:
|
||||
self.send_response(400)
|
||||
self.end_headers()
|
||||
self.wfile.write(json.dumps({"error": f"Invalid JSON: {e}"}).encode())
|
||||
return
|
||||
|
||||
filepath = os.path.join(os.getcwd(), path)
|
||||
os.makedirs(os.path.dirname(filepath), exist_ok=True)
|
||||
|
||||
if os.path.exists(filepath):
|
||||
backup = filepath + f'.bak-{datetime.now().strftime("%Y%m%d-%H%M%S")}'
|
||||
shutil.copy2(filepath, backup)
|
||||
bak_dir = os.path.dirname(filepath)
|
||||
bak_base = os.path.basename(filepath)
|
||||
baks = sorted([f for f in os.listdir(bak_dir) if f.startswith(bak_base + '.bak-')])
|
||||
for old in baks[:-10]:
|
||||
os.remove(os.path.join(bak_dir, old))
|
||||
|
||||
with open(filepath, 'w') as f:
|
||||
json.dump(data, f, indent=2)
|
||||
|
||||
self.send_response(200)
|
||||
self.send_header('Content-Type', 'application/json')
|
||||
self.end_headers()
|
||||
self.wfile.write(json.dumps({"ok": True, "saved": path}).encode())
|
||||
|
||||
def log_message(self, format, *args):
|
||||
pass
|
||||
|
||||
if __name__ == '__main__':
|
||||
class ThreadedServer(http.server.ThreadingHTTPServer):
|
||||
allow_reuse_address = True
|
||||
server = ThreadedServer(('0.0.0.0', PORT), MissionControlHandler)
|
||||
print(f'Atomizer HQ Mission Control serving on port {PORT}')
|
||||
server.serve_forever()
|
||||
Reference in New Issue
Block a user