diff --git a/changedetectionio/blueprint/settings/templates/settings.html b/changedetectionio/blueprint/settings/templates/settings.html
index 096d7a3c..a6114830 100644
--- a/changedetectionio/blueprint/settings/templates/settings.html
+++ b/changedetectionio/blueprint/settings/templates/settings.html
@@ -44,10 +44,6 @@
-
- {{ render_field(form.requests.form.jitter_seconds, class="jitter_seconds") }}
- Example - 3 seconds random jitter could trigger up to 3 seconds earlier or up to 3 seconds later
-
{{ render_field(form.application.form.filter_failure_notification_threshold_attempts, class="filter_failure_notification_threshold_attempts") }}
After this many consecutive times that the CSS/xPath filter is missing, send a notification
@@ -134,6 +130,10 @@
Number of concurrent workers to process watches. More workers = faster processing but higher memory usage.
Currently running: {{ worker_info.count }} operational {{ worker_info.type }} workers{% if worker_info.active_workers > 0 %} ({{ worker_info.active_workers }} actively processing){% endif %}.
+
+ {{ render_field(form.requests.form.jitter_seconds, class="jitter_seconds") }}
+ Example - 3 seconds random jitter could trigger up to 3 seconds earlier or up to 3 seconds later
+
{{ render_field(form.requests.form.default_ua) }}
diff --git a/changedetectionio/blueprint/ui/notification.py b/changedetectionio/blueprint/ui/notification.py
index 2d6bf6bd..9299d60f 100644
--- a/changedetectionio/blueprint/ui/notification.py
+++ b/changedetectionio/blueprint/ui/notification.py
@@ -79,6 +79,7 @@ def construct_blueprint(datastore: ChangeDetectionStore):
if not notification_urls:
logger.debug("Test notification - Trying by group/tag in the edit form if available")
+ # @todo this logic is not clear, omegaconf?
# On an edit page, we should also fire off to the tags if they have notifications
if request.form.get('tags') and request.form['tags'].strip():
for k in request.form['tags'].split(','):
@@ -92,7 +93,7 @@ def construct_blueprint(datastore: ChangeDetectionStore):
notification_urls = datastore.data['settings']['application']['notification_urls']
if not notification_urls:
- return 'Error: No Notification URLs set/found'
+ return make_response("Error: No Notification URLs set/found.", 400)
for n_url in notification_urls:
if len(n_url.strip()):
diff --git a/changedetectionio/notification/handler.py b/changedetectionio/notification/handler.py
index 54049ff2..7b972943 100644
--- a/changedetectionio/notification/handler.py
+++ b/changedetectionio/notification/handler.py
@@ -35,7 +35,11 @@ def _populate_notification_tokens(n_object, datastore):
# Add text that was triggered
if len(dates):
- snapshot_contents = str(escape(watch.get_history_snapshot(dates[-1])))
+ snapshot_contents = watch.get_history_snapshot(dates[-1])
+
+ if n_object.get('notification_format').lower().startswith('html'):
+ snapshot_contents = str(escape(snapshot_contents))
+
else:
snapshot_contents = "No snapshot/history available, the watch should fetch atleast once."
@@ -44,18 +48,15 @@ def _populate_notification_tokens(n_object, datastore):
n_object['notification_format'] = datastore.data['settings']['application'].get('notification_format')
html_colour_enable = False
+ line_feed_sep = "\n"
+
# HTML needs linebreak, but MarkDown and Text can use a linefeed
- if n_object.get('notification_format') == 'HTML':
- line_feed_sep = "
"
- # Snapshot will be plaintext on the disk, convert to some kind of HTML
- snapshot_contents = snapshot_contents.replace('\n', line_feed_sep)
- elif n_object.get('notification_format') == 'HTML Color':
+ if n_object.get('notification_format').lower().startswith('html'):
line_feed_sep = "
"
# Snapshot will be plaintext on the disk, convert to some kind of HTML
snapshot_contents = snapshot_contents.replace('\n', line_feed_sep)
+ if n_object.get('notification_format') == 'HTML Color':
html_colour_enable = True
- else:
- line_feed_sep = "\n"
triggered_text = ''
if len(trigger_text):
@@ -69,8 +70,12 @@ def _populate_notification_tokens(n_object, datastore):
current_snapshot = "Example text: example test\nExample text: More than 1 watch change needs to exist to build a nice preview!"
if len(dates) > 1:
- prev_snapshot = str(escape(watch.get_history_snapshot(dates[-2])))
- current_snapshot = str(escape(watch.get_history_snapshot(dates[-1])))
+ prev_snapshot = watch.get_history_snapshot(dates[-2])
+ current_snapshot = watch.get_history_snapshot(dates[-1])
+ if n_object.get('notification_format').lower().startswith('html'):
+ prev_snapshot = str(escape(prev_snapshot))
+ current_snapshot = str(escape(current_snapshot))
+
if watch:
v = {'url': watch.get('url'), 'label': watch.label}
@@ -182,8 +187,10 @@ def process_notification(n_object, datastore):
# Get the notification body from datastore
n_body = jinja_render(template_str=n_object.get('notification_body', ''), **notification_parameters)
+ # hmm unsure about this, but why not
if n_object.get('notification_format', '').startswith('HTML'):
n_body = n_body.replace("\n", '
')
+
n_title = jinja_render(template_str=n_object.get('notification_title', ''), **notification_parameters)
n_body_from_file_template = scan_notification_file_templates(url=url,
@@ -238,7 +245,7 @@ def process_notification(n_object, datastore):
# Apprise will default to HTML, so we need to override it
# So that whats' generated in n_body is in line with what is going to be sent.
# https://github.com/caronc/apprise/issues/633#issuecomment-1191449321
- if not 'format=' in url and (n_format == 'Text' or n_format == 'Markdown'):
+ if not 'format=' in url and (n_format.lower() == 'text' or n_format.lower() == 'markdown'):
prefix = '?' if not '?' in url else '&'
# Apprise format is lowercase text https://github.com/caronc/apprise/issues/633
n_format = n_format.lower()
diff --git a/changedetectionio/static/js/notifications.js b/changedetectionio/static/js/notifications.js
index 9ea8ac0a..61064ccc 100644
--- a/changedetectionio/static/js/notifications.js
+++ b/changedetectionio/static/js/notifications.js
@@ -50,6 +50,8 @@ $(document).ready(function () {
function setPreview(data) {
const iframe = document.getElementById("notification-iframe");
const isDark = document.documentElement.getAttribute('data-darkmode') === 'true';
+ const isTextFormat = $('select.notification-format').val() === 'Text';
+
$('#notification-preview-title-text').text(data['title']);
iframe.srcdoc = `
@@ -76,9 +78,15 @@ $(document).ready(function () {
color: var(--color-text);
padding: 5px;
}
+ body.text-format {
+ font-family: monospace;
+ white-space: pre;
+ overflow-wrap: normal;
+ overflow-x: auto;
+ }
- ${data['body']}
+ ${data['body']}