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
4 changes: 4 additions & 0 deletions changedetectionio/blueprint/ui/templates/edit.html
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,10 @@ <h3>{{ _('Text filtering') }}</h3>
{{ render_checkbox_field(form.remove_duplicate_lines) }}
<span class="pure-form-message-inline">{{ _('Remove duplicate lines of text') }}</span>
</fieldset>
<fieldset class="pure-control-group">
{{ render_checkbox_field(form.sort_keys_alphabetically) }}
<span class="pure-form-message-inline">{{ _('Helps reduce changes detected caused by inconsistent JSON formatting') }}</span>
</fieldset>
<fieldset class="pure-control-group">
{{ render_checkbox_field(form.sort_text_alphabetically) }}
<span class="pure-form-message-inline">{{ _('Helps reduce changes detected caused by sites shuffling lines around, combine with') }} <i>{{ _('check unique lines') }}</i> {{ _('below.') }}</span>
Expand Down
1 change: 1 addition & 0 deletions changedetectionio/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -811,6 +811,7 @@ class processor_text_json_diff_form(commonSettingsForm):
ignore_status_codes = BooleanField(_l('Ignore status codes (process non-2xx status codes as normal)'), default=False)
check_unique_lines = BooleanField(_l('Only trigger when unique lines appear in all history'), default=False)
remove_duplicate_lines = BooleanField(_l('Remove duplicate lines of text'), default=False)
sort_keys_alphabetically = BooleanField(_l('Sort JSON keys alphabetically'), default=False)
sort_text_alphabetically = BooleanField(_l('Sort text alphabetically'), default=False)
strip_ignored_lines = TernaryNoneBooleanField(_l('Strip ignored lines'), default=None)
trim_text_whitespace = BooleanField(_l('Trim whitespace before and after text'), default=False)
Expand Down
1 change: 1 addition & 0 deletions changedetectionio/model/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ def __init__(self, *arg, **kw):
'price_change_threshold_percent': None,
'proxy': None, # Preferred proxy connection
'remote_server_reply': None, # From 'server' reply header
'sort_keys_alphabetically': False,
'sort_text_alphabetically': False,
'strip_ignored_lines': None,
'subtractive_selectors': [],
Expand Down
48 changes: 46 additions & 2 deletions changedetectionio/processors/text_json_diff/processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,15 @@ def _(x): return x

JSON_FILTER_PREFIXES = ['json:', 'jq:', 'jqraw:']


def sort_json_keys(value):
"""Recursively sort JSON object keys while preserving array order."""
if isinstance(value, dict):
return {key: sort_json_keys(value[key]) for key in sorted(value.keys())}
if isinstance(value, list):
return [sort_json_keys(item) for item in value]
return value

# Assume it's this type if the server says nothing on content-type
DEFAULT_WHEN_NO_CONTENT_TYPE_HEADER = 'text/html'

Expand Down Expand Up @@ -122,6 +131,32 @@ def trim_whitespace(text):
# Use generator expression to avoid building intermediate list
return '\n'.join(line.strip() for line in text.replace("\n\n", "\n").splitlines())

@staticmethod
def format_json_output_if_possible(text):
"""Pretty-print JSON if the entire text is valid JSON."""
try:
parsed = json.loads(text)
except Exception:
return text

try:
return json.dumps(parsed, indent=2, ensure_ascii=False)
except Exception:
return text

@staticmethod
def sort_json_keys_if_possible(text, indent=2):
"""Sort JSON object keys recursively if the entire text is valid JSON."""
try:
parsed = json.loads(text)
except Exception:
return text

try:
return json.dumps(sort_json_keys(parsed), indent=indent, ensure_ascii=False)
except Exception:
return text

