mirror of
https://github.com/dgtlmoon/changedetection.io.git
synced 2026-03-24 20:58:05 +00:00
Compare commits
1 Commits
JSONP-supp
...
multiple-g
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
62e1259750 |
@@ -6,6 +6,7 @@ Extracted from update_worker.py to provide standalone notification functionality
|
|||||||
for both sync and async workers
|
for both sync and async workers
|
||||||
"""
|
"""
|
||||||
import datetime
|
import datetime
|
||||||
|
from copy import deepcopy
|
||||||
|
|
||||||
import pytz
|
import pytz
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
@@ -352,7 +353,7 @@ class NotificationService:
|
|||||||
"""
|
"""
|
||||||
Send notification when content changes are detected
|
Send notification when content changes are detected
|
||||||
"""
|
"""
|
||||||
n_object = NotificationContextData()
|
|
||||||
watch = self.datastore.data['watching'].get(watch_uuid)
|
watch = self.datastore.data['watching'].get(watch_uuid)
|
||||||
if not watch:
|
if not watch:
|
||||||
return
|
return
|
||||||
@@ -369,21 +370,51 @@ class NotificationService:
|
|||||||
# Should be a better parent getter in the model object
|
# Should be a better parent getter in the model object
|
||||||
|
|
||||||
# Prefer - Individual watch settings > Tag settings > Global settings (in that order)
|
# Prefer - Individual watch settings > Tag settings > Global settings (in that order)
|
||||||
# this change probably not needed?
|
# If the watch has no notification_body for example, it will try to get from the first matching group or system setting
|
||||||
n_object['notification_urls'] = _check_cascading_vars(self.datastore, 'notification_urls', watch)
|
|
||||||
|
# Should be, if none in the watch, and no group tag ones found, then use system ones at the end
|
||||||
|
#n_object['notification_urls'] = _check_cascading_vars(self.datastore, 'notification_urls', watch)
|
||||||
|
n_object = NotificationContextData()
|
||||||
n_object['notification_title'] = _check_cascading_vars(self.datastore,'notification_title', watch)
|
n_object['notification_title'] = _check_cascading_vars(self.datastore,'notification_title', watch)
|
||||||
n_object['notification_body'] = _check_cascading_vars(self.datastore,'notification_body', watch)
|
n_object['notification_body'] = _check_cascading_vars(self.datastore,'notification_body', watch)
|
||||||
n_object['notification_format'] = _check_cascading_vars(self.datastore,'notification_format', watch)
|
n_object['notification_format'] = _check_cascading_vars(self.datastore,'notification_format', watch)
|
||||||
|
|
||||||
|
notification_objects = []
|
||||||
|
if n_object.get('notification_urls'):
|
||||||
|
notification_objects.append(n_object)
|
||||||
|
|
||||||
|
|
||||||
|
# LOGIC SHOULD BE something that all tests currently pass too
|
||||||
|
# !!! _check_cascading_vars is not really used much, only used here..
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
|
# If any related group/tag has a notification_url set, then we fan out horizontally and collect it as extra notifications
|
||||||
|
tags = self.datastore.get_all_tags_for_watch(uuid=watch.get('uuid'))
|
||||||
|
logger.debug(f'{len(tags)} related to this watch')
|
||||||
|
if tags:
|
||||||
|
for tag_uuid, tag in tags.items():
|
||||||
|
logger.debug(f"Checking group/tag for notification URLs '{tag['title']}' Muted? '{tag.get('notification_muted')}', URLs {tag.get('notification_urls')}")
|
||||||
|
v = tag.get('notification_urls')
|
||||||
|
if v and not tag.get('notification_muted'):
|
||||||
|
logger.debug("OK MAN")
|
||||||
|
next_n_object = deepcopy(n_object)
|
||||||
|
next_n_object['notification_urls'] = v
|
||||||
|
next_n_object['notification_title'] = _check_cascading_vars(self.datastore, 'notification_title', watch)
|
||||||
|
next_n_object['notification_body'] = _check_cascading_vars(self.datastore, 'notification_body', watch)
|
||||||
|
next_n_object['notification_format'] = _check_cascading_vars(self.datastore, 'notification_format', watch)
|
||||||
|
notification_objects.append(next_n_object)
|
||||||
|
logger.debug(f"Adding notification from group/tag {tag['title']}")
|
||||||
|
|
||||||
|
|
||||||
# (Individual watch) Only prepare to notify if the rules above matched
|
# (Individual watch) Only prepare to notify if the rules above matched
|
||||||
queued = False
|
queued = False
|
||||||
if n_object and n_object.get('notification_urls'):
|
if notification_objects:
|
||||||
queued = True
|
queued = True
|
||||||
|
|
||||||
count = watch.get('notification_alert_count', 0) + 1
|
count = watch.get('notification_alert_count', 0) + 1
|
||||||
self.datastore.update_watch(uuid=watch_uuid, update_obj={'notification_alert_count': count})
|
self.datastore.update_watch(uuid=watch_uuid, update_obj={'notification_alert_count': count})
|
||||||
|
for n_object in notification_objects:
|
||||||
self.queue_notification_for_watch(n_object=n_object, watch=watch)
|
self.queue_notification_for_watch(n_object=n_object, watch=watch)
|
||||||
|
|
||||||
return queued
|
return queued
|
||||||
|
|
||||||
|
|||||||
@@ -171,6 +171,7 @@ def test_group_tag_notification(client, live_server, measure_memory_usage, datas
|
|||||||
delete_all_watches(client)
|
delete_all_watches(client)
|
||||||
|
|
||||||
set_original_response(datastore_path=datastore_path)
|
set_original_response(datastore_path=datastore_path)
|
||||||
|
notification_url_endpoint = url_for('test_notification_endpoint', _external=True).replace('http', 'post')
|
||||||
|
|
||||||
test_url = url_for('test_endpoint', _external=True)
|
test_url = url_for('test_endpoint', _external=True)
|
||||||
res = client.post(
|
res = client.post(
|
||||||
@@ -181,35 +182,50 @@ def test_group_tag_notification(client, live_server, measure_memory_usage, datas
|
|||||||
|
|
||||||
assert b"Watch added" in res.data
|
assert b"Watch added" in res.data
|
||||||
|
|
||||||
notification_url = url_for('test_notification_endpoint', _external=True).replace('http', 'json')
|
client.get(url_for("ui.form_watch_checknow"), follow_redirects=True)
|
||||||
notification_form_data = {"notification_urls": notification_url,
|
wait_for_all_checks(client)
|
||||||
"notification_title": "New GROUP TAG ChangeDetection.io Notification - {{watch_url}}",
|
|
||||||
"notification_body": "BASE URL: {{base_url}}\n"
|
|
||||||
"Watch URL: {{watch_url}}\n"
|
|
||||||
"Watch UUID: {{watch_uuid}}\n"
|
|
||||||
"Watch title: {{watch_title}}\n"
|
|
||||||
"Watch tag: {{watch_tag}}\n"
|
|
||||||
"Preview: {{preview_url}}\n"
|
|
||||||
"Diff URL: {{diff_url}}\n"
|
|
||||||
"Snapshot: {{current_snapshot}}\n"
|
|
||||||
"Diff: {{diff}}\n"
|
|
||||||
"Diff Added: {{diff_added}}\n"
|
|
||||||
"Diff Removed: {{diff_removed}}\n"
|
|
||||||
"Diff Full: {{diff_full}}\n"
|
|
||||||
"Diff as Patch: {{diff_patch}}\n"
|
|
||||||
":-)",
|
|
||||||
"notification_screenshot": True,
|
|
||||||
"notification_format": 'text',
|
|
||||||
"title": "test-tag"}
|
|
||||||
|
|
||||||
|
group_tag_form_data = {
|
||||||
|
"notification_title": "New GROUP TAG ChangeDetection.io Notification - {{watch_url}}",
|
||||||
|
"notification_body": "BASE URL: {{base_url}}\n"
|
||||||
|
"Watch URL: {{watch_url}}\n"
|
||||||
|
"Watch UUID: {{watch_uuid}}\n"
|
||||||
|
"Watch title: {{watch_title}}\n"
|
||||||
|
"Watch tag: {{watch_tag}}\n"
|
||||||
|
"Preview: {{preview_url}}\n"
|
||||||
|
"Diff URL: {{diff_url}}\n"
|
||||||
|
"Snapshot: {{current_snapshot}}\n"
|
||||||
|
"Diff: {{diff}}\n"
|
||||||
|
"Diff Added: {{diff_added}}\n"
|
||||||
|
"Diff Removed: {{diff_removed}}\n"
|
||||||
|
"Diff Full: {{diff_full}}\n"
|
||||||
|
"Diff as Patch: {{diff_patch}}\n"
|
||||||
|
":-)",
|
||||||
|
"notification_screenshot": True,
|
||||||
|
"notification_format": 'text',
|
||||||
|
}
|
||||||
|
|
||||||
|
# Setup for test-tag
|
||||||
|
group_tag_form_data['notification_urls'] = notification_url_endpoint+"?outputfilename=test-tag.txt"
|
||||||
|
group_tag_form_data['title'] = 'test-tag'
|
||||||
res = client.post(
|
res = client.post(
|
||||||
url_for("tags.form_tag_edit_submit", uuid=get_UUID_for_tag_name(client, name="test-tag")),
|
url_for("tags.form_tag_edit_submit", uuid=get_UUID_for_tag_name(client, name="test-tag")),
|
||||||
data=notification_form_data,
|
data=group_tag_form_data,
|
||||||
|
follow_redirects=True
|
||||||
|
)
|
||||||
|
assert b"Updated" in res.data
|
||||||
|
|
||||||
|
# Setup for other-tag, we only add notifications-urls
|
||||||
|
group_tag_form_data['notification_urls'] = notification_url_endpoint+"?outputfilename=other-tag.txt"
|
||||||
|
group_tag_form_data['title'] = 'other-tag'
|
||||||
|
|
||||||
|
res = client.post(
|
||||||
|
url_for("tags.form_tag_edit_submit", uuid=get_UUID_for_tag_name(client, name="other-tag")),
|
||||||
|
data=group_tag_form_data,
|
||||||
follow_redirects=True
|
follow_redirects=True
|
||||||
)
|
)
|
||||||
assert b"Updated" in res.data
|
assert b"Updated" in res.data
|
||||||
|
|
||||||
wait_for_all_checks(client)
|
|
||||||
|
|
||||||
set_modified_response(datastore_path=datastore_path)
|
set_modified_response(datastore_path=datastore_path)
|
||||||
client.get(url_for("ui.form_watch_checknow"), follow_redirects=True)
|
client.get(url_for("ui.form_watch_checknow"), follow_redirects=True)
|
||||||
@@ -217,12 +233,14 @@ def test_group_tag_notification(client, live_server, measure_memory_usage, datas
|
|||||||
|
|
||||||
time.sleep(3)
|
time.sleep(3)
|
||||||
|
|
||||||
assert os.path.isfile(os.path.join(datastore_path, "notification.txt"))
|
assert os.path.isfile(os.path.join(datastore_path, "test-tag.txt"))
|
||||||
|
assert os.path.isfile(os.path.join(datastore_path, "other-tag.txt"))
|
||||||
|
|
||||||
|
# @todo assert the group name or other unique body is in other-tag.txt
|
||||||
# Verify what was sent as a notification, this file should exist
|
# Verify what was sent as a notification, this file should exist
|
||||||
with open(os.path.join(datastore_path, "notification.txt"), "r") as f:
|
with open(os.path.join(datastore_path, "test-tag.txt"), "r") as f:
|
||||||
notification_submission = f.read()
|
notification_submission = f.read()
|
||||||
os.unlink(os.path.join(datastore_path, "notification.txt"))
|
os.unlink(os.path.join(datastore_path, "test-tag.txt"))
|
||||||
|
|
||||||
# Did we see the URL that had a change, in the notification?
|
# Did we see the URL that had a change, in the notification?
|
||||||
# Diff was correctly executed
|
# Diff was correctly executed
|
||||||
|
|||||||
@@ -343,8 +343,11 @@ def new_live_server_setup(live_server):
|
|||||||
@live_server.app.route('/test_notification_endpoint', methods=['POST', 'GET'])
|
@live_server.app.route('/test_notification_endpoint', methods=['POST', 'GET'])
|
||||||
def test_notification_endpoint():
|
def test_notification_endpoint():
|
||||||
datastore_path = current_app.config.get('TEST_DATASTORE_PATH', 'test-datastore')
|
datastore_path = current_app.config.get('TEST_DATASTORE_PATH', 'test-datastore')
|
||||||
|
from loguru import logger
|
||||||
with open(os.path.join(datastore_path, "notification.txt"), "wb") as f:
|
# @todo make safe
|
||||||
|
fname = request.args.get('outputfilename', "notification.txt")
|
||||||
|
logger.debug(f"Writing test notification endpoint data to '{fname}' - {request.args}")
|
||||||
|
with open(os.path.join(datastore_path, fname), "wb") as f:
|
||||||
# Debug method, dump all POST to file also, used to prove #65
|
# Debug method, dump all POST to file also, used to prove #65
|
||||||
data = request.stream.read()
|
data = request.stream.read()
|
||||||
if data != None:
|
if data != None:
|
||||||
|
|||||||
Reference in New Issue
Block a user