mirror of
https://github.com/sissbruecker/linkding.git
synced 2026-02-27 22:43:15 +08:00
64 lines
1.7 KiB
Python
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
|