diff --git a/changedetectionio/notification_service.py b/changedetectionio/notification_service.py index d478d56eb..356b39e05 100644 --- a/changedetectionio/notification_service.py +++ b/changedetectionio/notification_service.py @@ -61,6 +61,7 @@ class NotificationContextData(dict): super().__init__({ 'base_url': None, 'change_datetime': None, + 'change_datetime_z': None, 'current_snapshot': None, 'diff': None, 'diff_added': None, @@ -119,6 +120,16 @@ class NotificationContextData(dict): super().__setitem__(key, value) +def timestamp_to_localtime_iso8601(timestamp): + # Interpret timestamp as UTC + dt_utc = datetime.datetime.fromtimestamp(int(timestamp), tz=pytz.UTC) + + # Convert to local timezone + local_dt = dt_utc.astimezone() + + # Return ISO 8601 format + return local_dt.isoformat() + def timestamp_to_localtime(timestamp): # Format the date using locale-aware formatting with timezone # Pass tz=UTC so fromtimestamp() interprets the epoch correctly as UTC, @@ -204,6 +215,7 @@ def set_basic_notification_vars(current_snapshot, prev_snapshot, watch, triggere 'prev_snapshot': prev_snapshot, 'screenshot': watch.get_screenshot() if watch and watch.get('notification_screenshot') else None, 'change_datetime': timestamp_to_localtime(timestamp_changed) if timestamp_changed else None, + 'change_datetime_z': timestamp_to_localtime_iso8601(timestamp_changed) if timestamp_changed else None, 'triggered_text': triggered_text, 'uuid': watch.get('uuid') if watch else None, 'watch_url': watch.get('url') if watch else None, diff --git a/changedetectionio/templates/_common_fields.html b/changedetectionio/templates/_common_fields.html index b3cb8a7f1..d89955a26 100644 --- a/changedetectionio/templates/_common_fields.html +++ b/changedetectionio/templates/_common_fields.html @@ -44,6 +44,18 @@ {{ '{{preview_url}}' }} {{ _('The URL of the preview page generated by changedetection.io.') }} + + {{ '{{change_datime}}' }} + {{ _('Date/time of the change in \'%Y-%m-%d %H:%M:%S %Z\' format') }} + + + {{ '{{change_datime_z}}' }} + {{ _('Date/time of the change in ISO-8601 format') }} + + + {{ '{{diff_url}}' }} + {{ _('The URL of the diff output for the watch.') }} + {{ '{{diff_url}}' }} {{ _('The URL of the diff output for the watch.') }} diff --git a/changedetectionio/tests/test_notification.py b/changedetectionio/tests/test_notification.py index fbd80960e..f5715b472 100644 --- a/changedetectionio/tests/test_notification.py +++ b/changedetectionio/tests/test_notification.py @@ -109,6 +109,7 @@ def test_check_notification(client, live_server, measure_memory_usage, datastore "Diff Full: {{diff_full}}\n" "Diff as Patch: {{diff_patch}}\n" "Change datetime: {{change_datetime}}\n" + "Change datetime Z: {{change_datetime_z}}\n" ":-)", "notification_screenshot": True, "notification_format": 'text'} @@ -136,8 +137,6 @@ def test_check_notification(client, live_server, measure_memory_usage, datastore assert bytes(notification_url.encode('utf-8')) in res.data assert bytes("New ChangeDetection.io Notification".encode('utf-8')) in res.data - - ## Now recheck, and it should have sent the notification wait_for_all_checks(client) set_modified_response(datastore_path=datastore_path) @@ -181,11 +180,14 @@ def test_check_notification(client, live_server, measure_memory_usage, datastore # timestamp worked import time - from changedetectionio.notification_service import timestamp_to_localtime + from changedetectionio.notification_service import timestamp_to_localtime, timestamp_to_localtime_iso8601 # Could be from a few seconds ago (when the notification was fired vs in this test checking), so check for any times_possible = [timestamp_to_localtime(int(time.time()) - i) for i in range(15)] assert any(t in notification_submission for t in times_possible) + times_possible = [timestamp_to_localtime_iso8601(int(time.time()) - i) for i in range(15)] + assert any(t in notification_submission for t in times_possible) + # We keep PNG screenshots for now # IF THIS FAILS YOU SHOULD BE TESTING WITH ENV VAR REMOVE_REQUESTS_OLD_SCREENSHOTS=False