Add simplistic autoserve/update mechanism.

This commit is contained in:
Sergio Martínez Portela 2022-07-21 21:18:49 +02:00
parent a3ad99cb61
commit 7afb6be68f
2 changed files with 130 additions and 0 deletions

111
scripts/autoserve.py Normal file
View File

@ -0,0 +1,111 @@
#!/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()

19
wait_for_update.js Normal file
View File

@ -0,0 +1,19 @@
(function (){
var wait_for_update = function() {
console.debug("Waiting for changes...");
fetch('/__wait_for_changes').then(r => {
if (r.status !== 200) {
setTimeout(
wait_for_update,
1000,
);
}
else {
// Reload
window.location = window.location;
}
});
};
wait_for_update();
})();