#!/usr/bin/env python3 import json import logging import os import subprocess import sys from http.server import BaseHTTPRequestHandler, HTTPServer from urllib.parse import urlparse # Configure logging logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s' ) logger = logging.getLogger(__name__) # Allowlisted applications that can be launched ALLOWED_APPS = { 'firefox': 'firefox', 'kodi': 'kodi' } class AppLauncherHandler(BaseHTTPRequestHandler): def log_message(self, format, *args): logger.info(format % args) def do_GET(self): if self.path == '/': self.send_response(200) self.send_header('Content-type', 'application/json') self.end_headers() response = { 'status': 'running', 'available_apps': list(ALLOWED_APPS.keys()), 'usage': 'POST /launch/ to launch an application' } self.wfile.write(json.dumps(response, indent=2).encode()) else: self.send_error(404) def do_POST(self): parsed_path = urlparse(self.path) path_parts = parsed_path.path.strip('/').split('/') if len(path_parts) == 2 and path_parts[0] == 'launch': app_name = path_parts[1] self.launch_app(app_name) else: self.send_error(404, "Invalid endpoint. Use /launch/") def launch_app(self, app_name): if app_name not in ALLOWED_APPS: self.send_error(400, f"Application '{app_name}' not allowed. Available apps: {list(ALLOWED_APPS.keys())}") return command = ALLOWED_APPS[app_name] try: # Launch the application in the background # Ensure we have the proper environment for GUI apps env = os.environ.copy() logger.info(f"Launching application: {command}") process = subprocess.Popen( [command], env=env, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, start_new_session=True ) self.send_response(200) self.send_header('Content-type', 'application/json') self.end_headers() response = { 'status': 'success', 'message': f'Successfully launched {app_name}', 'pid': process.pid } self.wfile.write(json.dumps(response).encode()) except FileNotFoundError: logger.error(f"Application not found: {command}") self.send_error(500, f"Application '{app_name}' not found on system") except Exception as e: logger.error(f"Error launching {command}: {e}") self.send_error(500, f"Failed to launch {app_name}: {str(e)}") def main(): port = int(sys.argv[1]) if len(sys.argv) > 1 else 8081 server = HTTPServer(('0.0.0.0', port), AppLauncherHandler) logger.info(f"App launcher server starting on port {port}") logger.info(f"Available applications: {list(ALLOWED_APPS.keys())}") try: server.serve_forever() except KeyboardInterrupt: logger.info("Server shutting down...") server.server_close() if __name__ == '__main__': main()