#!/usr/bin/env python3 """ Local HTTP API for screen-brightness override (crew manual control per MSC.191(79)). Listens on 127.0.0.1 only. Run as root so it can write /run/screen-brightness/override. """ import os import urllib.parse from pathlib import Path from http.server import HTTPServer, BaseHTTPRequestHandler OVERRIDE_FILE = Path("/run/screen-brightness/override") RUN_DIR = OVERRIDE_FILE.parent HOST = "127.0.0.1" PORT = 8765 class BrightnessHandler(BaseHTTPRequestHandler): def do_POST(self): path = self.path.split("?")[0] if path != "/brightness" and path != "/": self.send_error(404) return length = int(self.headers.get("Content-Length", 0)) body = self.rfile.read(length).decode("utf-8", errors="ignore") if length else "" query = urllib.parse.parse_qs(urllib.parse.urlparse(self.path).query) level = (query.get("level") or [None])[0] or (urllib.parse.parse_qs(body).get("level") or [None])[0] if not level: self.send_response(400) self.send_header("Content-Type", "text/plain") self.end_headers() self.wfile.write(b"missing level=1|2|3|4|5|auto") return level = level.strip().lower() if level == "auto": value = "auto" elif level in ("1", "2", "3", "4", "5"): value = level else: self.send_response(400) self.send_header("Content-Type", "text/plain") self.end_headers() self.wfile.write(b"level must be 1, 2, 3, 4, 5, or auto") return try: RUN_DIR.mkdir(parents=True, exist_ok=True) OVERRIDE_FILE.write_text(value + "\n") except Exception as e: self.send_response(500) self.send_header("Content-Type", "text/plain") self.end_headers() self.wfile.write(f"write failed: {e}".encode()) return self.send_response(200) self.send_header("Content-Type", "text/plain") self.end_headers() self.wfile.write(f"ok {value}\n".encode()) def do_GET(self): if self.path.split("?")[0] in ("/", "/brightness", "/state"): state_file = Path("/run/screen-brightness/state") if state_file.exists(): self.send_response(200) self.send_header("Content-Type", "text/plain") self.end_headers() self.wfile.write(state_file.read_bytes()) else: self.send_response(404) self.end_headers() else: self.send_error(404) def log_message(self, format, *args): pass # quiet; use journal if needed def main(): if os.geteuid() != 0: raise SystemExit("brightness-api must run as root to write /run/screen-brightness/override") server = HTTPServer((HOST, PORT), BrightnessHandler) server.serve_forever() if __name__ == "__main__": main()