Files
linkding/bookmarks/views/reload.py
2026-01-02 18:26:14 +01:00

64 lines
1.7 KiB
Python

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