diff --git a/app/mealie.py b/app/mealie.py index 86a026e..4ce0437 100644 --- a/app/mealie.py +++ b/app/mealie.py @@ -147,7 +147,17 @@ class MealieClient: ingredients = [] for item in recipe.get("ingredients", []): if isinstance(item, dict): - ingredients.append(self._build_ingredient(item)) + # Group header marker + if "group" in item and "food" not in item: + ingredients.append({ + "referenceId": str(uuid.uuid4()), + "title": item["group"], + "note": "", + "isFood": False, + "disableAmount": True, + }) + else: + ingredients.append(self._build_ingredient(item)) else: # Legacy: plain string ingredients.append({ @@ -235,6 +245,7 @@ class MealieClient: r = self.session.put( f"{self.api_url}/api/recipes/{slug}/image", files=files, + data={"extension": ext}, timeout=30, ) r.raise_for_status() diff --git a/app/scraper.py b/app/scraper.py index bf388a6..795985f 100644 --- a/app/scraper.py +++ b/app/scraper.py @@ -61,9 +61,16 @@ def _parse_mindmegette(soup: BeautifulSoup, url: str) -> dict: image_url = _og(soup, "og:image") # --- Ingredients --- + # Multiple div.ingredients containers may exist (one per group). + # Group title: A habaráshoz: ingredients = [] - ing_container = soup.find("div", class_="ingredients") - if ing_container: + for ing_container in soup.find_all("div", class_="ingredients"): + # Check for a group title + group_el = ing_container.find("strong", class_="ingredients-group") + group_name = _text(group_el).rstrip(":").strip() if group_el else "" + if group_name: + ingredients.append({"group": group_name}) + for row in ing_container.find_all("div", class_="ingredients-meta"): # Actual HTML: qty unit # name (extra) diff --git a/app/templates/import.html b/app/templates/import.html index 34d6c9c..d89efb6 100644 --- a/app/templates/import.html +++ b/app/templates/import.html @@ -52,6 +52,31 @@ line-height: 1; flex-shrink: 0; } + .ingredient-group { + display: flex; + gap: 0.5rem; + align-items: center; + margin: 0.8rem 0 0.3rem; + } + .ingredient-group input { + margin-bottom: 0; + flex: 1; + font-weight: 600; + color: var(--accent); + border-style: dashed; + } + .ingredient-group button { + background: var(--danger); + border: none; + color: #fff; + width: 28px; + height: 28px; + border-radius: 4px; + cursor: pointer; + font-size: 1rem; + line-height: 1; + flex-shrink: 0; + } .instruction-row { display: flex; gap: 0.5rem; @@ -144,7 +169,10 @@ Megjegyzés
- +
+ + +
@@ -236,6 +264,11 @@ function populatePreview(r) { function addIngredient(item) { if (typeof item === 'string') item = { food: item }; + // Group header marker + if (item.group !== undefined && item.food === undefined) { + addIngredientGroup(item.group); + return; + } const list = document.getElementById('ingredientsList'); const row = document.createElement('div'); row.className = 'ingredient-row'; @@ -247,6 +280,15 @@ function addIngredient(item) { list.appendChild(row); } +function addIngredientGroup(name) { + const list = document.getElementById('ingredientsList'); + const row = document.createElement('div'); + row.className = 'ingredient-group'; + row.innerHTML = '' + + ''; + list.appendChild(row); +} + function addInstruction(value) { const list = document.getElementById('instructionsList'); const idx = list.children.length + 1; @@ -271,13 +313,18 @@ function renumberInstructions() { function gatherRecipe() { const ingredients = []; - document.querySelectorAll('#ingredientsList .ingredient-row').forEach(row => { - const qty = row.querySelector('.ing-qty').value.trim(); - const unit = row.querySelector('.ing-unit').value.trim(); - const food = row.querySelector('.ing-food').value.trim(); - const extra = row.querySelector('.ing-extra').value.trim(); - if (food || qty) { - ingredients.push({ quantity: qty, unit: unit, food: food, extra: extra }); + document.querySelectorAll('#ingredientsList > div').forEach(el => { + if (el.classList.contains('ingredient-group')) { + const name = el.querySelector('.ing-group-name').value.trim(); + if (name) ingredients.push({ group: name }); + } else if (el.classList.contains('ingredient-row')) { + const qty = el.querySelector('.ing-qty').value.trim(); + const unit = el.querySelector('.ing-unit').value.trim(); + const food = el.querySelector('.ing-food').value.trim(); + const extra = el.querySelector('.ing-extra').value.trim(); + if (food || qty) { + ingredients.push({ quantity: qty, unit: unit, food: food, extra: extra }); + } } });