mirror of
https://github.com/dgtlmoon/changedetection.io.git
synced 2026-01-14 03:00:19 +00:00
Compare commits
1 Commits
api-diff-e
...
2600-mode-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e16e72ee07 |
@@ -302,28 +302,18 @@ class WatchHistoryDiff(Resource):
|
||||
from_version_file_contents = watch.get_history_snapshot(from_timestamp)
|
||||
to_version_file_contents = watch.get_history_snapshot(to_timestamp)
|
||||
|
||||
# Get diff preferences from query parameters (matching UI preferences in DIFF_PREFERENCES_CONFIG)
|
||||
# Support both 'type' (UI parameter) and 'word_diff' (API parameter) for backward compatibility
|
||||
diff_type = request.args.get('type', 'diffLines')
|
||||
if diff_type == 'diffWords':
|
||||
word_diff = True
|
||||
# Get diff preferences (using defaults similar to the existing code)
|
||||
diff_prefs = {
|
||||
'diff_ignoreWhitespace': False,
|
||||
'diff_changesOnly': 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'))
|
||||
|
||||
# Generate the diff with all preferences
|
||||
# Generate the diff
|
||||
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,
|
||||
ignore_junk=diff_prefs.get('diff_ignoreWhitespace'),
|
||||
include_equal=not diff_prefs.get('diff_changesOnly'),
|
||||
word_diff=word_diff,
|
||||
)
|
||||
|
||||
|
||||
@@ -15,22 +15,6 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
// Open modal when language button is clicked
|
||||
languageButton.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
// Update all language links to include current hash in the redirect parameter
|
||||
const currentPath = window.location.pathname;
|
||||
const currentHash = window.location.hash;
|
||||
|
||||
if (currentHash) {
|
||||
const languageOptions = languageModal.querySelectorAll('.language-option');
|
||||
languageOptions.forEach(function(option) {
|
||||
const url = new URL(option.href, window.location.origin);
|
||||
// Update the redirect parameter to include the hash
|
||||
const redirectPath = currentPath + currentHash;
|
||||
url.searchParams.set('redirect', redirectPath);
|
||||
option.setAttribute('href', url.pathname + url.search + url.hash);
|
||||
});
|
||||
}
|
||||
|
||||
languageModal.showModal();
|
||||
});
|
||||
|
||||
|
||||
@@ -165,83 +165,18 @@ def test_api_simple(client, live_server, measure_memory_usage, datastore_path):
|
||||
assert b'<div id' in res.data
|
||||
|
||||
|
||||
# Fetch the difference between two versions (default text format)
|
||||
# Fetch the difference between two versions
|
||||
res = client.get(
|
||||
url_for("watchhistorydiff", uuid=watch_uuid, from_timestamp='previous', to_timestamp='latest'),
|
||||
headers={'x-api-key': api_key},
|
||||
)
|
||||
assert b'(changed) Which is across' in res.data
|
||||
|
||||
# Test htmlcolor format
|
||||
res = client.get(
|
||||
url_for("watchhistorydiff", uuid=watch_uuid, from_timestamp='previous', to_timestamp='latest')+'?format=htmlcolor',
|
||||
headers={'x-api-key': api_key},
|
||||
)
|
||||
assert b'aria-label="Changed text" title="Changed text">Which is across multiple lines' in res.data
|
||||
|
||||
# Test html format
|
||||
res = client.get(
|
||||
url_for("watchhistorydiff", uuid=watch_uuid, from_timestamp='previous', to_timestamp='latest')+'?format=html',
|
||||
headers={'x-api-key': api_key},
|
||||
)
|
||||
assert res.status_code == 200
|
||||
assert b'<br>' in res.data
|
||||
|
||||
# Test markdown format
|
||||
res = client.get(
|
||||
url_for("watchhistorydiff", uuid=watch_uuid, from_timestamp='previous', to_timestamp='latest')+'?format=markdown',
|
||||
headers={'x-api-key': api_key},
|
||||
)
|
||||
assert res.status_code == 200
|
||||
|
||||
# Test new diff preference parameters
|
||||
# Test removed=false (should hide removed content)
|
||||
res = client.get(
|
||||
url_for("watchhistorydiff", uuid=watch_uuid, from_timestamp='previous', to_timestamp='latest')+'?removed=false',
|
||||
headers={'x-api-key': api_key},
|
||||
)
|
||||
# Should not contain removed content indicator
|
||||
assert b'(removed)' not in res.data
|
||||
# Should still contain added content
|
||||
assert b'(added)' in res.data or b'which has this one new line' in res.data
|
||||
|
||||
# Test added=false (should hide added content)
|
||||
# Note: The test data has replacements, not pure additions, so we test differently
|
||||
res = client.get(
|
||||
url_for("watchhistorydiff", uuid=watch_uuid, from_timestamp='previous', to_timestamp='latest')+'?added=false&replaced=false',
|
||||
headers={'x-api-key': api_key},
|
||||
)
|
||||
# With both added and replaced disabled, should have minimal content
|
||||
# Should not contain added indicators
|
||||
assert b'(added)' not in res.data
|
||||
|
||||
# Test replaced=false (should hide replaced/changed content)
|
||||
res = client.get(
|
||||
url_for("watchhistorydiff", uuid=watch_uuid, from_timestamp='previous', to_timestamp='latest')+'?replaced=false',
|
||||
headers={'x-api-key': api_key},
|
||||
)
|
||||
# Should not contain changed content indicator
|
||||
assert b'(changed)' not in res.data
|
||||
|
||||
# Test type=diffWords for word-level diff
|
||||
res = client.get(
|
||||
url_for("watchhistorydiff", uuid=watch_uuid, from_timestamp='previous', to_timestamp='latest')+'?type=diffWords&format=htmlcolor',
|
||||
headers={'x-api-key': api_key},
|
||||
)
|
||||
# Should contain HTML formatted diff
|
||||
assert res.status_code == 200
|
||||
assert len(res.data) > 0
|
||||
|
||||
# Test combined parameters: show only additions with word diff
|
||||
res = client.get(
|
||||
url_for("watchhistorydiff", uuid=watch_uuid, from_timestamp='previous', to_timestamp='latest')+'?removed=false&replaced=false&type=diffWords',
|
||||
headers={'x-api-key': api_key},
|
||||
)
|
||||
assert res.status_code == 200
|
||||
# Should not contain removed or changed markers
|
||||
assert b'(removed)' not in res.data
|
||||
assert b'(changed)' not in res.data
|
||||
|
||||
|
||||
# Fetch the whole watch
|
||||
res = client.get(
|
||||
|
||||
@@ -28,7 +28,7 @@ info:
|
||||
|
||||
For example: `x-api-key: YOUR_API_KEY`
|
||||
|
||||
version: 0.1.4
|
||||
version: 0.1.3
|
||||
contact:
|
||||
name: ChangeDetection.io
|
||||
url: https://github.com/dgtlmoon/changedetection.io
|
||||
@@ -761,9 +761,9 @@ paths:
|
||||
get:
|
||||
operationId: getWatchHistoryDiff
|
||||
tags: [Watch History]
|
||||
summary: Get the difference between two snapshots
|
||||
summary: Get diff between two snapshots
|
||||
description: |
|
||||
Generate a difference (comparison) between two historical snapshots of a web page change monitor (watch).
|
||||
Generate a formatted diff (comparison) between two historical snapshots of a web page change monitor (watch).
|
||||
|
||||
This endpoint compares content between two points in time and returns the differences in your chosen format.
|
||||
Perfect for reviewing what changed between specific versions or comparing recent changes.
|
||||
@@ -798,10 +798,6 @@ paths:
|
||||
# Compare two specific timestamps in plain text with word-level diff
|
||||
curl -X GET "http://localhost:5000/api/v1/watch/095be615-a8ad-4c33-8e9c-c7612fbf6c9f/difference/1640995200/1640998800?format=text&word_diff=true" \
|
||||
-H "x-api-key: YOUR_API_KEY"
|
||||
|
||||
# Show only additions (hide removed/replaced content), ignore whitespace
|
||||
curl -X GET "http://localhost:5000/api/v1/watch/095be615-a8ad-4c33-8e9c-c7612fbf6c9f/difference/previous/latest?format=htmlcolor&removed=false&replaced=false&ignoreWhitespace=true" \
|
||||
-H "x-api-key: YOUR_API_KEY"
|
||||
- lang: 'Python'
|
||||
source: |
|
||||
import requests
|
||||
@@ -826,20 +822,6 @@ paths:
|
||||
params={'format': 'text', 'word_diff': 'true'}
|
||||
)
|
||||
print(response.text)
|
||||
|
||||
# Show only additions, ignore whitespace and use word-level diff
|
||||
response = requests.get(
|
||||
f'http://localhost:5000/api/v1/watch/{uuid}/difference/previous/latest',
|
||||
headers=headers,
|
||||
params={
|
||||
'format': 'htmlcolor',
|
||||
'type': 'diffWords',
|
||||
'removed': 'false',
|
||||
'replaced': 'false',
|
||||
'ignoreWhitespace': 'true'
|
||||
}
|
||||
)
|
||||
print(response.text)
|
||||
parameters:
|
||||
- name: uuid
|
||||
in: path
|
||||
@@ -879,10 +861,9 @@ paths:
|
||||
- `text` (default): Plain text with (removed) and (added) prefixes
|
||||
- `html`: Basic HTML format
|
||||
- `htmlcolor`: Rich HTML with colored backgrounds (red for deletions, green for additions)
|
||||
- `markdown`: Markdown format with HTML rendering
|
||||
schema:
|
||||
type: string
|
||||
enum: [text, html, htmlcolor, markdown]
|
||||
enum: [text, html, htmlcolor]
|
||||
default: text
|
||||
- name: word_diff
|
||||
in: query
|
||||
@@ -907,69 +888,6 @@ paths:
|
||||
type: string
|
||||
enum: ["true", "false", "1", "0", "yes", "no", "on", "off"]
|
||||
default: "false"
|
||||
- name: type
|
||||
in: query
|
||||
description: |
|
||||
Diff granularity type:
|
||||
- `diffLines` (default): Line-level comparison, showing which lines changed
|
||||
- `diffWords`: Word-level comparison, showing which words changed within lines
|
||||
|
||||
This parameter is an alternative to `word_diff` for better alignment with the UI.
|
||||
If both are specified, `type=diffWords` will enable word-level diffing.
|
||||
schema:
|
||||
type: string
|
||||
enum: [diffLines, diffWords]
|
||||
default: diffLines
|
||||
- name: changesOnly
|
||||
in: query
|
||||
description: |
|
||||
When enabled, only show lines/content that changed (no surrounding context).
|
||||
When disabled, include unchanged lines for context around changes.
|
||||
Accepts: true, false, 1, 0, yes, no, on, off
|
||||
schema:
|
||||
type: string
|
||||
enum: ["true", "false", "1", "0", "yes", "no", "on", "off"]
|
||||
default: "true"
|
||||
- name: ignoreWhitespace
|
||||
in: query
|
||||
description: |
|
||||
When enabled, ignore whitespace-only changes (spaces, tabs, newlines).
|
||||
Useful for focusing on content changes and ignoring formatting differences.
|
||||
Accepts: true, false, 1, 0, yes, no, on, off
|
||||
schema:
|
||||
type: string
|
||||
enum: ["true", "false", "1", "0", "yes", "no", "on", "off"]
|
||||
default: "false"
|
||||
- name: removed
|
||||
in: query
|
||||
description: |
|
||||
Include removed/deleted content in the diff output.
|
||||
When disabled, content that was deleted will not appear in the diff.
|
||||
Accepts: true, false, 1, 0, yes, no, on, off
|
||||
schema:
|
||||
type: string
|
||||
enum: ["true", "false", "1", "0", "yes", "no", "on", "off"]
|
||||
default: "true"
|
||||
- name: added
|
||||
in: query
|
||||
description: |
|
||||
Include added/new content in the diff output.
|
||||
When disabled, content that was added will not appear in the diff.
|
||||
Accepts: true, false, 1, 0, yes, no, on, off
|
||||
schema:
|
||||
type: string
|
||||
enum: ["true", "false", "1", "0", "yes", "no", "on", "off"]
|
||||
default: "true"
|
||||
- name: replaced
|
||||
in: query
|
||||
description: |
|
||||
Include replaced/modified content in the diff output.
|
||||
When disabled, content that was modified (changed from one value to another) will not appear in the diff.
|
||||
Accepts: true, false, 1, 0, yes, no, on, off
|
||||
schema:
|
||||
type: string
|
||||
enum: ["true", "false", "1", "0", "yes", "no", "on", "off"]
|
||||
default: "true"
|
||||
responses:
|
||||
'200':
|
||||
description: Formatted diff between the two snapshots
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user