- {{ render_field(form.notification_title, class="m-d notification-title") }}
+ {{ render_field(form.notification_title, class="m-d notification-title", placeholder=settings_application['notification_title']) }}
Title for all notifications
- {{ render_field(form.notification_body , rows=5, class="notification-body") }}
+ {{ render_field(form.notification_body , rows=5, class="notification-body", placeholder=settings_application['notification_body']) }}
Body for all notifications
- {{ render_field(form.notification_format , rows=5, class="notification-format") }}
+
+ {{ render_field(form.notification_format , class="notification-format") }}
Format for all notifications
@@ -94,7 +96,7 @@
URLs generated by changedetection.io (such as {diff_url}) require the BASE_URL environment variable set.
- Your BASE_URL var is currently "{{current_base_url}}"
+ Your BASE_URL var is currently "{{settings_application['current_base_url']}}"
diff --git a/changedetectionio/templates/settings.html b/changedetectionio/templates/settings.html
index 0518eb9b..2db8c8b6 100644
--- a/changedetectionio/templates/settings.html
+++ b/changedetectionio/templates/settings.html
@@ -60,7 +60,7 @@
{{ render_field(form.application.form.base_url, placeholder="http://yoursite.com:5000/",
class="m-d") }}
- Base URL used for the {base_url} token in notifications and RSS links. Default value is the ENV var 'BASE_URL' (Currently "{{current_base_url}}"),
+ Base URL used for the {base_url} token in notifications and RSS links. Default value is the ENV var 'BASE_URL' (Currently "{{settings_application['current_base_url']}}"),
read more here.
@@ -87,7 +87,7 @@
diff --git a/changedetectionio/tests/test_notification.py b/changedetectionio/tests/test_notification.py
index 2a620e50..6b534f62 100644
--- a/changedetectionio/tests/test_notification.py
+++ b/changedetectionio/tests/test_notification.py
@@ -4,7 +4,13 @@ import re
from flask import url_for
from . util import set_original_response, set_modified_response, set_more_modified_response, live_server_setup
import logging
-from changedetectionio.notification import default_notification_body, default_notification_title
+
+from changedetectionio.notification import (
+ default_notification_body,
+ default_notification_format,
+ default_notification_title,
+ valid_notification_formats,
+)
def test_setup(live_server):
live_server_setup(live_server)
@@ -20,9 +26,26 @@ def test_check_notification(client, live_server):
# Re 360 - new install should have defaults set
res = client.get(url_for("settings_page"))
+ notification_url = url_for('test_notification_endpoint', _external=True).replace('http', 'json')
+
assert default_notification_body.encode() in res.data
assert default_notification_title.encode() in res.data
+ #####################
+ # Set this up for when we remove the notification from the watch, it should fallback with these details
+ res = client.post(
+ url_for("settings_page"),
+ data={"application-notification_urls": notification_url,
+ "application-notification_title": "fallback-title "+default_notification_title,
+ "application-notification_body": "fallback-body "+default_notification_body,
+ "application-notification_format": default_notification_format,
+ "requests-time_between_check-minutes": 180,
+ 'application-fetch_backend': "html_requests"},
+ follow_redirects=True
+ )
+
+ assert b"Settings updated." in res.data
+
# When test mode is in BASE_URL env mode, we should see this already configured
env_base_url = os.getenv('BASE_URL', '').strip()
if len(env_base_url):
@@ -47,8 +70,6 @@ def test_check_notification(client, live_server):
# Goto the edit page, add our ignore text
# Add our URL to the import page
- url = url_for('test_notification_endpoint', _external=True)
- notification_url = url.replace('http', 'json')
print (">>>> Notification URL: "+notification_url)
@@ -71,7 +92,6 @@ def test_check_notification(client, live_server):
"url": test_url,
"tag": "my tag",
"title": "my title",
- # No 'notification_use_default' here, so it's effectively False/off
"headers": "",
"fetch_backend": "html_requests"})
@@ -159,6 +179,30 @@ def test_check_notification(client, live_server):
# be sure we see it in the output log
assert b'New ChangeDetection.io Notification - ' + test_url.encode('utf-8') in res.data
+ set_original_response()
+ res = client.post(
+ url_for("edit_page", uuid="first"),
+ data={
+ "url": test_url,
+ "tag": "my tag",
+ "title": "my title",
+ "notification_urls": '',
+ "notification_title": '',
+ "notification_body": '',
+ "notification_format": default_notification_format,
+ "fetch_backend": "html_requests"},
+ follow_redirects=True
+ )
+ assert b"Updated watch." in res.data
+
+ time.sleep(2)
+
+ # Verify what was sent as a notification, this file should exist
+ with open("test-datastore/notification.txt", "r") as f:
+ notification_submission = f.read()
+ assert "fallback-title" in notification_submission
+ assert "fallback-body" in notification_submission
+
# cleanup for the next
client.get(
url_for("form_delete", uuid="all"),
@@ -181,20 +225,20 @@ def test_notification_validation(client, live_server):
assert b"Watch added" in res.data
# Re #360 some validation
- res = client.post(
- url_for("edit_page", uuid="first"),
- data={"notification_urls": 'json://localhost/foobar',
- "notification_title": "",
- "notification_body": "",
- "notification_format": "Text",
- "url": test_url,
- "tag": "my tag",
- "title": "my title",
- "headers": "",
- "fetch_backend": "html_requests"},
- follow_redirects=True
- )
- assert b"Notification Body and Title is required when a Notification URL is used" in res.data
+# res = client.post(
+# url_for("edit_page", uuid="first"),
+# data={"notification_urls": 'json://localhost/foobar',
+# "notification_title": "",
+# "notification_body": "",
+# "notification_format": "Text",
+# "url": test_url,
+# "tag": "my tag",
+# "title": "my title",
+# "headers": "",
+# "fetch_backend": "html_requests"},
+# follow_redirects=True
+# )
+# assert b"Notification Body and Title is required when a Notification URL is used" in res.data
# Now adding a wrong token should give us an error
res = client.post(
@@ -217,81 +261,4 @@ def test_notification_validation(client, live_server):
follow_redirects=True
)
-# Check that the default VS watch specific notification is hit
-def test_check_notification_use_default(client, live_server):
- set_original_response()
- notification_url = url_for('test_notification_endpoint', _external=True).replace('http', 'json')
- test_url = url_for('test_endpoint', _external=True)
- res = client.post(
- url_for("form_quick_watch_add"),
- data={"url": test_url, "tag": ''},
- follow_redirects=True
- )
- assert b"Watch added" in res.data
-
- ## Setup the local one and enable it
- res = client.post(
- url_for("edit_page", uuid="first"),
- data={"notification_urls": notification_url,
- "notification_title": "watch-notification",
- "notification_body": "watch-body",
- 'notification_use_default': "True",
- "notification_format": "Text",
- "url": test_url,
- "tag": "my tag",
- "title": "my title",
- "headers": "",
- "fetch_backend": "html_requests"},
- follow_redirects=True
- )
-
- res = client.post(
- url_for("settings_page"),
- data={"application-notification_title": "global-notifications-title",
- "application-notification_body": "global-notifications-body\n",
- "application-notification_format": "Text",
- "application-notification_urls": notification_url,
- "requests-time_between_check-minutes": 180,
- "fetch_backend": "html_requests"
- },
- follow_redirects=True
- )
-
- # A change should by default trigger a notification of the global-notifications
- time.sleep(1)
- set_modified_response()
- client.get(url_for("form_watch_checknow"), follow_redirects=True)
- time.sleep(2)
- with open("test-datastore/notification.txt", "r") as f:
- assert 'global-notifications-title' in f.read()
-
- ## Setup the local one and enable it
- res = client.post(
- url_for("edit_page", uuid="first"),
- data={"notification_urls": notification_url,
- "notification_title": "watch-notification",
- "notification_body": "watch-body",
- # No 'notification_use_default' here, so it's effectively False/off = "dont use default, use this one"
- "notification_format": "Text",
- "url": test_url,
- "tag": "my tag",
- "title": "my title",
- "headers": "",
- "fetch_backend": "html_requests"},
- follow_redirects=True
- )
- set_original_response()
-
- client.get(url_for("form_watch_checknow"), follow_redirects=True)
- time.sleep(2)
- assert os.path.isfile("test-datastore/notification.txt")
- with open("test-datastore/notification.txt", "r") as f:
- assert 'watch-notification' in f.read()
-
-
- # cleanup for the next
- client.get(
- url_for("form_delete", uuid="all"),
- follow_redirects=True
- )
\ No newline at end of file
diff --git a/changedetectionio/update_worker.py b/changedetectionio/update_worker.py
index 1617e61f..8f1c0f28 100644
--- a/changedetectionio/update_worker.py
+++ b/changedetectionio/update_worker.py
@@ -11,11 +11,14 @@ from changedetectionio.html_tools import FilterNotFoundInResponse
# Requests for checking on a single site(watch) from a queue of watches
# (another process inserts watches into the queue that are time-ready for checking)
+import logging
+import sys
class update_worker(threading.Thread):
current_uuid = None
def __init__(self, q, notification_q, app, datastore, *args, **kwargs):
+ logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)
self.q = q
self.app = app
self.notification_q = notification_q
@@ -26,6 +29,10 @@ class update_worker(threading.Thread):
from changedetectionio import diff
+ from changedetectionio.notification import (
+ default_notification_format_for_watch
+ )
+
n_object = {}
watch = self.datastore.data['watching'].get(watch_uuid, False)
if not watch:
@@ -40,33 +47,27 @@ class update_worker(threading.Thread):
"History index had 2 or more, but only 1 date loaded, timestamps were not unique? maybe two of the same timestamps got written, needs more delay?"
)
- # Did it have any notification alerts to hit?
- if not watch.get('notification_use_default') and len(watch['notification_urls']):
- print(">>> Notifications queued for UUID from watch {}".format(watch_uuid))
- n_object['notification_urls'] = watch['notification_urls']
- n_object['notification_title'] = watch['notification_title']
- n_object['notification_body'] = watch['notification_body']
- n_object['notification_format'] = watch['notification_format']
+ n_object['notification_urls'] = watch['notification_urls'] if len(watch['notification_urls']) else \
+ self.datastore.data['settings']['application']['notification_urls']
+
+ n_object['notification_title'] = watch['notification_title'] if watch['notification_title'] else \
+ self.datastore.data['settings']['application']['notification_title']
+
+ n_object['notification_body'] = watch['notification_body'] if watch['notification_body'] else \
+ self.datastore.data['settings']['application']['notification_body']
+
+ n_object['notification_format'] = watch['notification_format'] if watch['notification_format'] != default_notification_format_for_watch else \
+ self.datastore.data['settings']['application']['notification_format']
- # No? maybe theres a global setting, queue them all
- elif watch.get('notification_use_default') and len(self.datastore.data['settings']['application']['notification_urls']):
- print(">>> Watch notification URLs were empty, using GLOBAL notifications for UUID: {}".format(watch_uuid))
- n_object['notification_urls'] = self.datastore.data['settings']['application']['notification_urls']
- n_object['notification_title'] = self.datastore.data['settings']['application']['notification_title']
- n_object['notification_body'] = self.datastore.data['settings']['application']['notification_body']
- n_object['notification_format'] = self.datastore.data['settings']['application']['notification_format']
- else:
- print(">>> NO notifications queued, watch and global notification URLs were empty.")
# Only prepare to notify if the rules above matched
- if 'notification_urls' in n_object:
+ if 'notification_urls' in n_object and n_object['notification_urls']:
# HTML needs linebreak, but MarkDown and Text can use a linefeed
if n_object['notification_format'] == 'HTML':
line_feed_sep = ""
else:
line_feed_sep = "\n"
- snapshot_contents = ''
with open(watch_history[dates[-1]], 'rb') as f:
snapshot_contents = f.read()
@@ -77,8 +78,10 @@ class update_worker(threading.Thread):
'diff': diff.render_diff(watch_history[dates[-2]], watch_history[dates[-1]], line_feed_sep=line_feed_sep),
'diff_full': diff.render_diff(watch_history[dates[-2]], watch_history[dates[-1]], True, line_feed_sep=line_feed_sep)
})
-
+ logging.info (">> SENDING NOTIFICATION")
self.notification_q.put(n_object)
+ else:
+ logging.info (">> NO Notification sent, notification_url was empty in both watch and system")
def send_filter_failure_notification(self, watch_uuid):