# Recipe Image Ingestion Spec **Goal:** Give every `.cook` recipe file in the repository a high-quality, relevant food image hosted at `https://roux.roo.lol/recipe-images/` and referenced in its YAML frontmatter. ## Scope | Category | Count | Action | |---|---|---| | Has YAML frontmatter + already has `image:` | 19 | Download existing image, re-host, update URL | | Has YAML frontmatter + no `image:` | 48 | Find + download image, add `image:` field | | No YAML frontmatter | 9 | Add frontmatter with title, find + download image, add `image:` field | | **Total** | **76** | | ## Image Filename Convention Slugify the `.cook` filename stem: 1. Strip `.cook` extension 2. Lowercase 3. Replace runs of non-alphanumeric characters (spaces, punctuation, `&`, etc.) with a single hyphen 4. Strip leading/trailing hyphens 5. Append `.webp` **Examples:** - `Black Bean and Corn Salad.cook` → `black-bean-and-corn-salad.webp` - `BUTTERNUT & TURKEY CHILI with sweet peppers, spiced pepitas & queso fresco.cook` → `butternut-turkey-chili-with-sweet-peppers-spiced-pepitas-queso-fresco.webp` - `Chickpea_Butter_Curry.cook` → `chickpea-butter-curry.webp` ## Image URL Format ``` https://roux.roo.lol/recipe-images/.webp ``` ## Image Sourcing ### For recipes that already have an `image:` field - Download the image from its current URL (e.g., `https://kitchen.roo.lol/data/images/.webp`) - Save locally as `.webp` - Update the `image:` field to `https://roux.roo.lol/recipe-images/.webp` ### For recipes without an `image:` field - Use the recipe title (from frontmatter or content) to search for a relevant, free-to-use food image online - Prefer reputable recipe sites, Unsplash/Pexels, or other permissively-licensed sources - Download as `.webp` - Add `image: https://roux.roo.lol/recipe-images/.webp` to the frontmatter ### For recipes without frontmatter - Parse the recipe content to determine a title (from context, first line, or filename) - Construct minimal YAML frontmatter: `---`, `title: `, `---` - Find and download image as above - Insert frontmatter + image field above the recipe body ## Implementation Approach 1. **Batch by category** to minimize context switching: - Batch 1: 19 existing-image recipes (download + relink) - Batch 2: 48 no-image recipes with frontmatter (find + download + add field) - Batch 3: 9 no-frontmatter recipes (create frontmatter + find + download + add field) 2. **For image discovery**, use a web-search agent to find an appropriate image URL for each recipe, then download via `curl`. 3. **Parallelize** image discovery across multiple subagent workers to keep total time reasonable. ## Edge Cases - **Duplicate-ish recipes** (e.g., `butternut-turkey-chili.cook`, `Butternut Turkey Chili.cook`, `BUTTERNUT & TURKEY CHILI...`): Each gets its own image slug. They may share similar images, but each file gets its own entry. - **Image download failure**: If an image URL is unreachable (for existing images) or no suitable image is found (for new ones), log the recipe slug and skip it. - **Special characters in filenames**: Slugify handles `&`, `'`, `(`, `)`, etc. by collapsing them into hyphens. - **Existing image URLs that are already in the target format**: Skip re-download (they're already correct). - **Non-WebP source images**: Downloaded images should be saved as `.webp`. If the source is not WebP, use `ffmpeg` or `convert` to re-encode.