Handle quantity ranges (e.g. 2-3) in Mealie and Tandoor clients

Both APIs require numeric quantity/amount fields. When a range like
"2-3" is detected, uses the first number as the quantity and puts
the full range (e.g. "2- 3 ek") in the note field.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-24 16:17:06 +01:00
parent 4dde7bd8b5
commit 3524f372cc
2 changed files with 47 additions and 10 deletions
+25 -5
View File
@@ -1,10 +1,32 @@
"""Mealie API client — creates recipes and uploads images.""" """Mealie API client — creates recipes and uploads images."""
import io import io
import re
import uuid import uuid
import requests import requests
def _parse_qty(qty_str: str) -> tuple[float, str]:
"""Parse a quantity string, handling ranges like '2-3' or '6- 8'.
Returns (number, range_note) where range_note is the original range
string if the quantity is a range, or empty string if it's a plain number.
"""
if not qty_str:
return (0, "")
# Try plain number first
try:
return (float(qty_str.replace(",", ".")), "")
except (ValueError, TypeError):
pass
# Try range: "2-3", "2- 3", "6 - 8"
m = re.match(r"^(\d+(?:[.,]\d+)?)\s*-\s*(\d+(?:[.,]\d+)?)$", qty_str.strip())
if m:
first = float(m.group(1).replace(",", "."))
return (first, qty_str.strip())
return (0, "")
class MealieClient: class MealieClient:
"""Thin wrapper around the Mealie REST API.""" """Thin wrapper around the Mealie REST API."""
@@ -275,11 +297,9 @@ class MealieClient:
unit_ref = self._ensure_unit(unit_str) if unit_str else None unit_ref = self._ensure_unit(unit_str) if unit_str else None
food_ref = self._ensure_food(food_str) food_ref = self._ensure_food(food_str)
qty = 0 qty, range_note = _parse_qty(qty_str)
try: if range_note:
qty = float(qty_str.replace(",", ".")) extra = f"{range_note} {unit_str}; {extra}".strip("; ") if extra else f"{range_note} {unit_str}".strip()
except (ValueError, TypeError):
pass
return { return {
"referenceId": str(uuid.uuid4()), "referenceId": str(uuid.uuid4()),
+22 -5
View File
@@ -5,6 +5,25 @@ import re
import requests import requests
def _parse_qty(qty_str: str) -> tuple[float, str]:
"""Parse a quantity string, handling ranges like '2-3' or '6- 8'.
Returns (number, range_note) where range_note is the original range
string if the quantity is a range, or empty string if it's a plain number.
"""
if not qty_str:
return (0, "")
try:
return (float(qty_str.replace(",", ".")), "")
except (ValueError, TypeError):
pass
m = re.match(r"^(\d+(?:[.,]\d+)?)\s*-\s*(\d+(?:[.,]\d+)?)$", qty_str.strip())
if m:
first = float(m.group(1).replace(",", "."))
return (first, qty_str.strip())
return (0, "")
class TandoorClient: class TandoorClient:
"""Thin wrapper around the Tandoor REST API.""" """Thin wrapper around the Tandoor REST API."""
@@ -184,11 +203,9 @@ class TandoorClient:
has_structured = bool(qty_str or unit_str) has_structured = bool(qty_str or unit_str)
if has_structured and food_str: if has_structured and food_str:
qty = 0 qty, range_note = _parse_qty(qty_str)
try: if range_note:
qty = float(qty_str.replace(",", ".")) extra = f"{range_note} {unit_str}; {extra}".strip("; ") if extra else f"{range_note} {unit_str}".strip()
except (ValueError, TypeError):
pass
return { return {
"food": {"name": food_str}, "food": {"name": food_str},