From f67e7489751d84f788e44cc70bb30fc1b6d008c6 Mon Sep 17 00:00:00 2001 From: dgtlmoon Date: Tue, 16 Jul 2024 12:12:59 +0200 Subject: [PATCH] move restock to its own sttings --- .../processors/restock_diff/__init__.py | 4 ++++ .../processors/restock_diff/forms.py | 24 ++++++++++++------- .../processors/restock_diff/processor.py | 19 ++++++++------- .../tests/test_restock_itemprop.py | 12 +++++----- 4 files changed, 36 insertions(+), 23 deletions(-) diff --git a/changedetectionio/processors/restock_diff/__init__.py b/changedetectionio/processors/restock_diff/__init__.py index 3c48eec9..785668be 100644 --- a/changedetectionio/processors/restock_diff/__init__.py +++ b/changedetectionio/processors/restock_diff/__init__.py @@ -59,6 +59,10 @@ class Watch(BaseWatch): super().__init__(*arg, **kw) self['restock'] = Restock(kw['default']['restock']) if kw.get('default') and kw['default'].get('restock') else Restock() + self['restock_settings'] = kw['default']['restock_settings'] if kw.get('default',{}).get('restock_settings') else { + 'follow_price_changes': True + } + def clear_watch(self): super().clear_watch() self.update({'restock': Restock()}) diff --git a/changedetectionio/processors/restock_diff/forms.py b/changedetectionio/processors/restock_diff/forms.py index 92e5d31c..6ee45220 100644 --- a/changedetectionio/processors/restock_diff/forms.py +++ b/changedetectionio/processors/restock_diff/forms.py @@ -4,10 +4,12 @@ from wtforms import ( validators, FloatField ) +from wtforms.fields.form import FormField +from wtforms.form import Form from changedetectionio.forms import processor_text_json_diff_form - -class processor_settings_form(processor_text_json_diff_form): +class RestockSettingsForm(Form): +# Could be both, "in_stock_only" either in_stock_only = BooleanField('Only trigger when product goes BACK to in-stock', default=True) price_change_min = FloatField('Minimum amount to trigger notification', [validators.Optional()], render_kw={"placeholder": "No limit", "size": "10"}) @@ -19,7 +21,12 @@ class processor_settings_form(processor_text_json_diff_form): validators.NumberRange(min=0, max=100, message="Should be between 0 and 100"), ], render_kw={"placeholder": "0%", "size": "5"}) - follow_price_changes = BooleanField('Follow price changes', default=False) + follow_price_changes = BooleanField('Follow price changes', default=True) + +class processor_settings_form(processor_text_json_diff_form): + + restock_settings = FormField(RestockSettingsForm) + def extra_tab_content(self): return 'Restock & Price Detection' @@ -33,29 +40,28 @@ class processor_settings_form(processor_text_json_diff_form): }); -
- {{ render_checkbox_field(form.in_stock_only) }} + {{ render_checkbox_field(form.restock_settings.in_stock_only) }} Only trigger re-stock notification when page changes from out of stock to back in stock
- {{ render_checkbox_field(form.follow_price_changes) }} + {{ render_checkbox_field(form.restock_settings.follow_price_changes) }} Changes in price should trigger a notification
When OFF - Only care about restock detection
- {{ render_field(form.price_change_min, placeholder=watch['restock'].get('price')) }} + {{ render_field(form.restock_settings.price_change_min, placeholder=watch['restock'].get('price')) }} Minimum amount, only trigger a change when the price is less than this amount.
- {{ render_field(form.price_change_max, placeholder=watch['restock'].get('price')) }} + {{ render_field(form.restock_settings.price_change_max, placeholder=watch['restock'].get('price')) }} Maximum amount, only trigger a change when the price is more than this amount.
- {{ render_field(form.price_change_threshold_percent) }} + {{ render_field(form.restock_settings.price_change_threshold_percent) }} Price must change more than this % to trigger a change.
For example, If the product is $1,000 USD originally, 2% would mean it has to change more than $20 since the first check.
diff --git a/changedetectionio/processors/restock_diff/processor.py b/changedetectionio/processors/restock_diff/processor.py index 42dd9bd4..d51f9166 100644 --- a/changedetectionio/processors/restock_diff/processor.py +++ b/changedetectionio/processors/restock_diff/processor.py @@ -132,6 +132,9 @@ class perform_site_check(difference_detection_processor): update_obj['content_type'] = self.fetcher.headers.get('Content-Type', '') update_obj["last_check_status"] = self.fetcher.get_last_status_code() + # Which restock settings to compare against? + restock_settings = watch.get('restock_settings', {}) + itemprop_availability = {} try: itemprop_availability = get_itemprop_availability(html_content=self.fetcher.content) @@ -195,14 +198,14 @@ class perform_site_check(difference_detection_processor): # out of stock -> back in stock only? if watch.get('restock') and watch['restock'].get('in_stock') != update_obj['restock'].get('in_stock'): # Yes if we only care about it going to instock, AND we are in stock - if watch.get('in_stock_only') and update_obj['restock']['in_stock']: + if restock_settings.get('in_stock_only') and update_obj['restock']['in_stock']: changed_detected = True - if not watch.get('in_stock_only'): + if not restock_settings.get('in_stock_only'): # All cases changed_detected = True - if watch.get('follow_price_changes') and watch.get('restock') and update_obj.get('restock') and update_obj['restock'].get('price'): + if restock_settings.get('follow_price_changes') and watch.get('restock') and update_obj.get('restock') and update_obj['restock'].get('price'): price = float(update_obj['restock'].get('price')) # Default to current price if no previous price found if watch['restock'].get('original_price'): @@ -214,10 +217,10 @@ class perform_site_check(difference_detection_processor): # Minimum/maximum price limit if update_obj.get('restock') and update_obj['restock'].get('price'): logger.debug( - f"{watch.get('uuid')} - Change was detected, 'price_change_max' is '{watch.get('price_change_max', '')}' 'price_change_min' is '{watch.get('price_change_min', '')}', price from website is '{update_obj['restock'].get('price', '')}'.") + f"{watch.get('uuid')} - Change was detected, 'price_change_max' is '{restock_settings.get('price_change_max', '')}' 'price_change_min' is '{restock_settings.get('price_change_min', '')}', price from website is '{update_obj['restock'].get('price', '')}'.") if update_obj['restock'].get('price'): - min_limit = float(watch.get('price_change_min')) if watch.get('price_change_min') else None - max_limit = float(watch.get('price_change_max')) if watch.get('price_change_max') else None + min_limit = float(restock_settings.get('price_change_min')) if restock_settings.get('price_change_min') else None + max_limit = float(restock_settings.get('price_change_max')) if restock_settings.get('price_change_max') else None price = float(update_obj['restock'].get('price')) logger.debug(f"{watch.get('uuid')} after float conversion - Min limit: '{min_limit}' Max limit: '{max_limit}' Price: '{price}'") @@ -231,9 +234,9 @@ class perform_site_check(difference_detection_processor): logger.trace(f"{watch.get('uuid')} {price} is NOT between {min_limit} and {max_limit}") # Price comparison by % - if watch['restock'].get('original_price') and changed_detected and watch.get('price_change_threshold_percent'): + if watch['restock'].get('original_price') and changed_detected and restock_settings.get('price_change_threshold_percent'): previous_price = float(watch['restock'].get('original_price')) - pc = float(watch.get('price_change_threshold_percent')) + pc = float(restock_settings.get('price_change_threshold_percent')) change = abs((price - previous_price) / previous_price * 100) if change and change <= pc: logger.debug(f"{watch.get('uuid')} Override change-detected to FALSE because % threshold ({pc}%) was {change:.3f}%") diff --git a/changedetectionio/tests/test_restock_itemprop.py b/changedetectionio/tests/test_restock_itemprop.py index e33de270..e342f511 100644 --- a/changedetectionio/tests/test_restock_itemprop.py +++ b/changedetectionio/tests/test_restock_itemprop.py @@ -114,7 +114,7 @@ def test_itemprop_price_change(client, live_server): set_original_response(props_markup=instock_props[0], price='120.45') res = client.post( url_for("edit_page", uuid="first"), - data={"follow_price_changes": "", "url": test_url, "tags": "", "headers": "", 'fetch_backend': "html_requests"}, + data={"restock_settings-follow_price_changes": "", "url": test_url, "tags": "", "headers": "", 'fetch_backend': "html_requests"}, follow_redirects=True ) assert b"Updated watch." in res.data @@ -149,9 +149,9 @@ def test_itemprop_price_minmax_limit(client, live_server): res = client.post( url_for("edit_page", uuid="first"), - data={"follow_price_changes": "y", - "price_change_min": 900.0, - "price_change_max": 1100.10, + data={"restock_settings-follow_price_changes": "y", + "restock_settings-price_change_min": 900.0, + "restock_settings-price_change_max": 1100.10, "url": test_url, "tags": "", "headers": "", @@ -221,8 +221,8 @@ def test_itemprop_percent_threshold(client, live_server): res = client.post( url_for("edit_page", uuid="first"), - data={"follow_price_changes": "y", - "price_change_threshold_percent": 5.0, + data={"restock_settings-follow_price_changes": "y", + "restock_settings-price_change_threshold_percent": 5.0, "url": test_url, "tags": "", "headers": "",