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:
+25
-5
@@ -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
@@ -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},
|
||||||
|
|||||||
Reference in New Issue
Block a user