Excel import
A one-time converter from Wochenspeiseplan.xlsm to a Recipe Bundle (format) that you then import into CookIt on the phone. The workbook and the bundle are private data and stay out of git.
cd tools/excel-import
python -m venv .venv
.venv/Scripts/pip install -r requirements.txt # Windows; use .venv/bin/pip elsewhere
.venv/Scripts/python convert.py ../../Wochenspeiseplan.xlsm
# -> out/cookit-rezepte.zip; copy it to the phone and use Einstellungen → Rezepte importieren
.venv/Scripts/python -m pytest
The tests in tests/test_workbook.py run only when the workbook is at the repo root, or wherever COOKIT_WORKBOOK points.
What it does
- Reads every sheet built from the recipe template (
C2 = Menge,E2 = Zutat) and skipsLeeres RezeptandSpinat-Feta-Pizza. - Ingredients: C/D/E from row 3 down.
- A blank row starts a new (unnamed) Ingredient Group.
- An
ODERrow starts a group named "Alternative". - Cell comments such as "Zutaten für die Sauce" name the group starting at that row.
- Units are mapped to canonical keys, including typos.
- "100 g" typed into the unit column is split into amount and unit.
- Rows without an ingredient name that hold only numbers (left over from rescaling) are dropped.
- A repeated copy of the ingredient list is dropped.
- Steps: text from the F column.
- Blank lines separate Steps.
- If there are no blank lines, each line is a Step.
- Short lines ("Teig", "Soße:") and inline headings ("Salat:Die Zwiebel…") become Step Sections.
- Calories: more than 1500 kcal counts as the whole recipe, otherwise per serving. A "Pro Portion" comment on the cell settles it. The guess isn't flagged: on review it matched every value in the workbook.
- Notes & Sources:
- The comment field (B12) and any cell outside the template go into Notes, one line per sheet row.
- URLs anywhere become Sources.
- The template text "Löschen Sie dieses Rezeptarbeitsblatt nicht." is dropped.
- Photos: pictures on the sheet, top-left first, re-encoded as JPEG, at most 1600 px. The template's stock picture (copied onto every sheet made from
Leeres Rezept) is dropped, so those Recipes simply have no Photo. - Review Flags: anything the converter guessed or moved adds a German reason to
reviewReasons, shown in the app under "zu prüfen". - IDs: Recipe IDs come from the sheet name (UUIDv5), so converting again gives the same IDs and a second import skips Recipes already there.