From 0d05ee1586e6385fccf586dfcf714a7df8395df4 Mon Sep 17 00:00:00 2001 From: reecespieces Date: Sun, 12 Mar 2023 15:21:47 +0000 Subject: [PATCH] Notification Improvements - New tokens `{{diff_added}}` and `{{diff_removed}}`, removed whitespace around `added` and `into` ( Issue #905 ) (#1454) --- changedetectionio/diff.py | 14 ++++---- changedetectionio/notification.py | 4 +++ .../templates/_common_fields.jinja | 36 +++++++++++++------ changedetectionio/tests/test_backend.py | 2 +- changedetectionio/tests/test_notification.py | 4 ++- .../tests/unit/test_notification_diff.py | 21 +++++++++-- changedetectionio/update_worker.py | 4 ++- 7 files changed, 61 insertions(+), 24 deletions(-) diff --git a/changedetectionio/diff.py b/changedetectionio/diff.py index 61ab5c5b..a7215a1b 100644 --- a/changedetectionio/diff.py +++ b/changedetectionio/diff.py @@ -10,7 +10,7 @@ def same_slicer(l, a, b): return l[a:b] # like .compare but a little different output -def customSequenceMatcher(before, after, include_equal=False): +def customSequenceMatcher(before, after, include_equal=False, include_removed=True, include_added=True): cruncher = difflib.SequenceMatcher(isjunk=lambda x: x in " \\t", a=before, b=after) # @todo Line-by-line mode instead of buncghed, including `after` that is not in `before` (maybe unset?) @@ -18,20 +18,20 @@ def customSequenceMatcher(before, after, include_equal=False): if include_equal and tag == 'equal': g = before[alo:ahi] yield g - elif tag == 'delete': + elif include_removed and tag == 'delete': g = ["(removed) " + i for i in same_slicer(before, alo, ahi)] yield g elif tag == 'replace': g = ["(changed) " + i for i in same_slicer(before, alo, ahi)] - g += ["(into ) " + i for i in same_slicer(after, blo, bhi)] + g += ["(into) " + i for i in same_slicer(after, blo, bhi)] yield g - elif tag == 'insert': - g = ["(added ) " + i for i in same_slicer(after, blo, bhi)] + elif include_added and tag == 'insert': + g = ["(added) " + i for i in same_slicer(after, blo, bhi)] yield g # only_differences - only return info about the differences, no context # line_feed_sep could be "
" or "
  • " or "\n" etc -def render_diff(previous_file, newest_file, include_equal=False, line_feed_sep="\n"): +def render_diff(previous_file, newest_file, include_equal=False, include_removed=True, include_added=True, line_feed_sep="\n"): with open(newest_file, 'r') as f: newest_version_file_contents = f.read() newest_version_file_contents = [line.rstrip() for line in newest_version_file_contents.splitlines()] @@ -45,7 +45,7 @@ def render_diff(previous_file, newest_file, include_equal=False, line_feed_sep=" rendered_diff = customSequenceMatcher(previous_version_file_contents, newest_version_file_contents, - include_equal) + include_equal, include_removed, include_added) # Recursively join lists f = lambda L: line_feed_sep.join([f(x) if type(x) is list else x for x in L]) diff --git a/changedetectionio/notification.py b/changedetectionio/notification.py index 492cdef8..4b4020e2 100644 --- a/changedetectionio/notification.py +++ b/changedetectionio/notification.py @@ -10,6 +10,8 @@ valid_tokens = { 'watch_title': '', 'watch_tag': '', 'diff': '', + 'diff_added': '', + 'diff_removed': '', 'diff_full': '', 'diff_url': '', 'preview_url': '', @@ -215,6 +217,8 @@ def create_notification_parameters(n_object, datastore): 'watch_tag': watch_tag if watch_tag is not None else '', 'diff_url': diff_url, 'diff': n_object.get('diff', ''), # Null default in the case we use a test + 'diff_added': n_object.get('diff_added', ''), # Null default in the case we use a test + 'diff_removed': n_object.get('diff_removed', ''), # Null default in the case we use a test 'diff_full': n_object.get('diff_full', ''), # Null default in the case we use a test 'preview_url': preview_url, 'current_snapshot': n_object['current_snapshot'] if 'current_snapshot' in n_object else '' diff --git a/changedetectionio/templates/_common_fields.jinja b/changedetectionio/templates/_common_fields.jinja index 893b7774..4faef297 100644 --- a/changedetectionio/templates/_common_fields.jinja +++ b/changedetectionio/templates/_common_fields.jinja @@ -55,39 +55,51 @@ - {{ '{{ base_url }}' }} + {{ '{{base_url}}' }} The URL of the changedetection.io instance you are running. - {{ '{{ watch_url }}' }} + {{ '{{watch_url}}' }} The URL being watched. - {{ '{{ watch_uuid }}' }} + {{ '{{watch_uuid}}' }} The UUID of the watch. - {{ '{{ watch_title }}' }} + {{ '{{watch_title}}' }} The title of the watch. - {{ '{{ watch_tag }}' }} + {{ '{{watch_tag}}' }} The watch label / tag - {{ '{{ preview_url }}' }} + {{ '{{preview_url}}' }} The URL of the preview page generated by changedetection.io. - {{ '{{ diff_url }}' }} - The diff output - differences only + {{ '{{diff_url}}' }} + The URL of the diff output for the watch. + + + {{ '{{diff}}' }} + The diff output - only changes, additions, and removals + + + {{ '{{diff_added}}' }} + The diff output - only changes and additions + + + {{ '{{diff_removed}}' }} + The diff output - only changes and removals - {{ '{{ diff_full }}' }} + {{ '{{diff_full}}' }} The diff output - full difference output - {{ '{{ current_snapshot }}' }} + {{ '{{current_snapshot}}' }} The current snapshot value, useful when combined with JSON or CSS filters @@ -95,8 +107,10 @@

    - URLs generated by changedetection.io (such as {{ '{{ diff_url }}' }}) require the BASE_URL environment variable set.
    + URLs generated by changedetection.io (such as {{ '{{diff_url}}' }}) require the BASE_URL environment variable set.
    Your BASE_URL var is currently "{{settings_application['current_base_url']}}" +
    + Warning: Contents of {{ '{{diff}}' }}, {{ '{{diff_removed}}' }}, and {{ '{{diff_added}}' }} depend on how the difference algorithm perceives the change. For example, an addition or removal could be perceived as a change in some cases. More Here
    diff --git a/changedetectionio/tests/test_backend.py b/changedetectionio/tests/test_backend.py index 06fd10dd..73420434 100644 --- a/changedetectionio/tests/test_backend.py +++ b/changedetectionio/tests/test_backend.py @@ -82,7 +82,7 @@ def test_check_basic_change_detection_functionality(client, live_server): assert b'> SENDING NOTIFICATION") self.notification_q.put(n_object)