Compare commits

...

3 Commits

Author SHA1 Message Date
dgtlmoon
60d54bf92b tweak text 2025-06-04 11:14:08 +02:00
dgtlmoon
4b94e5b7f5 Add JS stub handler 2025-06-04 11:12:24 +02:00
dgtlmoon
1a2192680a Realtime UI - Ability to notify browser/client if there was a notification event 2025-06-04 11:03:17 +02:00
5 changed files with 64 additions and 3 deletions

View File

@@ -3,6 +3,41 @@ import asyncio
from blinker import signal
from loguru import logger
class NotificationQueue(queue.Queue):
"""
Extended Queue that sends a 'notification_event' signal when notifications are added.
This class extends the standard Queue and adds a signal emission after a notification
is put into the queue. The signal includes the watch UUID if available.
"""
def __init__(self, maxsize=0):
super().__init__(maxsize)
try:
self.notification_event_signal = signal('notification_event')
except Exception as e:
logger.critical(f"Exception creating notification_event signal: {e}")
def put(self, item, block=True, timeout=None):
# Call the parent's put method first
super().put(item, block, timeout)
# After putting the notification in the queue, emit signal with watch UUID
try:
if self.notification_event_signal and isinstance(item, dict):
watch_uuid = item.get('uuid')
if watch_uuid:
# Send the notification_event signal with the watch UUID
self.notification_event_signal.send(watch_uuid=watch_uuid)
logger.trace(f"NotificationQueue: Emitted notification_event signal for watch UUID {watch_uuid}")
else:
# Send signal without UUID for system notifications
self.notification_event_signal.send()
logger.trace("NotificationQueue: Emitted notification_event signal for system notification")
except Exception as e:
logger.error(f"Exception emitting notification_event signal: {e}")
class SignalPriorityQueue(queue.PriorityQueue):
"""
Extended PriorityQueue that sends a signal when items with a UUID are added.

View File

@@ -12,7 +12,7 @@ from blinker import signal
from changedetectionio.strtobool import strtobool
from threading import Event
from changedetectionio.custom_queue import SignalPriorityQueue, AsyncSignalPriorityQueue
from changedetectionio.custom_queue import SignalPriorityQueue, AsyncSignalPriorityQueue, NotificationQueue
from changedetectionio import worker_handler
from flask import (
@@ -52,7 +52,7 @@ extra_stylesheets = []
# Use async queue by default, keep sync for backward compatibility
update_q = AsyncSignalPriorityQueue() if worker_handler.USE_ASYNC_WORKERS else SignalPriorityQueue()
notification_q = queue.Queue()
notification_q = NotificationQueue()
MAX_QUEUE_SIZE = 2000
app = Flask(__name__,

View File

@@ -29,6 +29,11 @@ class SignalHandler:
watch_delete_signal = signal('watch_deleted')
watch_delete_signal.connect(self.handle_deleted_signal, weak=False)
# Connect to the notification_event signal
notification_event_signal = signal('notification_event')
notification_event_signal.connect(self.handle_notification_event, weak=False)
logger.info("SignalHandler: Connected to notification_event signal")
# Create and start the queue update thread using standard threading
import threading
self.polling_emitter_thread = threading.Thread(
@@ -89,6 +94,23 @@ class SignalHandler:
except Exception as e:
logger.error(f"Socket.IO error in handle_queue_length: {str(e)}")
def handle_notification_event(self, *args, **kwargs):
"""Handle notification_event signal and emit to all clients"""
try:
watch_uuid = kwargs.get('watch_uuid')
logger.debug(f"SignalHandler: Notification event received for watch UUID: {watch_uuid}")
# Emit the notification event to all connected clients
self.socketio_instance.emit("notification_event", {
"watch_uuid": watch_uuid,
"event_timestamp": time.time()
})
logger.trace(f"Socket.IO: Emitted notification_event for watch UUID {watch_uuid}")
except Exception as e:
logger.error(f"Socket.IO error in handle_notification_event: {str(e)}")
def polling_emit_running_or_queued_watches_threaded(self):
"""Threading version of polling for Windows compatibility"""

View File

@@ -94,6 +94,10 @@ $(document).ready(function () {
}
});
socket.on('notification_event', function (data) {
console.log(`Stub handler for notification_event ${data.watch_uuid}`)
});
// Listen for periodically emitted watch data
console.log('Adding watch_update event listener');

View File

@@ -236,7 +236,7 @@
<script src="{{url_for('static_content', group='js', filename='toggle-theme.js')}}" defer></script>
<div id="checking-now-fixed-tab" style="display: none;"><span class="spinner"></span><span>&nbsp;Checking now</span></div>
<div id="realtime-conn-error" style="display:none">Realtime updates offline</div>
<div id="realtime-conn-error" style="display:none">Offline</div>
</body>
</html>