Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 3 additions & 10 deletions changedetectionio/api/Watch.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from . import validate_openapi_request, get_readonly_watch_fields
from ..notification import valid_notification_formats
from ..notification.handler import newline_re
from ..processors.text_json_diff.difference import DIFF_PREFERENCES_CONFIG, parse_diff_preferences


def validate_time_between_check_required(json_data):
Expand Down Expand Up @@ -338,22 +339,14 @@ def get(self, uuid, from_timestamp, to_timestamp):
word_diff = True

# Get boolean diff preferences with defaults from DIFF_PREFERENCES_CONFIG
changes_only = strtobool(request.args.get('changesOnly', 'true'))
ignore_whitespace = strtobool(request.args.get('ignoreWhitespace', 'false'))
include_removed = strtobool(request.args.get('removed', 'true'))
include_added = strtobool(request.args.get('added', 'true'))
include_replaced = strtobool(request.args.get('replaced', 'true'))
prefs, render_kwargs = parse_diff_preferences(request.args)

# Generate the diff with all preferences
content = diff.render_diff(
previous_version_file_contents=from_version_file_contents,
newest_version_file_contents=to_version_file_contents,
ignore_junk=ignore_whitespace,
include_equal=changes_only,
include_removed=include_removed,
include_added=include_added,
include_replaced=include_replaced,
word_diff=word_diff,
**render_kwargs,
)

# Skip formatting if no_markup is set
Expand Down
42 changes: 22 additions & 20 deletions changedetectionio/processors/text_json_diff/difference.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,26 @@ def build_diff_cell_visualizer(content, resolution=100):
'type': {'default': 'diffLines', 'type': 'value'},
}

def parse_diff_preferences(args, checkbox_mode=False):
parsed = {}
render_kwargs = {}

for query_name, config in DIFF_PREFERENCES_CONFIG.items():
value = args.get(query_name, config['default'])

if config['type'] == 'bool':
if checkbox_mode:
value = strtobool(args.get(query_name, 'off'))
else:
value = strtobool(value)

parsed[query_name] = value

if 'render_arg' in config:
render_kwargs[config['render_arg']] = value

return parsed, render_kwargs

def render(watch, datastore, request, url_for, render_template, flash, redirect, extract_form=None):
"""
Render the history/diff view for text/JSON/HTML changes.
Expand Down Expand Up @@ -166,30 +186,12 @@ def render(watch, datastore, request, url_for, render_template, flash, redirect,

datastore.set_last_viewed(uuid, time.time())

# Parse diff preferences from request using config as single source of truth
# Check if this is a user submission (any diff pref param exists in query string)
user_submitted = any(key in request.args for key in DIFF_PREFERENCES_CONFIG.keys())

diff_prefs = {}
for key, config in DIFF_PREFERENCES_CONFIG.items():
if user_submitted:
# User submitted form - missing checkboxes are explicitly OFF
if config['type'] == 'bool':
diff_prefs[key] = strtobool(request.args.get(key, 'off'))
else:
diff_prefs[key] = request.args.get(key, config['default'])
else:
# Initial load - use defaults from config
diff_prefs[key] = config['default']
diff_prefs, render_kwargs = parse_diff_preferences(request.args)

content = diff.render_diff(previous_version_file_contents=from_version_file_contents,
newest_version_file_contents=to_version_file_contents,
include_replaced=diff_prefs['replaced'],
include_added=diff_prefs['added'],
include_removed=diff_prefs['removed'],
include_equal=diff_prefs['changesOnly'],
ignore_junk=diff_prefs['ignoreWhitespace'],
word_diff=diff_prefs['type'] == 'diffWords',
**render_kwargs,
)

# Build cell grid visualizer before applying HTML color (so we can detect placemarkers)
Expand Down
Loading