#!/usr/bin/env python3 import sys import http.server import socketserver import threading import os import time import select import inotify.adapters PORT = 8000 MONITORED_EVENT_TYPES = ( 'IN_CREATE', # 'IN_MODIFY', 'IN_CLOSE_WRITE', 'IN_DELETE', 'IN_MOVED_FROM', 'IN_MOVED_TO', 'IN_DELETE_SELF', 'IN_MOVE_SELF', ) WAITING_RESPONSES = [] SLEEP_TIME = 0.5 COUNTER = 0 MAX_WAITS = 100 class Server(http.server.SimpleHTTPRequestHandler): def do_GET(self): if self.path.strip('/') == '__wait_for_changes': WAITING_RESPONSES.append(self) print(len(WAITING_RESPONSES), "waiting responses") global COUNTER ticket, COUNTER = COUNTER, COUNTER + 1 while self in WAITING_RESPONSES: # This is an horribe way to wait! ... but it may work for quick tests 🤷 if COUNTER - ticket > MAX_WAITS: # Connection closed by the other side print("Manually closed for cleanup") WAITING_RESPONSES.remove(self) # send 502 response, timeout self.send_response(502) # send response headers self.end_headers() return time.sleep(SLEEP_TIME) return # send 200 response self.send_response(200) # send response headers self.end_headers() with open(self.path.strip('/'), 'rb') as f: # send the body of the response self.wfile.write(f.read()) if not self.path.endswith('.html'): return else: # Append update waiter with open('wait_for_update.js', 'rb') as f: new_data = b'' self.wfile.write(new_data) new_data_len = len(new_data) return def notify_reloads(): while len(WAITING_RESPONSES) > 0: # Close opened connections res = WAITING_RESPONSES.pop(0) try: # send 200 response res.send_response(200) # send response headers res.end_headers() except Exception as e: print("ERROR:", e) global COUNTER COUNTER = 0 def start_notifier(): notifier = inotify.adapters.InotifyTree(os.getcwd()) for event in notifier.event_gen(yield_nones=False): (ev, types, directory, file) = event if any([type in MONITORED_EVENT_TYPES for type in types]): notify_reloads() def serve(): Handler = Server notifier_thread = threading.Thread(target=start_notifier) with http.server.ThreadingHTTPServer(("127.0.0.1", PORT), Handler) as httpd: print("serving at port", PORT) notifier_thread.start() httpd.serve_forever() if __name__ == '__main__': serve()