From 716b09274b39e81ff452bbd943d8abac281c9950 Mon Sep 17 00:00:00 2001 From: neingeist Date: Wed, 18 Jun 2025 23:03:32 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=9A=A7=20fruehstueck.*?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- fruehstueck.csv | 14 ++++++ fruehstueck.py | 118 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 132 insertions(+) create mode 100644 fruehstueck.csv create mode 100644 fruehstueck.py diff --git a/fruehstueck.csv b/fruehstueck.csv new file mode 100644 index 0000000..e2fa07a --- /dev/null +++ b/fruehstueck.csv @@ -0,0 +1,14 @@ +title;url;isVegan;ingredients;comment +Mungobohnenhummus mit Jalapenos und Zatar;https://entropia.de/GPN23:Mungobohnenhummus_mit_Jalapenos_und_Zatar;1;Mungobohnen, Olivenöl, Tahini (\Alg{Sesam}), Jalapenoringe, eingelegt, fein gehackt, Knoblauch, Zatar (\Alg{Sesam, mgw. Senf und Sellerie}), Kreuzkümmel (Cumin), Zitronensaft; +Rauchige Schwarze Bohnencreme;https://entropia.de/GPN23:Rauchige_Schwarze_Bohnencreme;1;Zwiebeln, Schwarze Bohnen, gekocht, Erdnussmus (\Alg{Erdnuss}), Tomatenmark, Knoblauch, Pflanzenöl, Hefeflocken, Rauchpaprika (Pimentón de la Vera), Salz, Pfeffer (schwarz), Majoran, Wasser; +Gulaschmarmelade;https://entropia.de/GPN23:Gulaschmarmelade;1;Paprika, rot oder gemischt, Gelierzucker 3:1, Chilischoten, Salz, Branntweinessig; +Bagel;https://entropia.de/GPN23:Bagel;1;Mehl (\Alg{Gluten}), Malzsirup (\Alg{Gluten}), Salz, Trockenhefe, Wasser; +Granatapfelcreme;https://entropia.de/GPN23:Granatapfelcreme;1;Paprika, Cashewkerne (\Alg{Nüsse (Cashew)}), Paniermehl (\Alg{Gluten}), Knoblauch, Granatapfelsirup, Tomatenmark, Salz, Harissa, Paprikapulver, Pfeffer (schwarz); +Kattis Hummus;https://entropia.de/GPN23:Kattis_Hummus;1;Kichererbsen, Tahini (\Alg{Sesam}), Olivenöl, Zitronensaft, Knoblauch, Kreuzkümmel (Cumin), Salz, Pfeffer (schwarz), Petersilie, glatt; +GPN-Tomatenbutter;https://entropia.de/GPN23:GPN-Tomatenbutter;1;Margarine (\Alg{\faExclamationTriangle verwendetes Produkt prüfen}), Getrocknete Tomaten, Knoblauch, Rosmarin, Salz, Pfeffer (schwarz), Cayennepfeffer; +Erbsenhummus;https://entropia.de/GPN23:Erbsenhummus;1;Erbsen, Knoblauch, Petersilie, Zitronenschale, Zitronensaft, Tahini (\Alg{Sesam}), Olivenöl, Wasser, Kreuzkümmel (Cumin), Cayennepfeffer, Salz; +Franzbrötchen;https://entropia.de/GPN23:Franzbrötchen;1;Weizenmehl (Type 550) (\Alg{Gluten}), Margarine (\Alg{\faExclamationTriangle verwendetes Produkt prüfen}), Wasser, Zimtzucker, Weizenvollkornmehl (\Alg{Gluten}), Zucker, altes Weizenanstellgut TA 200 (\Alg{Gluten}), Frischhefe, Salz, Läuterzucker; +Cashew-Streichkäse;https://entropia.de/GPN23:Cashew-Streichkäse;1;Cashewkerne (\Alg{Nüsse (Cashew)}), Getrocknete Tomaten, Hefeflocken, Salz, Paprikapulver, Chiliflocken, Wasser; +Schwarzwaldbutter;https://entropia.de/GPN23:Schwarzwaldbutter;1;Margarine (\Alg{\faExclamationTriangle verwendetes Produkt prüfen}), Kräuter gemischt (8-Kräuter), Fichtenspitzen, Knoblauch, Salz, Pfeffer (schwarz); +Matelade Apfel;https://entropia.de/GPN23:Matelade_Apfel;1;Gelierzucker 1:1, Äpfel, Zitrone, Limetten, Club Mate, Matetee; +Levervurst;https://entropia.de/GPN23:Levervurst;1;Kidneybohnen, Räuchertofu (\Alg{Soja}), Zwiebeln, Senf (\Alg{Senf}), Knoblauch, Petersilie, Majoran, Paprikapulver, Salz, Pfeffer (schwarz); diff --git a/fruehstueck.py b/fruehstueck.py new file mode 100644 index 0000000..021562f --- /dev/null +++ b/fruehstueck.py @@ -0,0 +1,118 @@ +import json +import sys +from pathlib import Path +from datetime import timedelta +import re +import os +from tqdm import tqdm +import csv +from collections import defaultdict + +from config import * + + +def grams(ingredient): + conversion = None + for c in ingredient["conversions"]: + if c["unit"] in ["g / Gramm", "g"]: + conversion = c + if conversion: + return conversion.get('amount') + + +def allergens_for_step_ingredients(step): + l = [] + for ingredient in step["ingredients"]: + if not ingredient.get("food"): + raise ValueError("No food in ingredient") + continue + i_grams = grams(ingredient) + i_name = ingredient["food"]["name"] + i_description = ingredient["food"]["description"] + + if match := re.search(r"^Allergene: (.*)$", i_description, re.MULTILINE): + i_allergens = match.group(1) + else: + i_allergens = "❗ keine Allergene hinterlegt" + + l.append((i_grams, i_name, i_allergens)) + + return l + + +def allergens_for_recipe(recipe): + l = [] + for step in recipe["steps"]: + l += allergens_for_step_ingredients(step) + return l + + +def link(recipe): + return f"{TANDOOR_URL + "/view/recipe/" + str(recipe["id"])}" + +def wiki_link(recipe): + wiki_slug = recipe["name"] + wiki_slug = re.sub(" ", "_", wiki_slug) + return f"{WIKI_URL + WIKI_ARTICLE_PREFIX + wiki_slug}" + + +def decruft_ingredient(i_name: str): + i_name = i_name.replace(" (trocken)", "") + i_name = i_name.replace(" (frisch)", "") + i_name = i_name.replace(" (TK)", "") + i_name = i_name.replace(" (Dose)", "") + i_name = i_name.replace(" (getrocknet)", "") + return i_name + + +def aggregate_zutaten(data): + result = defaultdict(int) + for grams, item in data: + result[item] += grams + return [(g, n) for n, g in result.items()] + + +def main(): + + Path("fruehstueck.csv").unlink(missing_ok=True) + + recipes = [] + for json_file in os.listdir(OUTDIR_JSON): + with open(os.path.join(OUTDIR_JSON, json_file), "r", encoding="utf-8") as f: + data = json.load(f) + recipes.append(data) + + # filter "Frühstück" + recipes = [r for r in recipes if any(k["name"] == "Fr\u00fchst\u00fcck" for k in r["keywords"])] + + with open("fruehstueck.csv", "w") as f: + fwriter = csv.writer(f, delimiter=';', quotechar='"', quoting=csv.QUOTE_MINIMAL) + fwriter.writerow(["title", "url", "isVegan", "ingredients", "comment"]) + + for recipe in recipes: + zutaten = [] + for i_grams, i_name, i_allergens in allergens_for_recipe(recipe): + if i_grams is None: + i_grams = 0 + + zn = decruft_ingredient(i_name) + if i_allergens != "(keine)": + i_allergens = i_allergens.replace("⁉\ufe0f", "\\faExclamationTriangle") + zn += f" (\\Alg{{{i_allergens}}})" + + zutaten.append((i_grams, zn)) + + zutaten = aggregate_zutaten(zutaten) + zutaten.sort(key=lambda z: z[0], reverse=True) + + fwriter.writerow([ + recipe["name"], + wiki_link(recipe), + 1, # XXX hardcoded + ", ".join(z[1] for z in zutaten), + "" + ]) + + +if __name__ == "__main__": + main()