From b39c770f84abdff8c010c31fde310a09b5e15116 Mon Sep 17 00:00:00 2001 From: dgtlmoon Date: Wed, 12 Jun 2024 18:29:44 +0200 Subject: [PATCH] adding % threshold handling --- changedetectionio/processors/restock_diff.py | 12 +++- .../tests/test_restock_itemprop.py | 66 +++++++++++++++++++ 2 files changed, 76 insertions(+), 2 deletions(-) diff --git a/changedetectionio/processors/restock_diff.py b/changedetectionio/processors/restock_diff.py index b9f3e60b7..cdca1cd5d 100644 --- a/changedetectionio/processors/restock_diff.py +++ b/changedetectionio/processors/restock_diff.py @@ -198,10 +198,18 @@ class perform_site_check(difference_detection_processor): if min_limit or max_limit: if is_between(number=price, lower=min_limit, upper=max_limit): if changed_detected: - logger.debug( - f"{uuid} Override change-detected to FALSE because price was inside threshold") + logger.debug(f"{uuid} Override change-detected to FALSE because price was inside threshold") changed_detected = False + if changed_detected and watch.get('price_change_threshold_percent'): + pc = float(watch.get('price_change_threshold_percent')) + change = abs((price - previous_price) / previous_price * 100) + if change and change <= pc: + logger.debug(f"{uuid} Override change-detected to FALSE because % threshold ({pc}%) was {change:.3f}%") + changed_detected = False + else: + logger.debug(f"{uuid} Price change was {change:.3f}% , (threshold {pc}%)") + # Always record the new checksum update_obj["previous_md5"] = fetched_md5 return changed_detected, update_obj, self.fetcher.instock_data.encode('utf-8').strip() diff --git a/changedetectionio/tests/test_restock_itemprop.py b/changedetectionio/tests/test_restock_itemprop.py index 1a673df1d..af84930e0 100644 --- a/changedetectionio/tests/test_restock_itemprop.py +++ b/changedetectionio/tests/test_restock_itemprop.py @@ -189,3 +189,69 @@ def test_itemprop_price_minmax_limit(client, live_server): res = client.get(url_for("form_delete", uuid="all"), follow_redirects=True) assert b'Deleted' in res.data + +def test_itemprop_percent_threshold(client, live_server): + #live_server_setup(live_server) + + res = client.get(url_for("form_delete", uuid="all"), follow_redirects=True) + assert b'Deleted' in res.data + + test_url = url_for('test_endpoint', _external=True) + + set_original_response(props_markup=instock_props[0], price="950.95") + client.post( + url_for("form_quick_watch_add"), + data={"url": test_url, "tags": 'restock tests', 'processor': 'restock_diff'}, + follow_redirects=True + ) + + # A change in price, should trigger a change by default + wait_for_all_checks(client) + + res = client.post( + url_for("edit_page", uuid="first"), + data={"follow_price_changes": "y", + "price_change_threshold_percent": 5.0, + "url": test_url, + "tags": "", + "headers": "", + 'fetch_backend': "html_requests" + }, + follow_redirects=True + ) + assert b"Updated watch." in res.data + wait_for_all_checks(client) + + + # Basic change should not trigger + set_original_response(props_markup=instock_props[0], price='960.45') + client.get(url_for("form_watch_checknow")) + wait_for_all_checks(client) + res = client.get(url_for("index")) + assert b'960.45' in res.data + assert b'unviewed' not in res.data + + # Bigger INCREASE change than the threshold should trigger + set_original_response(props_markup=instock_props[0], price='1960.45') + client.get(url_for("form_watch_checknow")) + wait_for_all_checks(client) + res = client.get(url_for("index")) + assert b'1960.45' in res.data + assert b'unviewed' in res.data + + + # Small decrease should NOT trigger + client.get(url_for("mark_all_viewed")) + set_original_response(props_markup=instock_props[0], price='1950.45') + client.get(url_for("form_watch_checknow")) + wait_for_all_checks(client) + res = client.get(url_for("index")) + assert b'1950.45' in res.data + assert b'unviewed' not in res.data + + + + + res = client.get(url_for("form_delete", uuid="all"), follow_redirects=True) + assert b'Deleted' in res.data +