rename handler
This commit is contained in:
@@ -9,7 +9,7 @@ from changedetectionio.blueprint.ui.edit import construct_blueprint as construct
|
||||
from changedetectionio.blueprint.ui.notification import construct_blueprint as construct_notification_blueprint
|
||||
from changedetectionio.blueprint.ui.views import construct_blueprint as construct_views_blueprint
|
||||
|
||||
def construct_blueprint(datastore: ChangeDetectionStore, update_q, running_update_threads, queuedWatchMetaData, watch_check_completed):
|
||||
def construct_blueprint(datastore: ChangeDetectionStore, update_q, running_update_threads, queuedWatchMetaData, watch_check_update):
|
||||
ui_blueprint = Blueprint('ui', __name__, template_folder="templates")
|
||||
|
||||
# Register the edit blueprint
|
||||
@@ -21,10 +21,10 @@ def construct_blueprint(datastore: ChangeDetectionStore, update_q, running_updat
|
||||
ui_blueprint.register_blueprint(notification_blueprint)
|
||||
|
||||
# Register the views blueprint
|
||||
views_blueprint = construct_views_blueprint(datastore, update_q, queuedWatchMetaData, watch_check_completed)
|
||||
views_blueprint = construct_views_blueprint(datastore, update_q, queuedWatchMetaData, watch_check_update)
|
||||
ui_blueprint.register_blueprint(views_blueprint)
|
||||
|
||||
ui_ajax_blueprint = constuct_ui_ajax_blueprint(datastore, update_q, running_update_threads, queuedWatchMetaData, watch_check_completed)
|
||||
ui_ajax_blueprint = constuct_ui_ajax_blueprint(datastore, update_q, running_update_threads, queuedWatchMetaData, watch_check_update)
|
||||
ui_blueprint.register_blueprint(ui_ajax_blueprint)
|
||||
|
||||
# Import the login decorator
|
||||
@@ -252,7 +252,7 @@ def construct_blueprint(datastore: ChangeDetectionStore, update_q, running_updat
|
||||
|
||||
if uuids:
|
||||
for uuid in uuids:
|
||||
watch_check_completed.send(watch_uuid=uuid)
|
||||
watch_check_update.send(watch_uuid=uuid)
|
||||
|
||||
return redirect(url_for('watchlist.index'))
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ from flask import Blueprint, request, redirect, url_for, flash, render_template,
|
||||
|
||||
from changedetectionio.store import ChangeDetectionStore
|
||||
|
||||
def constuct_ui_ajax_blueprint(datastore: ChangeDetectionStore, update_q, running_update_threads, queuedWatchMetaData, watch_check_completed):
|
||||
def constuct_ui_ajax_blueprint(datastore: ChangeDetectionStore, update_q, running_update_threads, queuedWatchMetaData, watch_check_update):
|
||||
ui_ajax_blueprint = Blueprint('ajax', __name__, template_folder="templates", url_prefix='/ajax')
|
||||
|
||||
# Import the login decorator
|
||||
@@ -25,9 +25,9 @@ def constuct_ui_ajax_blueprint(datastore: ChangeDetectionStore, update_q, runnin
|
||||
elif op == 'recheck':
|
||||
update_q.put(queuedWatchMetaData.PrioritizedItem(priority=1, item={'uuid': uuid}))
|
||||
|
||||
watch_check_completed = signal('watch_check_completed')
|
||||
if watch_check_completed:
|
||||
watch_check_completed.send(watch_uuid=uuid)
|
||||
watch_check_update = signal('watch_check_update')
|
||||
if watch_check_update:
|
||||
watch_check_update.send(watch_uuid=uuid)
|
||||
|
||||
return 'OK'
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ from changedetectionio.store import ChangeDetectionStore
|
||||
from changedetectionio.auth_decorator import login_optionally_required
|
||||
from changedetectionio import html_tools
|
||||
|
||||
def construct_blueprint(datastore: ChangeDetectionStore, update_q, queuedWatchMetaData, watch_check_completed):
|
||||
def construct_blueprint(datastore: ChangeDetectionStore, update_q, queuedWatchMetaData, watch_check_update):
|
||||
views_blueprint = Blueprint('ui_views', __name__, template_folder="../ui/templates")
|
||||
|
||||
@views_blueprint.route("/preview/<string:uuid>", methods=['GET'])
|
||||
|
||||
@@ -21,7 +21,7 @@ class SignalPriorityQueue(queue.PriorityQueue):
|
||||
if hasattr(item, 'item') and isinstance(item.item, dict) and 'uuid' in item.item:
|
||||
uuid = item.item['uuid']
|
||||
# Get the signal and send it if it exists
|
||||
watch_check_completed = signal('watch_check_completed')
|
||||
if watch_check_completed:
|
||||
watch_check_update = signal('watch_check_update')
|
||||
if watch_check_update:
|
||||
# Send the watch_uuid parameter
|
||||
watch_check_completed.send(watch_uuid=uuid)
|
||||
watch_check_update.send(watch_uuid=uuid)
|
||||
@@ -33,7 +33,7 @@ from flask_cors import CORS
|
||||
|
||||
# Create specific signals for application events
|
||||
# Make this a global singleton to avoid multiple signal objects
|
||||
watch_check_completed = signal('watch_check_completed', doc='Signal sent when a watch check is completed')
|
||||
watch_check_update = signal('watch_check_update', doc='Signal sent when a watch check is completed')
|
||||
from flask_wtf import CSRFProtect
|
||||
from loguru import logger
|
||||
import eventlet
|
||||
@@ -245,7 +245,7 @@ def changedetection_app(config=None, datastore_o=None):
|
||||
app.config['DATASTORE'] = datastore_o
|
||||
|
||||
# Store the signal in the app config to ensure it's accessible everywhere
|
||||
app.config['WATCH_CHECK_COMPLETED_SIGNAL'] = watch_check_completed
|
||||
app.config['watch_check_update_SIGNAL'] = watch_check_update
|
||||
|
||||
login_manager = flask_login.LoginManager(app)
|
||||
login_manager.login_view = 'login'
|
||||
@@ -472,7 +472,7 @@ def changedetection_app(config=None, datastore_o=None):
|
||||
|
||||
# watchlist UI buttons etc
|
||||
import changedetectionio.blueprint.ui as ui
|
||||
app.register_blueprint(ui.construct_blueprint(datastore, update_q, running_update_threads, queuedWatchMetaData, watch_check_completed))
|
||||
app.register_blueprint(ui.construct_blueprint(datastore, update_q, running_update_threads, queuedWatchMetaData, watch_check_update))
|
||||
|
||||
import changedetectionio.blueprint.watchlist as watchlist
|
||||
app.register_blueprint(watchlist.construct_blueprint(datastore=datastore, update_q=update_q, queuedWatchMetaData=queuedWatchMetaData), url_prefix='')
|
||||
|
||||
@@ -126,9 +126,9 @@ class model(watch_base):
|
||||
'remote_server_reply': None,
|
||||
'track_ldjson_price_data': None
|
||||
})
|
||||
watch_check_completed = signal('watch_check_completed')
|
||||
if watch_check_completed:
|
||||
watch_check_completed.send(watch_uuid=self.get('uuid'))
|
||||
watch_check_update = signal('watch_check_update')
|
||||
if watch_check_update:
|
||||
watch_check_update.send(watch_uuid=self.get('uuid'))
|
||||
|
||||
return
|
||||
|
||||
|
||||
@@ -5,17 +5,14 @@ import time
|
||||
import os
|
||||
from loguru import logger
|
||||
|
||||
from changedetectionio.flask_app import _jinja2_filter_datetime, watch_check_completed
|
||||
|
||||
|
||||
class SignalHandler:
|
||||
"""A standalone class to receive signals"""
|
||||
def __init__(self, socketio_instance, datastore):
|
||||
self.socketio_instance = socketio_instance
|
||||
self.datastore = datastore
|
||||
|
||||
# Connect to the watch_check_completed signal
|
||||
from changedetectionio.flask_app import watch_check_completed as wcc
|
||||
# Connect to the watch_check_update signal
|
||||
from changedetectionio.flask_app import watch_check_update as wcc
|
||||
wcc.connect(self.handle_signal, weak=False)
|
||||
logger.info("SignalHandler: Connected to signal from direct import")
|
||||
|
||||
@@ -42,6 +39,7 @@ def handle_watch_update(socketio, **kwargs):
|
||||
|
||||
# Emit the watch update to all connected clients
|
||||
from changedetectionio.flask_app import running_update_threads, update_q
|
||||
from changedetectionio.flask_app import _jinja2_filter_datetime
|
||||
|
||||
# Get list of watches that are currently running
|
||||
running_uuids = []
|
||||
@@ -69,9 +67,10 @@ def handle_watch_update(socketio, **kwargs):
|
||||
'notification_muted': True if watch.get('notification_muted') else False,
|
||||
'unviewed': watch.has_unviewed,
|
||||
'uuid': watch.get('uuid'),
|
||||
'event_timestamp': time.time()
|
||||
}
|
||||
socketio.emit("watch_update", watch_data)
|
||||
logger.debug(f"Socket.IO: Emitted update for watch {watch.get('uuid')}")
|
||||
logger.debug(f"Socket.IO: Emitted update for watch {watch.get('uuid')}, Checking now: {watch_data['checking_now']}")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Socket.IO error in handle_watch_update: {str(e)}")
|
||||
|
||||
@@ -43,7 +43,7 @@ $(document).ready(function () {
|
||||
|
||||
// Listen for periodically emitted watch data
|
||||
socket.on('watch_update', function (watch) {
|
||||
console.log(`Watch update ${watch.uuid}`);
|
||||
console.log(`${watch.event_timestamp} - Watch update ${watch.uuid} - Checking now - ${watch.checking_now}`);
|
||||
|
||||
const $watchRow = $('tr[data-watch-uuid="' + watch.uuid + '"]');
|
||||
if ($watchRow.length) {
|
||||
|
||||
@@ -167,9 +167,9 @@ class ChangeDetectionStore:
|
||||
self.data['watching'][uuid].update({'last_viewed': int(timestamp)})
|
||||
self.needs_write = True
|
||||
|
||||
watch_check_completed = signal('watch_check_completed')
|
||||
if watch_check_completed:
|
||||
watch_check_completed.send(watch_uuid=uuid)
|
||||
watch_check_update = signal('watch_check_update')
|
||||
if watch_check_update:
|
||||
watch_check_update.send(watch_uuid=uuid)
|
||||
|
||||
def remove_password(self):
|
||||
self.__data['settings']['application']['password'] = False
|
||||
|
||||
37
changedetectionio/tests/realtime/test_socketio.py
Executable file
37
changedetectionio/tests/realtime/test_socketio.py
Executable file
@@ -0,0 +1,37 @@
|
||||
import asyncio
|
||||
import socketio
|
||||
|
||||
# URL of your Socket.IO server
|
||||
SOCKETIO_URL = "http://localhost:5000" # Change as needed
|
||||
SOCKETIO_PATH = "/socket.io" # Match the path used in your JS config
|
||||
|
||||
# Number of clients to simulate
|
||||
NUM_CLIENTS = 10
|
||||
|
||||
async def start_client(client_id: int):
|
||||
sio = socketio.AsyncClient(reconnection_attempts=5, reconnection_delay=1)
|
||||
|
||||
@sio.event
|
||||
async def connect():
|
||||
print(f"[Client {client_id}] Connected")
|
||||
|
||||
@sio.event
|
||||
async def disconnect():
|
||||
print(f"[Client {client_id}] Disconnected")
|
||||
|
||||
@sio.on("watch_update")
|
||||
async def on_watch_update(watch):
|
||||
print(f"[Client {client_id}] Received update: {watch}")
|
||||
|
||||
try:
|
||||
await sio.connect(SOCKETIO_URL, socketio_path=SOCKETIO_PATH, transports=["websocket", "polling"])
|
||||
await sio.wait()
|
||||
except Exception as e:
|
||||
print(f"[Client {client_id}] Connection error: {e}")
|
||||
|
||||
async def main():
|
||||
clients = [start_client(i) for i in range(NUM_CLIENTS)]
|
||||
await asyncio.gather(*clients)
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -2,7 +2,7 @@ from .processors.exceptions import ProcessorException
|
||||
import changedetectionio.content_fetchers.exceptions as content_fetchers_exceptions
|
||||
from changedetectionio.processors.text_json_diff.processor import FilterNotFoundInResponse
|
||||
from changedetectionio import html_tools
|
||||
from changedetectionio.flask_app import watch_check_completed
|
||||
from changedetectionio.flask_app import watch_check_update
|
||||
|
||||
import importlib
|
||||
import os
|
||||
@@ -272,7 +272,7 @@ class update_worker(threading.Thread):
|
||||
logger.info(f"Processing watch UUID {uuid} Priority {queued_item_data.priority} URL {watch['url']}")
|
||||
|
||||
try:
|
||||
watch_check_completed.send(watch_uuid=watch['uuid'])
|
||||
watch_check_update.send(watch_uuid=watch['uuid'])
|
||||
|
||||
# Processor is what we are using for detecting the "Change"
|
||||
processor = watch.get('processor', 'text_json_diff')
|
||||
@@ -595,8 +595,8 @@ class update_worker(threading.Thread):
|
||||
|
||||
# Send signal for watch check completion with the watch data
|
||||
if watch:
|
||||
logger.info(f"Sending watch_check_completed signal for UUID {watch['uuid']}")
|
||||
watch_check_completed.send(watch_uuid=watch['uuid'])
|
||||
logger.info(f"Sending watch_check_update signal for UUID {watch['uuid']}")
|
||||
watch_check_update.send(watch_uuid=watch['uuid'])
|
||||
|
||||
update_handler = None
|
||||
logger.debug(f"Watch {uuid} done in {time.time()-fetch_start_time:.2f}s")
|
||||
|
||||
Reference in New Issue
Block a user