README.md (4211B)
1 # Anton 2 3 A self-hosted Telegram bot for tracking recipes, managing a weekly staples 4 list, and generating grocery lists. Runs as a long-polling service — no 5 public webhook or reverse proxy needed. See `CLAUDE.md` for coding 6 conventions/hard constraints and `SPEC.md` for the original project plan. 7 8 ## Setup 9 10 ```bash 11 python3 -m venv .venv 12 .venv/bin/pip install -r requirements.txt 13 cp .env.example .env # then fill in TELEGRAM_BOT_TOKEN (get one from @BotFather) 14 .venv/bin/python3 bot.py 15 ``` 16 17 The SQLite database is created automatically on first run at the path set 18 by `ANTON_DB_PATH` in `.env` (defaults to `anton.db` in the working 19 directory). 20 21 ## Testing 22 23 ```bash 24 .venv/bin/pytest 25 ``` 26 27 Covers quantity parsing, grocery-list merge logic, category grouping, and 28 the recipe-text parser. There's no automated coverage of the Telegram 29 wiring itself — that needs manual testing against a real bot token. 30 31 ## Commands 32 33 - `/addrecipe` — add a recipe; the bot asks for a name, then you paste the 34 ingredients (freeform text copied straight from a recipe site works, or 35 the structured `<quantity> | <unit> | <name> | <category>` format for 36 precise merging later). Long pastes can span multiple messages — send 37 `/done` when finished, `/cancel` to abort. 38 - `/recipes [tag/group/keyword]` — list recipes. `keto` filters by the 39 auto-suggested keto tag; a manually-created group matches next (e.g. 40 `/recipes slowcooker`); anything else searches recipe names. An exact 41 name shows that recipe's ingredients instead of a list. 42 - `/recipe <name>` — show one recipe's ingredients. 43 - `/instructions <name>` — show one recipe's instructions. 44 - `/instructions add <name>` — paste instructions for a recipe (replaces 45 any existing ones); spans multiple messages the same way `/addrecipe` 46 does, send `/done` when finished. 47 - `/instructions delete <name>` — clear a recipe's instructions. 48 - `/tag <group>` — list recipes tagged with a group (e.g. `/tag beef`). 49 - `/tag add <group>` — create a new, empty group. 50 - `/tag add <recipe name>, <group>` — tag a recipe with a group (creates 51 the group if it doesn't exist yet). 52 - `/tag remove <group>` — delete a group entirely, untagging it from 53 every recipe. 54 - `/tag remove <recipe name>, <group>` — untag one recipe, group stays. 55 - `/tags` — list all groups and how many recipes are in each. 56 - `/staples` — show the staples list. 57 - `/staples add <item>` / `/staples remove <item>`. 58 - `/grocerylist [recipe1, recipe2, ...]` — merge staples plus named 59 recipes into one list, quantities summed where they can be, grouped by 60 ingredient category (anything uncategorized lands in one plain 61 leftover section rather than being guessed at). 62 - `/add <item>` — freeform one-off add to the current grocery list. 63 - `/clearlist` — reset the working grocery list. 64 - `/random [tag]` — random recipe suggestion, optionally filtered. 65 - `/help` — show the command list from inside Telegram. 66 67 ## Known limitations 68 69 - Ingredient merging (summing quantities across recipes/staples) only 70 works for ingredients entered in the structured `qty | unit | name | 71 category` format. Freeform-pasted ingredients (the common case) have no 72 parsed quantity/unit, so they're never summed — they just show up as 73 separate line items. 74 - Keto tagging is a rough keyword heuristic (flags things like flour, 75 sugar, rice, potato), not a real nutrition calculation. Always manually 76 overridable. 77 - No recipe-URL fetching — `/addrecipe` is paste-only. 78 79 ## Deployment 80 81 `anton-bot.service` (systemd unit) and `install.sh` are provided for 82 deploying to a Proxmox LXC/VM, per `SPEC.md`. `install.sh` stages a full 83 copy of the repo, installs dependencies, and runs the test suite against 84 that staged copy — it only touches the live install and running service if 85 those tests pass, so a broken update never overwrites a working one. Read 86 the comments at the top of `anton-bot.service` for the manual steps 87 (create a system user, set up `.env`, etc.) before running it: 88 89 ```bash 90 sudo ./install.sh 91 ``` 92 93 Config (bot token, DB path) is always via `.env` / environment variables — 94 never hardcoded, never committed (`.gitignore` excludes `.env` and `*.db`).