aboutsummaryrefslogtreecommitdiffstats
path: root/dev-docs/contessa.md
blob: 07b4140c7a855c8fb50b0448de4c9d9271e87bad (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
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.