diff --git a/changedetectionio/processors/__init__.py b/changedetectionio/processors/__init__.py index a1d55f9ea..f5cb215b0 100644 --- a/changedetectionio/processors/__init__.py +++ b/changedetectionio/processors/__init__.py @@ -4,12 +4,10 @@ from changedetectionio.strtobool import strtobool from copy import deepcopy from loguru import logger import hashlib -import importlib -import inspect import os -import pkgutil import re -import sys + + from .pluggy_interface import plugin_manager, hookimpl class difference_detection_processor(): @@ -275,13 +273,14 @@ def get_watch_model_for_processor(processor_name): Get the Watch model class for the specified processor name :return: The Watch model class """ + # Try each plugin in turn for plugin in plugin_manager.get_plugins(): if hasattr(plugin, "get_watch_model_class"): model_class = plugin.get_watch_model_class(processor_name=processor_name) if model_class: return model_class - + # Default to standard Watch model from changedetectionio.model import Watch return Watch.model @@ -360,16 +359,11 @@ class RestockDiffPlugin: @hookimpl def get_watch_model_class(self, processor_name): if processor_name == 'restock_diff': - # Currently uses default watch model, could be customized in the future - from changedetectionio.model import Watch - return Watch.model + from . import restock_diff + return restock_diff.Watch return None -# For backward compatibility -def get_custom_watch_obj_for_processor(processor_name): - return get_watch_model_for_processor(processor_name) - # Register the built-in processor plugins plugin_manager.register(TextJsonDiffPlugin()) plugin_manager.register(RestockDiffPlugin()) diff --git a/changedetectionio/processors/restock_diff/__init__.py b/changedetectionio/processors/restock_diff/__init__.py index 3d472beec..9bee55d78 100644 --- a/changedetectionio/processors/restock_diff/__init__.py +++ b/changedetectionio/processors/restock_diff/__init__.py @@ -1,5 +1,4 @@ -from babel.numbers import parse_decimal from changedetectionio.model.Watch import model as BaseWatch from typing import Union import re @@ -7,6 +6,7 @@ import re class Restock(dict): def parse_currency(self, raw_value: str) -> Union[float, None]: + from babel.numbers import parse_decimal # Clean and standardize the value (ie 1,400.00 should be 1400.00), even better would be store the whole thing as an integer. standardized_value = raw_value diff --git a/changedetectionio/processors/restock_diff/processor.py b/changedetectionio/processors/restock_diff/processor.py index ac3512108..8242f4e8a 100644 --- a/changedetectionio/processors/restock_diff/processor.py +++ b/changedetectionio/processors/restock_diff/processor.py @@ -152,7 +152,8 @@ class perform_site_check(difference_detection_processor): # Unset any existing notification error update_obj = {'last_notification_error': False, 'last_error': False, 'restock': Restock()} - + if not 'restock_settings' in watch.keys(): + raise Exception("Restock settings not found in watch.") self.screenshot = self.fetcher.screenshot self.xpath_data = self.fetcher.xpath_data diff --git a/changedetectionio/store.py b/changedetectionio/store.py index 9d5c70861..4e8f7e794 100644 --- a/changedetectionio/store.py +++ b/changedetectionio/store.py @@ -18,8 +18,7 @@ import time import uuid as uuid_builder from loguru import logger -from .processors import get_custom_watch_obj_for_processor -from .processors.restock_diff import Restock +from .processors import get_watch_model_for_processor # Because the server will run as a daemon and wont know the URL for notification links when firing off a notification BASE_URL_NOT_SET_TEXT = '("Base URL" not set - see settings - notifications)' @@ -150,10 +149,10 @@ class ChangeDetectionStore: entity['uuid'] = uuid if processor_override: - watch_class = get_custom_watch_obj_for_processor(processor_override) + watch_class = get_watch_model_for_processor(processor_override) entity['processor']=processor_override else: - watch_class = get_custom_watch_obj_for_processor(entity.get('processor')) + watch_class = get_watch_model_for_processor(entity.get('processor')) if entity.get('uuid') != 'text_json_diff': logger.trace(f"Loading Watch object '{watch_class.__module__}.{watch_class.__name__}' for UUID {uuid}") @@ -345,7 +344,7 @@ class ChangeDetectionStore: apply_extras['tags'] = list(set(apply_extras.get('tags'))) # If the processor also has its own Watch implementation - watch_class = get_custom_watch_obj_for_processor(apply_extras.get('processor')) + watch_class = get_watch_model_for_processor(apply_extras.get('processor')) new_watch = watch_class(datastore_path=self.datastore_path, url=url) new_uuid = new_watch.get('uuid') @@ -890,6 +889,7 @@ class ChangeDetectionStore: # Migrate old 'in_stock' values to the new Restock def update_17(self): + from .processors.restock_diff import Restock for uuid, watch in self.data['watching'].items(): if 'in_stock' in watch: watch['restock'] = Restock({'in_stock': watch.get('in_stock')}) diff --git a/changedetectionio/tests/test_restock_itemprop.py b/changedetectionio/tests/test_restock_itemprop.py index f5e852f47..3cd0f7a72 100644 --- a/changedetectionio/tests/test_restock_itemprop.py +++ b/changedetectionio/tests/test_restock_itemprop.py @@ -95,12 +95,14 @@ def test_itemprop_price_change(client, live_server): test_url = url_for('test_endpoint', _external=True) set_original_response(props_markup=instock_props[0], price="190.95") - client.post( + res = client.post( url_for("ui.ui_views.form_quick_watch_add"), data={"url": test_url, "tags": 'restock tests', 'processor': 'restock_diff'}, follow_redirects=True ) + assert res.status_code == 200 + # A change in price, should trigger a change by default wait_for_all_checks(client) res = client.get(url_for("index")) @@ -110,6 +112,7 @@ def test_itemprop_price_change(client, live_server): set_original_response(props_markup=instock_props[0], price='180.45') client.get(url_for("ui.form_watch_checknow"), follow_redirects=True) wait_for_all_checks(client) + res = client.get(url_for("index")) assert b'180.45' in res.data assert b'unviewed' in res.data @@ -395,7 +398,7 @@ def test_data_sanity(client, live_server): test_url = url_for('test_endpoint', _external=True) test_url2 = url_for('test_endpoint2', _external=True) set_original_response(props_markup=instock_props[0], price="950.95") - client.post( + res = client.post( url_for("ui.ui_views.form_quick_watch_add"), data={"url": test_url, "tags": 'restock tests', 'processor': 'restock_diff'}, follow_redirects=True