mirror of
				https://github.com/dgtlmoon/changedetection.io.git
				synced 2025-11-04 00:27:48 +00:00 
			
		
		
		
	Compare commits
	
		
			5 Commits
		
	
	
		
			only-call-
			...
			filter-fai
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					491e0fc9c0 | ||
| 
						 | 
					58fccd3b2b | ||
| 
						 | 
					cb1b8b88d5 | ||
| 
						 | 
					2c720360bb | ||
| 
						 | 
					415896e838 | 
@@ -679,7 +679,10 @@ def changedetection_app(config=None, datastore_o=None):
 | 
			
		||||
 | 
			
		||||
        if request.method == 'POST' and form.validate():
 | 
			
		||||
 | 
			
		||||
            extra_update_obj = {}
 | 
			
		||||
            extra_update_obj = {
 | 
			
		||||
                'consecutive_filter_failures': 0,
 | 
			
		||||
                'last_error' : False
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if request.args.get('unpause_on_save'):
 | 
			
		||||
                extra_update_obj['paused'] = False
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,7 @@ from changedetectionio.notification import (
 | 
			
		||||
    default_notification_title,
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
# Equal to or greater than this number of FilterNotFoundInResponse exceptions will trigger a filter-not-found notification
 | 
			
		||||
_FILTER_FAILURE_THRESHOLD_ATTEMPTS_DEFAULT = 6
 | 
			
		||||
DEFAULT_SETTINGS_HEADERS_USERAGENT='Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.66 Safari/537.36'
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -21,10 +21,11 @@ def set_response_with_filter():
 | 
			
		||||
        f.write(test_return_data)
 | 
			
		||||
    return None
 | 
			
		||||
 | 
			
		||||
def run_filter_test(client, content_filter):
 | 
			
		||||
def run_filter_test(client, live_server, content_filter):
 | 
			
		||||
 | 
			
		||||
    # Response WITHOUT the filter ID element
 | 
			
		||||
    set_original_response()
 | 
			
		||||
 | 
			
		||||
    # Give the endpoint time to spin up
 | 
			
		||||
    time.sleep(1)
 | 
			
		||||
    # cleanup for the next
 | 
			
		||||
    client.get(
 | 
			
		||||
        url_for("form_delete", uuid="all"),
 | 
			
		||||
@@ -79,6 +80,7 @@ def run_filter_test(client, content_filter):
 | 
			
		||||
        "include_filters": content_filter,
 | 
			
		||||
        "fetch_backend": "html_requests"})
 | 
			
		||||
 | 
			
		||||
    # A POST here will also reset the filter failure counter (filter_failure_notification_threshold_attempts)
 | 
			
		||||
    res = client.post(
 | 
			
		||||
        url_for("edit_page", uuid="first"),
 | 
			
		||||
        data=notification_form_data,
 | 
			
		||||
@@ -91,20 +93,21 @@ def run_filter_test(client, content_filter):
 | 
			
		||||
    # Now the notification should not exist, because we didnt reach the threshold
 | 
			
		||||
    assert not os.path.isfile("test-datastore/notification.txt")
 | 
			
		||||
 | 
			
		||||
    # -2 because we would have checked twice above (on adding and on edit)
 | 
			
		||||
    # recheck it up to just before the threshold, including the fact that in the previous POST it would have rechecked (and incremented)
 | 
			
		||||
    for i in range(0, App._FILTER_FAILURE_THRESHOLD_ATTEMPTS_DEFAULT-2):
 | 
			
		||||
        res = client.get(url_for("form_watch_checknow"), follow_redirects=True)
 | 
			
		||||
        client.get(url_for("form_watch_checknow"), follow_redirects=True)
 | 
			
		||||
        wait_for_all_checks(client)
 | 
			
		||||
        assert not os.path.isfile("test-datastore/notification.txt"), f"test-datastore/notification.txt should not exist - Attempt {i}"
 | 
			
		||||
        time.sleep(2) # delay for apprise to fire
 | 
			
		||||
        assert not os.path.isfile("test-datastore/notification.txt"), f"test-datastore/notification.txt should not exist - Attempt {i} when threshold is {App._FILTER_FAILURE_THRESHOLD_ATTEMPTS_DEFAULT}"
 | 
			
		||||
 | 
			
		||||
    # We should see something in the frontend
 | 
			
		||||
    res = client.get(url_for("index"))
 | 
			
		||||
    assert b'Warning, no filters were found' in res.data
 | 
			
		||||
 | 
			
		||||
    # One more check should trigger it (see -2 above)
 | 
			
		||||
    client.get(url_for("form_watch_checknow"), follow_redirects=True)
 | 
			
		||||
    wait_for_all_checks(client)
 | 
			
		||||
    # One more check should trigger the _FILTER_FAILURE_THRESHOLD_ATTEMPTS_DEFAULT threshold
 | 
			
		||||
    client.get(url_for("form_watch_checknow"), follow_redirects=True)
 | 
			
		||||
    wait_for_all_checks(client)
 | 
			
		||||
    time.sleep(2)  # delay for apprise to fire
 | 
			
		||||
    # Now it should exist and contain our "filter not found" alert
 | 
			
		||||
    assert os.path.isfile("test-datastore/notification.txt")
 | 
			
		||||
 | 
			
		||||
@@ -149,13 +152,9 @@ def test_setup(live_server):
 | 
			
		||||
    live_server_setup(live_server)
 | 
			
		||||
 | 
			
		||||
def test_check_include_filters_failure_notification(client, live_server):
 | 
			
		||||
    set_original_response()
 | 
			
		||||
    wait_for_all_checks(client)
 | 
			
		||||
    run_filter_test(client, '#nope-doesnt-exist')
 | 
			
		||||
    run_filter_test(client, live_server,'#nope-doesnt-exist')
 | 
			
		||||
 | 
			
		||||
def test_check_xpath_filter_failure_notification(client, live_server):
 | 
			
		||||
    set_original_response()
 | 
			
		||||
    time.sleep(1)
 | 
			
		||||
    run_filter_test(client, '//*[@id="nope-doesnt-exist"]')
 | 
			
		||||
    run_filter_test(client, live_server, '//*[@id="nope-doesnt-exist"]')
 | 
			
		||||
 | 
			
		||||
# Test that notification is never sent
 | 
			
		||||
 
 | 
			
		||||
@@ -348,7 +348,7 @@ class update_worker(threading.Thread):
 | 
			
		||||
                            # Send notification if we reached the threshold?
 | 
			
		||||
                            threshold = self.datastore.data['settings']['application'].get('filter_failure_notification_threshold_attempts',
 | 
			
		||||
                                                                                           0)
 | 
			
		||||
                            logger.error(f"Filter for {uuid} not found, consecutive_filter_failures: {c}")
 | 
			
		||||
                            logger.warning(f"Filter for {uuid} not found, consecutive_filter_failures: {c}")
 | 
			
		||||
                            if threshold > 0 and c >= threshold:
 | 
			
		||||
                                if not self.datastore.data['watching'][uuid].get('notification_muted'):
 | 
			
		||||
                                    self.send_filter_failure_notification(uuid)
 | 
			
		||||
@@ -362,7 +362,6 @@ class update_worker(threading.Thread):
 | 
			
		||||
                        # Yes fine, so nothing todo, don't continue to process.
 | 
			
		||||
                        process_changedetection_results = False
 | 
			
		||||
                        changed_detected = False
 | 
			
		||||
                        self.datastore.update_watch(uuid=uuid, update_obj={'last_error': False})
 | 
			
		||||
                    except content_fetchers.exceptions.BrowserConnectError as e:
 | 
			
		||||
                        self.datastore.update_watch(uuid=uuid,
 | 
			
		||||
                                                    update_obj={'last_error': e.msg
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user