new-codigoparallevar/scripts/autoserve.py
2022-07-21 21:19:03 +02:00

112 lines
2.9 KiB
Python

#!/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'<script>' + f.read() + b'</script>'
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()