Skip to content

Commit 9d355b8

Browse files
authored
UI - Restock/pricing - Handle when price amount is sometimes string or integer (#3950)
1 parent da43a17 commit 9d355b8

File tree

5 files changed

+57
-6
lines changed

5 files changed

+57
-6
lines changed

changedetectionio/blueprint/watchlist/templates/watch-overview.html

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -305,12 +305,20 @@
305305
{%- endif -%}
306306

307307
{%- if watch.get('restock') and watch['restock'].get('price') -%}
308-
{%- if watch['restock']['price'] is number -%}
309-
<span class="restock-label price" title="{{ _('Price') }}">
310-
{{ watch['restock']['price']|format_number_locale if watch['restock'].get('price') else '' }} {{ watch['restock'].get('currency','') }}
311-
</span>
312-
{%- else -%} <!-- watch['restock']['price']' is not a number, cant output it -->
308+
{%- set restock = watch['restock'] -%}
309+
{%- set price = restock.get('price') -%}
310+
{%- set cur = restock.get('currency','') -%}
311+
312+
{%- if price is not none and (price|string)|regex_search('\d') -%}
313+
<span class="restock-label price" title="{{ _('Price') }}">
314+
{# @todo: make parse_currency/parse_decimal aware of the locale of the actual web page and use that instead changedetectionio/processors/restock_diff/__init__.py #}
315+
{%- if price is number -%}{# It's a number so we can convert it to their locale' #}
316+
{{ price|format_number_locale }} {{ cur }}<!-- as number -->
317+
{%- else -%}{# It's totally fine if it arrives as something else, the website might be something weird in this field #}
318+
{{ price }} {{ cur }}<!-- as string -->
313319
{%- endif -%}
320+
</span>
321+
{%- endif -%}
314322
{%- elif not watch.has_restock_info -%}
315323
<span class="restock-label error">{{ _('No information') }}</span>
316324
{%- endif -%}

changedetectionio/flask_app.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,9 +217,13 @@ def _jinja2_filter_format_number_locale(value: float) -> str:
217217
"Formats for example 4000.10 to the local locale default of 4,000.10"
218218
# Format the number with two decimal places (locale format string will return 6 decimal)
219219
formatted_value = locale.format_string("%.2f", value, grouping=True)
220-
221220
return formatted_value
222221

222+
@app.template_filter('regex_search')
223+
def _jinja2_filter_regex_search(value, pattern):
224+
import re
225+
return re.search(pattern, str(value)) is not None
226+
223227
@app.template_global('is_checking_now')
224228
def _watch_is_checking_now(watch_obj, format="%Y-%m-%d %H:%M:%S"):
225229
return worker_pool.is_watch_running(watch_obj['uuid'])

changedetectionio/processors/restock_diff/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ def parse_currency(self, raw_value: str) -> Union[float, None]:
3131

3232
if standardized_value:
3333
# Convert to float
34+
# @todo locale needs to be the locale of the webpage
3435
return float(parse_decimal(standardized_value, locale='en'))
3536

3637
return None

changedetectionio/processors/restock_diff/pure_python_extractor.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,4 +283,7 @@ def query_price_availability(extracted_data):
283283
if not result.get('availability') and 'availability' in microdata:
284284
result['availability'] = microdata['availability']
285285

286+
# result['price'] could be float or str here, depending on the website, for example it might contain "1,00" commas, etc.
287+
# using something like babel you need to know the locale of the website and even then it can be problematic
288+
# we dont really do anything with the price data so far.. so just accept it the way it comes.
286289
return result

changedetectionio/tests/test_restock_itemprop.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,3 +467,38 @@ def test_special_prop_examples(client, live_server, measure_memory_usage, datast
467467
assert b'155.55' in res.data
468468

469469
delete_all_watches(client)
470+
471+
472+
def test_itemprop_as_str(client, live_server, measure_memory_usage, datastore_path):
473+
474+
test_return_data = f"""<html>
475+
<body>
476+
Some initial text<br>
477+
<p>Which is across multiple lines</p>
478+
<span itemprop="offers" itemscope itemtype="http://schema.org/Offer">
479+
<meta content="767.55" itemprop="price"/>
480+
<meta content="EUR" itemprop="priceCurrency"/>
481+
<meta content="InStock" itemprop="availability"/>
482+
<meta content="https://www.123-test.dk" itemprop="url"/>
483+
</span>
484+
</body>
485+
</html>
486+
"""
487+
488+
with open(os.path.join(datastore_path, "endpoint-content.txt"), "w") as f:
489+
f.write(test_return_data)
490+
491+
492+
test_url = url_for('test_endpoint', _external=True)
493+
494+
client.post(
495+
url_for("ui.ui_views.form_quick_watch_add"),
496+
data={"url": test_url, "tags": 'restock tests', 'processor': 'restock_diff'},
497+
follow_redirects=True
498+
)
499+
500+
client.get(url_for("ui.form_watch_checknow"))
501+
wait_for_all_checks(client)
502+
503+
res = client.get(url_for("watchlist.index"))
504+
assert b'767.55' in res.data

0 commit comments

Comments
 (0)