From a7e531ca622c53af64c0c5c6195d5802a27a3475 Mon Sep 17 00:00:00 2001 From: javex Date: Fri, 8 Mar 2024 16:34:48 +1030 Subject: [PATCH] Handle comparable string edge case --- hotprices_au/sites/coles.py | 25 +++++++++++++++++++++++++ tests/stores/test_coles.py | 12 +++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/hotprices_au/sites/coles.py b/hotprices_au/sites/coles.py index a5a6ea5..99905a2 100644 --- a/hotprices_au/sites/coles.py +++ b/hotprices_au/sites/coles.py @@ -144,12 +144,37 @@ def get_quantity_and_unit(item): # If that didn't work we can now try to get the info from standard sizes (e.g. per 100g) if 'ofMeasureUnits' in unit_data: unit = unit_data['ofMeasureUnits'] + elif item.get('pricing',{}).get('comparable'): + return parse_comparable(item) else: raise return quantity, unit +def parse_comparable(item): + comparable = item['pricing']['comparable'] + m = re.match(r'\$([\.0-9]+) per (.*)', comparable) + if not m: + raise RuntimeError(f"Unable to parse comparable {comparable}") + + price_str, per_str = m.group(1), m.group(2) + price_per = float(price_str) + if price_per != item['pricing']['now']: + raise RuntimeError( + f"Price from {comparable} extracted as {price_per} " + f"does not match expected price of {item['pricing']['now']}" + ) + + if per_str == '1ea': + quantity, unit = 1, 'ea' + else: + raise RuntimeError( + f"Unable to understad what {per_str} means from " + f"{comparable}" + ) + return quantity, unit + def parse_str_unit(size): # Try coles-special methods before going to the generic function size = size.lower() diff --git a/tests/stores/test_coles.py b/tests/stores/test_coles.py index 8faf013..1bf5afc 100644 --- a/tests/stores/test_coles.py +++ b/tests/stores/test_coles.py @@ -1,6 +1,7 @@ from hotprices_au.sites import coles -def get_item(ofMeasureUnits=None, quantity=None, isWeighted=True, pricing=True, size=None, **kwargs): +def get_item(ofMeasureUnits=None, quantity=None, isWeighted=True, pricing=True, + size=None, comparable=None, **kwargs): defaults = { '_type': 'PRODUCT', 'id': '1', @@ -26,6 +27,9 @@ def get_item(ofMeasureUnits=None, quantity=None, isWeighted=True, pricing=True, if quantity is not None: defaults['pricing']['unit']['quantity'] = quantity + if comparable is not None: + defaults['pricing']['comparable'] = comparable + if pricing is None: defaults['pricing'] = None defaults.update(kwargs) @@ -133,6 +137,12 @@ def test_get_canonical(): assert can_item['quantity'] == 200 assert not can_item['isWeighted'] + item = get_item(comparable='$10.00 per 1ea', quantity=0) + can_item = coles.get_canonical(item, today) + assert can_item['unit'] == 'ea' + assert can_item['quantity'] == 1 + assert can_item['price'] == 10 + if __name__ == '__main__': test_get_canonical()