1*60517a1eSAndroid Build Coastguard Workerimport contextlib 2*60517a1eSAndroid Build Coastguard Workerimport errno 3*60517a1eSAndroid Build Coastguard Workerimport os 4*60517a1eSAndroid Build Coastguard Workerimport sys 5*60517a1eSAndroid Build Coastguard Workerimport time 6*60517a1eSAndroid Build Coastguard Workerfrom http import server 7*60517a1eSAndroid Build Coastguard Worker 8*60517a1eSAndroid Build Coastguard Worker 9*60517a1eSAndroid Build Coastguard Workerdef main(argv): 10*60517a1eSAndroid Build Coastguard Worker build_workspace_directory = os.environ["BUILD_WORKSPACE_DIRECTORY"] 11*60517a1eSAndroid Build Coastguard Worker docs_directory = argv[1] 12*60517a1eSAndroid Build Coastguard Worker serve_directory = os.path.join(build_workspace_directory, docs_directory) 13*60517a1eSAndroid Build Coastguard Worker 14*60517a1eSAndroid Build Coastguard Worker class DirectoryHandler(server.SimpleHTTPRequestHandler): 15*60517a1eSAndroid Build Coastguard Worker def __init__(self, *args, **kwargs): 16*60517a1eSAndroid Build Coastguard Worker super().__init__(directory=serve_directory, *args, **kwargs) 17*60517a1eSAndroid Build Coastguard Worker 18*60517a1eSAndroid Build Coastguard Worker address = ("0.0.0.0", 8000) 19*60517a1eSAndroid Build Coastguard Worker # with server.ThreadingHTTPServer(address, DirectoryHandler) as (ip, port, httpd): 20*60517a1eSAndroid Build Coastguard Worker with _start_server(DirectoryHandler, "0.0.0.0", 8000) as (ip, port, httpd): 21*60517a1eSAndroid Build Coastguard Worker 22*60517a1eSAndroid Build Coastguard Worker def _print_server_info(): 23*60517a1eSAndroid Build Coastguard Worker print(f"Serving...") 24*60517a1eSAndroid Build Coastguard Worker print(f" Address: http://{ip}:{port}") 25*60517a1eSAndroid Build Coastguard Worker print(f" Serving directory: {serve_directory}") 26*60517a1eSAndroid Build Coastguard Worker print(f" url: file://{serve_directory}") 27*60517a1eSAndroid Build Coastguard Worker print(f" Server CWD: {os.getcwd()}") 28*60517a1eSAndroid Build Coastguard Worker print() 29*60517a1eSAndroid Build Coastguard Worker print("*** You do not need to restart this server to see changes ***") 30*60517a1eSAndroid Build Coastguard Worker print("*** CTRL+C once to reprint this info ***") 31*60517a1eSAndroid Build Coastguard Worker print("*** CTRL+C twice to exit ***") 32*60517a1eSAndroid Build Coastguard Worker print() 33*60517a1eSAndroid Build Coastguard Worker 34*60517a1eSAndroid Build Coastguard Worker while True: 35*60517a1eSAndroid Build Coastguard Worker _print_server_info() 36*60517a1eSAndroid Build Coastguard Worker try: 37*60517a1eSAndroid Build Coastguard Worker httpd.serve_forever() 38*60517a1eSAndroid Build Coastguard Worker except KeyboardInterrupt: 39*60517a1eSAndroid Build Coastguard Worker _print_server_info() 40*60517a1eSAndroid Build Coastguard Worker print( 41*60517a1eSAndroid Build Coastguard Worker "*** KeyboardInterrupt received: CTRL+C again to terminate server ***" 42*60517a1eSAndroid Build Coastguard Worker ) 43*60517a1eSAndroid Build Coastguard Worker try: 44*60517a1eSAndroid Build Coastguard Worker time.sleep(1) 45*60517a1eSAndroid Build Coastguard Worker print("Restarting serving ...") 46*60517a1eSAndroid Build Coastguard Worker except KeyboardInterrupt: 47*60517a1eSAndroid Build Coastguard Worker break 48*60517a1eSAndroid Build Coastguard Worker return 0 49*60517a1eSAndroid Build Coastguard Worker 50*60517a1eSAndroid Build Coastguard Worker 51*60517a1eSAndroid Build Coastguard Worker@contextlib.contextmanager 52*60517a1eSAndroid Build Coastguard Workerdef _start_server(handler, ip, start_port): 53*60517a1eSAndroid Build Coastguard Worker for port in range(start_port, start_port + 10): 54*60517a1eSAndroid Build Coastguard Worker try: 55*60517a1eSAndroid Build Coastguard Worker with server.ThreadingHTTPServer((ip, port), handler) as httpd: 56*60517a1eSAndroid Build Coastguard Worker yield ip, port, httpd 57*60517a1eSAndroid Build Coastguard Worker return 58*60517a1eSAndroid Build Coastguard Worker except OSError as e: 59*60517a1eSAndroid Build Coastguard Worker if e.errno == errno.EADDRINUSE: 60*60517a1eSAndroid Build Coastguard Worker pass 61*60517a1eSAndroid Build Coastguard Worker else: 62*60517a1eSAndroid Build Coastguard Worker raise 63*60517a1eSAndroid Build Coastguard Worker raise ValueError("Unable to find an available port") 64*60517a1eSAndroid Build Coastguard Worker 65*60517a1eSAndroid Build Coastguard Worker 66*60517a1eSAndroid Build Coastguard Workerif __name__ == "__main__": 67*60517a1eSAndroid Build Coastguard Worker sys.exit(main(sys.argv)) 68