@staticmethod
def remove_duplicate_lines(text):
"""Remove duplicate lines while preserving order."""
Expand Down Expand Up @@ -282,9 +317,12 @@ def preprocess_json(self, raw_content):
# Then we re-format it, else it does have filters (later on) which will reformat it anyway
content = html_tools.extract_json_as_string(content=raw_content, json_filter="json:$")

# Sort JSON to avoid false alerts from reordering
# Format JSON, optionally sorting keys to avoid false alerts from reordering
try:
content = json.dumps(json.loads(content), sort_keys=True, indent=2, ensure_ascii=False)
parsed = json.loads(content)
if self.watch.get('sort_keys_alphabetically'):
parsed = sort_json_keys(parsed)
content = json.dumps(parsed, indent=2, ensure_ascii=False)
except Exception:
# Might be malformed JSON, continue anyway
pass
Expand Down Expand Up @@ -457,6 +495,12 @@ def run_changedetection(self, watch):
stripped_text = html_content

# === TEXT TRANSFORMATIONS ===
# If JSON/jq filters are used on embedded JSON, reformat output JSON before any text filtering/transformations
if filter_config.has_include_json_filters:
stripped_text = transformer.format_json_output_if_possible(stripped_text)
if watch.get('sort_keys_alphabetically'):
stripped_text = transformer.sort_json_keys_if_possible(stripped_text)

if watch.get('trim_text_whitespace'):
stripped_text = transformer.trim_whitespace(stripped_text)

Expand Down
4 changes: 4 additions & 0 deletions changedetectionio/translations/cs/LC_MESSAGES/messages.po
Original file line number Diff line number Diff line change
Expand Up @@ -1404,6 +1404,10 @@ msgid ""
"lines against all history for this watch."
msgstr ""

#: changedetectionio/blueprint/ui/templates/edit.html
msgid "Helps reduce changes detected caused by inconsistent JSON formatting"
msgstr ""

#: changedetectionio/blueprint/ui/templates/edit.html
msgid "Helps reduce changes detected caused by sites shuffling lines around, combine with"
msgstr ""
Expand Down
4 changes: 4 additions & 0 deletions changedetectionio/translations/de/LC_MESSAGES/messages.po
Original file line number Diff line number Diff line change
Expand Up @@ -1436,6 +1436,10 @@ msgstr ""
"Gut geeignet für Websites, auf denen nur Inhalte verschoben werden und Sie wissen möchten, wann NEUE Inhalte "
"hinzugefügt werden. Vergleicht neue Zeilen mit dem gesamten Verlauf dieser Überwachung."

#: changedetectionio/blueprint/ui/templates/edit.html
msgid "Helps reduce changes detected caused by inconsistent JSON formatting"
msgstr ""

#: changedetectionio/blueprint/ui/templates/edit.html
msgid "Helps reduce changes detected caused by sites shuffling lines around, combine with"
msgstr ""
Expand Down
4 changes: 4 additions & 0 deletions changedetectionio/translations/en_GB/LC_MESSAGES/messages.po
Original file line number Diff line number Diff line change
Expand Up @@ -1400,6 +1400,10 @@ msgid ""
"lines against all history for this watch."
msgstr ""

#: changedetectionio/blueprint/ui/templates/edit.html
msgid "Helps reduce changes detected caused by inconsistent JSON formatting"
msgstr ""

#: changedetectionio/blueprint/ui/templates/edit.html
msgid "Helps reduce changes detected caused by sites shuffling lines around, combine with"
msgstr ""
Expand Down
4 changes: 4 additions & 0 deletions changedetectionio/translations/en_US/LC_MESSAGES/messages.po
Original file line number Diff line number Diff line change
Expand Up @@ -1400,6 +1400,10 @@ msgid ""
"lines against all history for this watch."
msgstr ""

#: changedetectionio/blueprint/ui/templates/edit.html
msgid "Helps reduce changes detected caused by inconsistent JSON formatting"
msgstr ""

