diff --git a/changedetectionio/diff.py b/changedetectionio/diff.py index d2c2ab8a..61ab5c5b 100644 --- a/changedetectionio/diff.py +++ b/changedetectionio/diff.py @@ -2,22 +2,31 @@ import difflib + +def same_slicer(l, a, b): + if a == b: + return [l[a]] + else: + return l[a:b] + # like .compare but a little different output def customSequenceMatcher(before, after, include_equal=False): 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?) for tag, alo, ahi, blo, bhi in cruncher.get_opcodes(): if include_equal and tag == 'equal': g = before[alo:ahi] yield g elif tag == 'delete': - g = "(removed) {}".format(before[alo]) + g = ["(removed) " + i for i in same_slicer(before, alo, ahi)] yield g elif tag == 'replace': - g = ["(changed) {}".format(before[alo]), "(-> into) {}".format(after[blo])] + g = ["(changed) " + i for i in same_slicer(before, alo, ahi)] + g += ["(into ) " + i for i in same_slicer(after, blo, bhi)] yield g elif tag == 'insert': - g = "(added) {}".format(after[blo]) + g = ["(added ) " + i for i in same_slicer(after, blo, bhi)] yield g # only_differences - only return info about the differences, no context diff --git a/changedetectionio/tests/test_notification.py b/changedetectionio/tests/test_notification.py index 256339cd..ac5591e9 100644 --- a/changedetectionio/tests/test_notification.py +++ b/changedetectionio/tests/test_notification.py @@ -125,7 +125,7 @@ def test_check_notification(client, live_server): # Diff was correctly executed assert "Diff Full: Some initial text" in notification_submission assert "Diff: (changed) Which is across multiple lines" in notification_submission - assert "(-> into) which has this one new line" in notification_submission + assert "(into ) which has this one new line" in notification_submission if env_base_url: diff --git a/changedetectionio/tests/unit/test-content/after-2.txt b/changedetectionio/tests/unit/test-content/after-2.txt new file mode 100644 index 00000000..49030e7d --- /dev/null +++ b/changedetectionio/tests/unit/test-content/after-2.txt @@ -0,0 +1,3 @@ +After twenty years, as cursed as I may be +ok +and insure that I'm one of those computer nerds. diff --git a/changedetectionio/tests/unit/test-content/after.txt b/changedetectionio/tests/unit/test-content/after.txt index ffb0e3a5..7327be22 100644 --- a/changedetectionio/tests/unit/test-content/after.txt +++ b/changedetectionio/tests/unit/test-content/after.txt @@ -2,5 +2,6 @@ After twenty years, as cursed as I may be for having learned computerese, I continue to examine bits, bytes and words xok +next-x-ok and insure that I'm one of those computer nerds. and something new \ No newline at end of file diff --git a/changedetectionio/tests/unit/test_notification_diff.py b/changedetectionio/tests/unit/test_notification_diff.py index a3ef3e72..62216c31 100755 --- a/changedetectionio/tests/unit/test_notification_diff.py +++ b/changedetectionio/tests/unit/test_notification_diff.py @@ -12,12 +12,19 @@ from changedetectionio import diff class TestDiffBuilder(unittest.TestCase): def test_expected_diff_output(self): - base_dir=os.path.dirname(__file__) - output = diff.render_diff(base_dir+"/test-content/before.txt", base_dir+"/test-content/after.txt") + base_dir = os.path.dirname(__file__) + output = diff.render_diff(previous_file=base_dir + "/test-content/before.txt", newest_file=base_dir + "/test-content/after.txt") output = output.split("\n") - self.assertIn("(changed) ok", output) - self.assertIn("(-> into) xok", output) - self.assertIn("(added) and something new", output) + self.assertIn('(changed) ok', output) + self.assertIn('(into ) xok', output) + self.assertIn('(into ) next-x-ok', output) + self.assertIn('(added ) and something new', output) + + + output = diff.render_diff(previous_file=base_dir + "/test-content/before.txt", newest_file=base_dir + "/test-content/after-2.txt") + output = output.split("\n") + self.assertIn('(removed) for having learned computerese,', output) + self.assertIn('(removed) I continue to examine bits, bytes and words', output) # @todo test blocks of changed, blocks of added, blocks of removed diff --git a/requirements.txt b/requirements.txt index feef375b..7f69b402 100644 --- a/requirements.txt +++ b/requirements.txt @@ -35,3 +35,8 @@ lxml # 3.141 was missing socksVersion, 3.150 was not in pypi, so we try 4.1.0 selenium ~= 4.1.0 +# https://stackoverflow.com/questions/71652965/importerror-cannot-import-name-safe-str-cmp-from-werkzeug-security/71653849#71653849 +# ImportError: cannot import name 'safe_str_cmp' from 'werkzeug.security' +# need to revisit flask login versions +werkzeug ~= 2.0.0 +