chore: initial import
This commit is contained in:
@@ -0,0 +1,216 @@
|
||||
# boehmitools
|
||||
|
||||
Ein Dashboard, unter dem alle Tools zusammenlaufen. Jedes Tool bleibt dabei
|
||||
eigenständig — es liegt als Plugin in `plugins/<name>/`, hat sein eigenes
|
||||
Backend und seinen eigenen Datenordner. Gemeinsam sind das Design, die
|
||||
Zugangsdaten und das Dach.
|
||||
|
||||
```
|
||||
Dashboard /
|
||||
├── Trainingsplan- & Rezept-Editor /plugins/trainingsplan
|
||||
├── Tandoor AI Import /plugins/tandoor-ai-import
|
||||
├── Rezept-Inventur /plugins/tandoor-lint
|
||||
├── Stammdaten aufräumen /plugins/tandoor-cleanup
|
||||
├── Nährwerte vervollständigen /plugins/tandoor-nutrition
|
||||
├── Zutaten-Kategorien /plugins/tandoor-categories
|
||||
└── Einheiten-Umrechnungen /plugins/tandoor-conversions
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Starten
|
||||
|
||||
### Docker (empfohlen)
|
||||
|
||||
```bash
|
||||
cd boehmitools
|
||||
cp .env.example .env
|
||||
nano .env # mindestens APP_PASSWORD setzen
|
||||
docker compose up -d --build
|
||||
```
|
||||
|
||||
Dann im Browser: `http://<server-ip>:8080`
|
||||
|
||||
Port ändern: in der `.env` `APP_PORT=9090` setzen.
|
||||
Logs: `docker compose logs -f` · Stoppen: `docker compose down`
|
||||
|
||||
### Direkt mit Python
|
||||
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
python run.py # Standard-Port 8080
|
||||
PORT=9090 python run.py # anderer Port
|
||||
```
|
||||
|
||||
Für die Entwicklung mit automatischem Neuladen:
|
||||
|
||||
```bash
|
||||
uvicorn core.app:app --reload --port 8080
|
||||
```
|
||||
|
||||
## Einrichten
|
||||
|
||||
Nach dem ersten Start einmal auf **Einstellungen** (⚙ oben rechts):
|
||||
|
||||
| Gruppe | wird gebraucht von |
|
||||
|---|---|
|
||||
| **Tandoor** — URL, Token, Auth-Schema | AI Import, Rezept-Inventur, Stammdaten, Nährwerte |
|
||||
| **OpenAI** — API-Key, Modell | AI Import |
|
||||
| **Rezeptquellen** — TLS, Timeouts, private IPs | AI Import |
|
||||
|
||||
Die Werte landen in `data/settings.json` und werden den Tools als
|
||||
Umgebungsvariablen übergeben — genau so, wie die Tools sie als Einzelprogramm
|
||||
erwarten. Wer lieber alles in der `.env` pflegt, kann das weiterhin tun: Diese
|
||||
Werte gelten als Vorgabe, solange in der Oberfläche nichts eingetragen ist.
|
||||
|
||||
> Ohne `APP_PASSWORD` ist die Oberfläche ungeschützt. Der Schutz gilt dann für
|
||||
> das Dashboard und alle Tools gemeinsam.
|
||||
|
||||
## Die Tools
|
||||
|
||||
### 🏋 Trainingsplan- & Rezept-Editor
|
||||
Der 8-Wochen-Calisthenics-Plan und die vier Rezeptsammlungen, im Browser
|
||||
bearbeitbar und per Klick als PDF. Phasen anlegen, duplizieren, exportieren.
|
||||
Der ReportLab-Renderer ist unverändert der aus dem Einzeltool — das Layout
|
||||
bleibt identisch.
|
||||
|
||||
### 🥕 Tandoor AI Import (v1.1)
|
||||
URL einfügen → Seite sicher auslesen → OpenAI strukturiert das Rezept →
|
||||
Vorschau, Warnungen und Zuordnungen prüfen → bewusst importieren → Verifikation,
|
||||
bei Fehlern Rollback. Jeder Durchlauf wird unter
|
||||
`data/tandoor-ai-import/runs/<RUN-ID>/` protokolliert.
|
||||
|
||||
Jede Zutat hat ein **Dropdown** mit den passenden Tandoor-Einträgen, der beste
|
||||
Treffer ist vorausgewählt. Gesucht wird über Singular, Plural und Teilwörter —
|
||||
`Kartoffeln` findet `Kartoffel`. Passt nichts, lässt sich über das Textfeld mit
|
||||
einem anderen Namen erneut suchen oder der Eintrag per `➕ Neu anlegen` beim
|
||||
Import erzeugen. Scheitert der Import, werden Rezept **und** die in diesem Lauf
|
||||
neu angelegten Stammdaten zurückgerollt.
|
||||
|
||||
### 🔍 Rezept-Inventur
|
||||
Geht die Sammlung durch und meldet, was fehlt: Rezepte ohne Quelle, Bild,
|
||||
Portionsangabe oder Arbeitszeit, Zutaten ohne Einheit oder Menge, Schritte ohne
|
||||
Text, doppelte Rezeptnamen, verwaiste Zutaten/Einheiten/Schlagworte. **Liest
|
||||
ausschließlich** — es gibt keinen schreibenden Endpunkt. Befunde filterbar,
|
||||
Export als CSV.
|
||||
|
||||
### 🧹 Stammdaten aufräumen
|
||||
Führt doppelte Zutaten, Einheiten und Schlagworte zusammen und findet
|
||||
Karteileichen. Vorgeschlagen wird nur, was praktisch sicher dasselbe ist
|
||||
(`Zwiebel`/`Zwiebeln`, `Vegan`/`vegan`); Grenzfälle wie `Sahne`/`Schlagsahne`
|
||||
stehen nur zur Ansicht. Tandoor verwirft beim Zusammenführen die Nährwerte des
|
||||
Quelleintrags — dieses Tool rettet sie vorher ans Ziel. Trockenübung,
|
||||
Einzelfreigabe und Sicherung je Schritt. Löschen ist nie vorausgewählt.
|
||||
|
||||
### 🥑 Nährwerte vervollständigen
|
||||
Zeigt, bei welchen Zutaten Eigenschaften fehlen (Abdeckung je Eigenschaft,
|
||||
Lücken nach Rezeptzahl sortiert), lässt sie je 100 g schätzen und schreibt sie
|
||||
nach Prüfung zurück. Jeder Wert ist vor dem Schreiben editierbar. Vorhandene
|
||||
Werte bleiben unangetastet, fehlende Bezugsmengen werden mitgesetzt.
|
||||
Die Zahlen sind Schätzungen eines Sprachmodells, keine Laboranalysen.
|
||||
|
||||
|
||||
### 🏷 Zutaten-Kategorien
|
||||
Ordnet Zutaten ohne Supermarkt-Kategorie einer der vorhandenen
|
||||
Kategorien zu — auf Wunsch von ChatGPT vorgeschlagen. Es werden nur
|
||||
bestehende Kategorien vergeben, jede Zuweisung ist freizugeben und voll
|
||||
rückspielbar.
|
||||
|
||||
### 🔁 Einheiten-Umrechnungen
|
||||
Findet Zutaten, die in Rezepten mit mehreren, nicht ohne Weiteres
|
||||
umrechenbaren Einheiten vorkommen (z. B. Stück und g) und wofür noch
|
||||
keine Umrechnung hinterlegt ist. ChatGPT schlägt sinnvolle Werte vor —
|
||||
diese sind Schätzungen und vor dem Eintragen zu prüfen. Angelegte
|
||||
Umrechnungen sind über die Sicherungen wieder löschbar.
|
||||
## Ein neues Tool hinzufügen
|
||||
|
||||
Es gibt zwei Wege:
|
||||
|
||||
**Hochladen.** Das Plugin als ZIP packen und im Dashboard auf **„Plugin
|
||||
importieren“** — fertig. Erkannt wird es an der `id` aus seiner `plugin.json`;
|
||||
ist die schon vorhanden, wird jene Fassung aktualisiert. Dabei wird nur ergänzt
|
||||
und überschrieben, **nie gelöscht**, und der Datenordner bleibt unberührt. Der
|
||||
bisherige Stand wandert vorher in eine Sicherung unter
|
||||
`data/_plugin-sicherungen/<id>/`.
|
||||
|
||||
**Direkt ablegen.** Ordner unter `plugins/<name>/` anlegen, `plugin.json` und
|
||||
`backend.py` dazulegen und im Dashboard **„Plugins neu laden“** klicken — die
|
||||
Karte erscheint sofort, ohne die Suite neu zu starten. Der Knopf liest `plugins/` neu
|
||||
ein, hängt neue oder geänderte Tools frisch ein und entfernt gelöschte. (Nur
|
||||
Änderungen unter `core/` selbst brauchen weiterhin einen echten Neustart.)
|
||||
Die vollständige Bauanleitung samt Design-Bausteinen steht in
|
||||
**[`plugins/README.md`](plugins/README.md)**.
|
||||
|
||||
## Aufbau
|
||||
|
||||
```
|
||||
boehmitools/
|
||||
├── run.py Start
|
||||
├── core/ Host: Dashboard, Plugin-Lader, Einstellungen, Jobs
|
||||
│ ├── app.py mountet jedes Plugin unter /plugins/<id>
|
||||
│ ├── registry.py liest plugin.json, lädt backend.py
|
||||
│ ├── settings.py data/settings.json ⇄ Umgebungsvariablen
|
||||
│ ├── jobs.py Subprozess-Läufe mit Live-Protokoll (SSE)
|
||||
│ ├── loader.py kollisionsfreier Import der Tool-Module
|
||||
│ └── static/ Dashboard, Einstellungen, Läufe
|
||||
├── shared/ das gemeinsame Aussehen
|
||||
│ ├── boehmi.css Design-System (hell/dunkel)
|
||||
│ ├── boehmi.js App-Bar, Tool-Umschalter, BT.api/BT.toast
|
||||
│ └── boehmi-runner.js Protokoll-Ansicht für Kommandozeilen-Tools
|
||||
├── plugins/ ein Ordner je Tool ← hier wächst der Baukasten
|
||||
└── data/ alles Veränderliche (Volume)
|
||||
├── settings.json
|
||||
├── trainingsplan/plans/
|
||||
├── tandoor-ai-import/runs/
|
||||
├── tandoor-cleanup/laeufe/
|
||||
└── tandoor-nutrition/laeufe/
|
||||
```
|
||||
|
||||
Ein Backup ist das Sichern des Ordners `data/`.
|
||||
|
||||
## Tools weiterhin einzeln starten
|
||||
|
||||
Jedes Plugin ist für sich lauffähig geblieben:
|
||||
|
||||
```bash
|
||||
cd plugins/trainingsplan && python app.py
|
||||
cd plugins/tandoor-ai-import && uvicorn app.main:app --port 8091
|
||||
```
|
||||
|
||||
Die Original-Anleitungen der Tools liegen als `TOOL-README.md` bzw.
|
||||
`TOOL-README.txt` in den jeweiligen Plugin-Ordnern; beim AI-Import steht in
|
||||
`TOOL-UPGRADE.md` zusätzlich, was v1.1 geändert hat.
|
||||
|
||||
## Hinweise
|
||||
|
||||
- Gedacht für das **lokale Netzwerk**. Wenn erreichbar: `APP_PASSWORD` setzen
|
||||
oder einen Reverse Proxy davorsetzen.
|
||||
- Die Tokens verlassen das Backend nicht; OpenAI bekommt ausschließlich die
|
||||
extrahierten Rezeptdaten und die Quell-URL.
|
||||
- Läuft die Suite hinter einem Reverse Proxy in einem Unterpfad, in den
|
||||
HTML-Seiten `<meta name="bt-root" content="/unterpfad">` ergänzen.
|
||||
|
||||
|
||||
## Sicherungen und Zurückspielen
|
||||
|
||||
Die beiden Plugins, die etwas in Tandoor verändern, schreiben vor jeder Änderung
|
||||
eine Sicherung und lassen sich über einen Reiter „Sicherungen“ wieder
|
||||
zurückspielen. Jeder Lauf, der wirklich schreibt, landet unter
|
||||
`data/<plugin>/laeufe/<zeit>/` samt einer `manifest.json`, in der Schritt für
|
||||
Schritt steht, was geändert wurde und wie der Zustand vorher war.
|
||||
|
||||
Wie weit ein Lauf zurückgeholt werden kann, hängt vom Eingriff ab und steht
|
||||
ehrlich an jedem Lauf:
|
||||
|
||||
* **🥑 Nährwerte** – *vollständig rückspielbar.* Die alten Werte werden exakt
|
||||
zurückgeschrieben. Wurde eine Zutat seither von Hand geändert, wird sie
|
||||
erkannt und übersprungen.
|
||||
* **🧹 Stammdaten** – *teilweise rückspielbar.* Zusammengeführte und gelöschte
|
||||
Einträge werden neu angelegt und die aufgezeichneten Rezeptverweise
|
||||
zurückgehängt. Die alte ID ist in Tandoor vergeben und kommt nicht zurück;
|
||||
Einkaufslisten, Umrechnungen und Automatisierungen bleiben beim Ziel. Das
|
||||
Werkzeug zeichnet dafür vor jedem Zusammenführen alle Rezeptverweise auf.
|
||||
|
||||
Zurückspielen gibt es immer als Trockenübung zuerst. Jeder Lauf, der schon
|
||||
einmal zurückgespielt wurde, ist markiert und muss ausdrücklich bestätigt
|
||||
werden.
|
||||
Reference in New Issue
Block a user