#: changedetectionio/blueprint/ui/templates/edit.html
msgid "Helps reduce changes detected caused by sites shuffling lines around, combine with"
msgstr ""
Expand Down
4 changes: 4 additions & 0 deletions changedetectionio/translations/fr/LC_MESSAGES/messages.po
Original file line number Diff line number Diff line change
Expand Up @@ -1406,6 +1406,10 @@ msgid ""
"lines against all history for this watch."
msgstr ""

#: changedetectionio/blueprint/ui/templates/edit.html
msgid "Helps reduce changes detected caused by inconsistent JSON formatting"
msgstr ""

#: changedetectionio/blueprint/ui/templates/edit.html
msgid "Helps reduce changes detected caused by sites shuffling lines around, combine with"
msgstr ""
Expand Down
4 changes: 4 additions & 0 deletions changedetectionio/translations/it/LC_MESSAGES/messages.po
Original file line number Diff line number Diff line change
Expand Up @@ -1402,6 +1402,10 @@ msgid ""
"lines against all history for this watch."
msgstr ""

#: changedetectionio/blueprint/ui/templates/edit.html
msgid "Helps reduce changes detected caused by inconsistent JSON formatting"
msgstr ""

#: changedetectionio/blueprint/ui/templates/edit.html
msgid "Helps reduce changes detected caused by sites shuffling lines around, combine with"
msgstr ""
Expand Down
4 changes: 4 additions & 0 deletions changedetectionio/translations/ko/LC_MESSAGES/messages.po
Original file line number Diff line number Diff line change
Expand Up @@ -1400,6 +1400,10 @@ msgid ""
"lines against all history for this watch."
msgstr ""

#: changedetectionio/blueprint/ui/templates/edit.html
msgid "Helps reduce changes detected caused by inconsistent JSON formatting"
msgstr ""

#: changedetectionio/blueprint/ui/templates/edit.html
msgid "Helps reduce changes detected caused by sites shuffling lines around, combine with"
msgstr ""
Expand Down
4 changes: 4 additions & 0 deletions changedetectionio/translations/messages.pot
Original file line number Diff line number Diff line change
Expand Up @@ -1399,6 +1399,10 @@ msgid ""
"lines against all history for this watch."
msgstr ""

#: changedetectionio/blueprint/ui/templates/edit.html
msgid "Helps reduce changes detected caused by inconsistent JSON formatting"
msgstr ""

#: changedetectionio/blueprint/ui/templates/edit.html
msgid "Helps reduce changes detected caused by sites shuffling lines around, combine with"
msgstr ""
Expand Down
4 changes: 4 additions & 0 deletions changedetectionio/translations/zh/LC_MESSAGES/messages.po
Original file line number Diff line number Diff line change
Expand Up @@ -1400,6 +1400,10 @@ msgid ""
"lines against all history for this watch."
msgstr "适合仅移动内容的网站,想知道新增内容时使用,会将新行与该监控项的全部历史进行比对。"

#: changedetectionio/blueprint/ui/templates/edit.html
msgid "Helps reduce changes detected caused by inconsistent JSON formatting"
msgstr ""

#: changedetectionio/blueprint/ui/templates/edit.html
msgid "Helps reduce changes detected caused by sites shuffling lines around, combine with"
msgstr "有助于减少因行顺序变化导致的变更,可结合"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1400,6 +1400,10 @@ msgid ""
"lines against all history for this watch."
msgstr "適用於內容僅會移動的網站,且您想知道何時新增了「新」內容,此功能會將新行與此監測任務的所有歷史記錄進行比較。"

#: changedetectionio/blueprint/ui/templates/edit.html
msgid "Helps reduce changes detected caused by inconsistent JSON formatting"
msgstr ""

#: changedetectionio/blueprint/ui/templates/edit.html
msgid "Helps reduce changes detected caused by sites shuffling lines around, combine with"
msgstr "有助於減少因網站重新排列行而檢測到的變更,結合"
Expand Down
Loading