diff options
| author | Ahmed <git@gumx.cc> | 2026-06-14 01:46:29 +0300 |
|---|---|---|
| committer | Ahmed <git@gumx.cc> | 2026-06-14 01:46:29 +0300 |
| commit | 5a8d568931d9b23ce0df1265d05259a7012081c9 (patch) | |
| tree | 4ea19b8bb1763a38246f342f172c285f6579e09b /dev-docs/contessa.md | |
init: mostly vibed
Diffstat (limited to 'dev-docs/contessa.md')
| -rw-r--r-- | dev-docs/contessa.md | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/dev-docs/contessa.md b/dev-docs/contessa.md new file mode 100644 index 0000000..07b4140 --- /dev/null +++ b/dev-docs/contessa.md @@ -0,0 +1,92 @@ +# contessa - developer documentation + +## Overview + +Contessa is a recipe suggestion bot. It loads a JSON recipe file at startup +and serves random suggestions or full recipes on demand. There is no external +API, no database, and no persistent state beyond what is in memory. + +--- + +## Module structure + +``` +contessa/ + commands.py - all commands and recipe logic + recipes.json - bundled recipe data + __init__.py - empty +``` + +--- + +## Data loading + +Recipes are loaded once in `setup()` and stored in `bot.memory["ct_recipes"]`. +The structure is a dict with meal-type keys mapping to lists of dish objects: + +```json +{ + "breakfast": [{"name": "...", "description": "...", "ingredients": [...], "steps": [...]}], + "lunch": [...], + "dinner": [...], + "snack": [...] +} +``` + +If the file is missing or malformed, `setup()` catches the exception and +initializes all categories to empty lists. The bot will respond with "no +recipes loaded" rather than crashing. + +There is no hot-reload. A restart is required to pick up changes to the +recipe file. + +--- + +## Recipe lookup + +`_find_dish()` does two passes over all categories: +1. Exact name match (case-insensitive) +2. Substring match (case-insensitive) + +This order matters. If someone has a dish named "Rice" and another named +"Rice Pudding", searching for "rice" returns "Rice" not "Rice Pudding". The +first exact match wins. + +The function is a generator consumer over `_all_dishes()`, which yields +`(category, dish)` tuples from all categories. The double traversal (once +for exact, once for partial) is acceptable given that recipe sets are small. + +--- + +## Output format + +`_fmt_recipe()` returns three strings meant to be sent as three separate IRC +messages: +1. Name and description +2. Ingredients joined by comma +3. All steps joined into one line, numbered + +The steps line can get long for recipes with many steps. IRC servers typically +truncate or drop messages over ~512 bytes. This is a known limitation. The +decision to keep steps on one line was made to minimize flood (three messages +per recipe is already pushing it in a shared channel). + +--- + +## Channel requirement + +All meal and recipe commands require channel context (`@plugin.require_chanmsg`). +The admin commands (join, part, chans, help) do not, since the owner needs to +manage the bot from PM. + +--- + +## Config + +| Key | Default | Description | +|-----|---------|-------------| +| `[contessa] recipes_path` | `/var/contessa/recipes.json` | Path to recipe JSON | + +The bundled `recipes.json` contains 24 recipes per category (96 total) covering +Egyptian, Middle Eastern, and Western dishes. It is the default data file and +can be replaced or extended without code changes. |
