Live reload for dev mode

This commit is contained in:
Sascha Ißbrücker
2026-01-02 18:23:29 +01:00
parent 4291bda9d4
commit ec0c7ee253
5 changed files with 115 additions and 0 deletions

63
bookmarks/views/reload.py Normal file
View File

@@ -0,0 +1,63 @@
import json
import threading
import uuid
from pathlib import Path
from queue import Empty, Queue
from django.dispatch import receiver
from django.http import StreamingHttpResponse
from django.utils.autoreload import autoreload_started, file_changed
_styles_dir = Path(__file__).resolve().parent.parent / "styles"
_static_dir = Path(__file__).resolve().parent.parent / "static"
_server_id = str(uuid.uuid4())
_active_connections = set()
_connections_lock = threading.Lock()
def _event_stream():
client_queue = Queue()
with _connections_lock:
_active_connections.add(client_queue)
try:
data = json.dumps({"server_id": _server_id})
yield f"event: connected\ndata: {data}\n\n"
while True:
try:
data = client_queue.get(timeout=30)
yield f"event: file_change\ndata: {data}\n\n"
except Empty:
yield ": keepalive\n\n"
finally:
with _connections_lock:
_active_connections.discard(client_queue)
def live_reload(request):
response = StreamingHttpResponse(_event_stream(), content_type="text/event-stream")
response["Cache-Control"] = "no-cache"
return response
@receiver(autoreload_started)
def handle_auto_reload(sender, **kwargs):
sender.watch_dir(_styles_dir, "**/*.css")
sender.watch_dir(_static_dir, "bundle.js")
@receiver(file_changed)
def handle_file_changed(sender, file_path, **kwargs):
print(f"File changed: {file_path}")
data = json.dumps({"file_path": str(file_path)})
with _connections_lock:
for queue in _active_connections:
queue.put(data)
# Return True for CSS/JS files to prevent Django server restart
if file_path.suffix in (".css", ".js"):
return True