diff --git a/Alain-Ducase-Bread.cook b/Alain-Ducase-Bread.cook index c0a7b0b..7fdee41 100644 --- a/Alain-Ducase-Bread.cook +++ b/Alain-Ducase-Bread.cook @@ -16,6 +16,7 @@ tags: - french +image: https://roux.roo.lol/recipe-images/alain-ducase-bread.webp --- diff --git a/Apple Cider Vinegar Dressing.cook b/Apple Cider Vinegar Dressing.cook index 54f9911..35284d6 100644 --- a/Apple Cider Vinegar Dressing.cook +++ b/Apple Cider Vinegar Dressing.cook @@ -3,7 +3,7 @@ title: Apple Cider Vinegar Dressing description: This homemade apple cider vinaigrette is SO much better than any store bought dressing! Made with 7 simple ingredients, it's tangy, healthy, and easy to make. servings: 6 source: https://www.loveandlemons.com/apple-cider-vinegar-dressing/ -image: https://kitchen.roo.lol/data/images/14663763-8d52-4e31-a4e8-36a7f3c6c229.webp +image: https://roux.roo.lol/recipe-images/apple-cider-vinegar-dressing.webp thumbnail: https://kitchen.roo.lol/data/images/thumbnails/14663763-8d52-4e31-a4e8-36a7f3c6c229.webp date_created: 2024-11-03 date_modified: 2024-11-03 diff --git a/Arugula Pesto Chicken with Pecans & Roasted Butternut.cook b/Arugula Pesto Chicken with Pecans & Roasted Butternut.cook index e30a247..853b321 100644 --- a/Arugula Pesto Chicken with Pecans & Roasted Butternut.cook +++ b/Arugula Pesto Chicken with Pecans & Roasted Butternut.cook @@ -20,6 +20,7 @@ tags: - pesto +image: https://roux.roo.lol/recipe-images/arugula-pesto-chicken-with-pecans-roasted-butternut.webp --- diff --git a/Arugula Pesto Wheat Berries Recipe.cook b/Arugula Pesto Wheat Berries Recipe.cook index 59fbc9f..2370708 100644 --- a/Arugula Pesto Wheat Berries Recipe.cook +++ b/Arugula Pesto Wheat Berries Recipe.cook @@ -8,6 +8,7 @@ tags: - arugula - pesto - wheat berries +image: https://roux.roo.lol/recipe-images/arugula-pesto-wheat-berries-recipe.webp --- Place the @cooked wheat berries{3%cups} in a large mixing bowl and set them aside so they can come up to room temperature if you've had them in the refrigerator. diff --git a/Asparagus Salad.cook b/Asparagus Salad.cook index 7db0ac3..fb99a47 100644 --- a/Asparagus Salad.cook +++ b/Asparagus Salad.cook @@ -10,6 +10,7 @@ tags: - salad description: A fresh spring asparagus salad with peas, radishes, feta, pine nuts, and herbs, tossed with lemon and olive oil and finished with creamy avocado dressing. source: Love and Lemons +image: https://roux.roo.lol/recipe-images/asparagus-salad.webp --- Bring a large #pot of well-salted @water{} to a boil and prepare a #bowl of @ice water{}. diff --git a/Authentic Cacio e Pepe Recipe.cook b/Authentic Cacio e Pepe Recipe.cook index c283a85..919feda 100644 --- a/Authentic Cacio e Pepe Recipe.cook +++ b/Authentic Cacio e Pepe Recipe.cook @@ -8,6 +8,7 @@ tags: - pasta - italian - quick +image: https://roux.roo.lol/recipe-images/authentic-cacio-e-pepe-recipe.webp --- In a #pot, bring @water{} to a boil. Lightly salt the water when it comes to a boil. diff --git a/BUTTERNUT & TURKEY CHILI with sweet peppers, spiced pepitas & queso fresco.cook b/BUTTERNUT & TURKEY CHILI with sweet peppers, spiced pepitas & queso fresco.cook index eabe936..24584e3 100644 --- a/BUTTERNUT & TURKEY CHILI with sweet peppers, spiced pepitas & queso fresco.cook +++ b/BUTTERNUT & TURKEY CHILI with sweet peppers, spiced pepitas & queso fresco.cook @@ -9,6 +9,7 @@ tags: - butternut squash - chili - turkey +image: https://roux.roo.lol/recipe-images/butternut-turkey-chili-with-sweet-peppers-spiced-pepitas-queso-fresco.webp --- Heat ~{1%Tbsp} @olive oil{} in a #pot over medium heat. diff --git a/Baked Chile Relleno with Black Beans.cook b/Baked Chile Relleno with Black Beans.cook index a59af0f..242f70d 100644 --- a/Baked Chile Relleno with Black Beans.cook +++ b/Baked Chile Relleno with Black Beans.cook @@ -9,6 +9,7 @@ tags: - mexican - peppers - vegetarian +image: https://roux.roo.lol/recipe-images/baked-chile-relleno-with-black-beans.webp --- Preheat the #oven to high broil with a rack near the broiler. diff --git a/Bang Bang Tofu.cook b/Bang Bang Tofu.cook index de717c8..3454247 100644 --- a/Bang Bang Tofu.cook +++ b/Bang Bang Tofu.cook @@ -10,6 +10,7 @@ tags: - rice - tofu - vegetarian +image: https://roux.roo.lol/recipe-images/bang-bang-tofu.webp --- Drain @tofu{1%lb}, pat dry, and place on a plate lined with several paper towels or a clean dish towel to dry for ~{15%minutes}. diff --git a/Barbecue Chicken with Crispy Pan-Fried Okra & Cheddar Biscuits.cook b/Barbecue Chicken with Crispy Pan-Fried Okra & Cheddar Biscuits.cook index dfbf019..73301b9 100644 --- a/Barbecue Chicken with Crispy Pan-Fried Okra & Cheddar Biscuits.cook +++ b/Barbecue Chicken with Crispy Pan-Fried Okra & Cheddar Biscuits.cook @@ -9,6 +9,7 @@ tags: - chicken - biscuits - okra +image: https://roux.roo.lol/recipe-images/barbecue-chicken-with-crispy-pan-fried-okra-cheddar-biscuits.webp --- Preheat the #oven to 400°F and lightly grease a #baking sheet. diff --git a/Black Bean and Corn Salad.cook b/Black Bean and Corn Salad.cook index 613119f..2224465 100644 --- a/Black Bean and Corn Salad.cook +++ b/Black Bean and Corn Salad.cook @@ -12,6 +12,7 @@ tags: - avocado - summer - healthy +image: https://roux.roo.lol/recipe-images/black-bean-and-corn-salad.webp --- In a large #mixing bowl{}, whisk together the @lime juice{1/4%cup}, @avocado oil{3%tablespoons}, @garlic{1%clove}, grated, @cumin{1/2%teaspoon}, @sea salt{3/4%teaspoon}, and @black pepper{}. diff --git a/Black Pepper Tofu (Ottolenghi).cook b/Black Pepper Tofu (Ottolenghi).cook index b26d435..06eaa3c 100644 --- a/Black Pepper Tofu (Ottolenghi).cook +++ b/Black Pepper Tofu (Ottolenghi).cook @@ -1,3 +1,12 @@ +--- +title: Black Pepper Tofu (Ottolenghi) +description: +servings: 1 +category: uncategorized +source: Unknown +image: https://roux.roo.lol/recipe-images/black-pepper-tofu-ottolenghi.webp +--- + >> Servings: 4 Pour enough @vegetable oil{} into a large #frying pan or wok{} to come 1/4 inch and turn on heat. diff --git a/Black Pepper Tofu with Bok Choy.cook b/Black Pepper Tofu with Bok Choy.cook index 8085877..2f9d180 100644 --- a/Black Pepper Tofu with Bok Choy.cook +++ b/Black Pepper Tofu with Bok Choy.cook @@ -1,3 +1,12 @@ +--- +title: Black Pepper Tofu with Bok Choy +description: +servings: 1 +category: uncategorized +source: Unknown +image: https://roux.roo.lol/recipe-images/black-pepper-tofu-with-bok-choy.webp +--- + >> Servings: 2 >> Prep time: 30 minutes >> Total time: 30 minutes diff --git a/Blackened Shrimp and Gouda Grits.cook b/Blackened Shrimp and Gouda Grits.cook index 7b94d84..dcdf482 100644 --- a/Blackened Shrimp and Gouda Grits.cook +++ b/Blackened Shrimp and Gouda Grits.cook @@ -7,6 +7,7 @@ tags: caesar salad,garnish-and-gather,seafood,shrimp and grits,southern source: Unknown description: Southern-style shrimp and grits with smoked gouda, served with a charred scallion kale caesar salad prep_time: 25 minutes +image: https://roux.roo.lol/recipe-images/blackened-shrimp-and-gouda-grits.webp --- In a #pot{}, bring 3 cups @water{} & @salt{1/2 teaspoon} to a boil. diff --git a/Butter Tofu.cook b/Butter Tofu.cook index a813bef..2ba1848 100644 --- a/Butter Tofu.cook +++ b/Butter Tofu.cook @@ -4,7 +4,7 @@ servings: 6 category: uncategorized source: https://cooking.nytimes.com/recipes/1020094-tofu-makhani-indian-butter-tofu description: This recipe is a vegetarian riff on butter chicken, or murgh makhani, a classic Indian dish in which chicken simmers in a rich, dairy-laden tomato sauce that's seasoned with heady spices like turmeric, cumin, garam masala and cardamom. This weeknight-friendly version has a toned-down ingredient list, and the tofu doesn't require hours of marinating, which means you can get everything on the table in under an hour if you start the rice as the tomatoes are cooking down. Heavy cream gives this dish a rich finish, but full-fat coconut milk makes a fine substitute. Whatever you do, don't substitute anything for butter or ghee (sorry, vegans) — it's signature ingredient. -image: https://kitchen.roo.lol/data/images/99596aa7-0678-40ce-8020-f2ae9308be6a.webp +image: https://roux.roo.lol/recipe-images/butter-tofu.webp --- In a large #bowl{}, whisk @fresh lemon juice{2 tablespoons}, @ground cumin{1 tablespoon} and 1 heaping tablespoon @ground turmeric{} with 1 tablespoon @water{} to make a thin paste. Drain and pat @tofu{2 (14-ounce) packages, firm} dry then cut it into 1-inch cubes. Add @tofu{} to the @turmeric{} marinade, gently stirring to coat. Set aside at room temperature while you prepare the remaining ingredients, or cover and refrigerate for up to 1 day. diff --git a/Butternut Turkey Chili.cook b/Butternut Turkey Chili.cook index 49528c8..aea6c5e 100644 --- a/Butternut Turkey Chili.cook +++ b/Butternut Turkey Chili.cook @@ -9,6 +9,7 @@ tags: - butternut squash - chili - turkey +image: https://roux.roo.lol/recipe-images/butternut-turkey-chili-2.webp --- Heat ~{1%Tbsp} @olive oil{} in a #pot over medium heat. diff --git a/Cabbage_Salad.cook b/Cabbage_Salad.cook index 079ad5f..076a27c 100644 --- a/Cabbage_Salad.cook +++ b/Cabbage_Salad.cook @@ -3,6 +3,7 @@ title: Cabbage Salad servings: 6 category: Salad source: https://www.loveandlemons.com/cabbage-salad/ +image: https://roux.roo.lol/recipe-images/cabbage-salad.webp --- In a large bowl, toss together @green cabbage{4%cup}, @red cabbage{4%cup}, @red bell pepper{1%medium}, @carrots{1%cup}(julienned), @cilantro{1/2%cup}(chopped). diff --git a/Cajun Shrimp and Sausage Vegetable Foil Packets.cook b/Cajun Shrimp and Sausage Vegetable Foil Packets.cook index 51cc5b8..7baff73 100644 --- a/Cajun Shrimp and Sausage Vegetable Foil Packets.cook +++ b/Cajun Shrimp and Sausage Vegetable Foil Packets.cook @@ -4,7 +4,7 @@ servings: 4 category: uncategorized source: https://therecipecritic.com/cajun-shrimp-and-sausage-vegetable-foil-packets/ description: Cajun Shrimp and Sausage Foil Packets are loaded with shrimp, sausage, summer vegetables and tossed in cajun spices. These are quick and easy and packed with big flavor! -image: https://kitchen.roo.lol/data/images/9f6c7d9f-c6d7-4ea3-bad7-dcffe1187cba.webp +image: https://roux.roo.lol/recipe-images/cajun-shrimp-and-sausage-vegetable-foil-packets.webp --- In a large #bowl{} add @shrimp{1 pound, large, peeled and deveined}, @sausage{14 ounce, pork or chicken, sliced}, @zucchini{2 medium sized, sliced}, @yellow squash{2 medium sized, sliced}, @asparagus{½ bunch, sliced into thirds}, @red bell pepper{2, chopped into chunks} and @salt{} and @pepper{}. Add @olive oil{3 Tablespoons} and @cajun seasoning{3 Tablespoons} and toss until coated. diff --git a/Cajun Spice Mix (for pecans, oysters, etc).cook b/Cajun Spice Mix (for pecans, oysters, etc).cook index 1a5e90d..4933190 100644 --- a/Cajun Spice Mix (for pecans, oysters, etc).cook +++ b/Cajun Spice Mix (for pecans, oysters, etc).cook @@ -3,7 +3,7 @@ title: Cajun Spice Mix (for pecans, oysters, etc) description: A Leonard-family recipe for spice mix for seasoning Cajun Pecans or Oysters servings: 9 source: Mealie -image: https://kitchen.roo.lol/data/images/c0540c17-29a5-4fe3-b038-1b421037c6e8.webp +image: https://roux.roo.lol/recipe-images/cajun-spice-mix-for-pecans-oysters-etc.webp thumbnail: https://kitchen.roo.lol/data/images/thumbnails/c0540c17-29a5-4fe3-b038-1b421037c6e8.webp date_created: 2024-11-03 date_modified: 2024-11-03 diff --git a/Caramel Cake.cook b/Caramel Cake.cook index d307974..4bfa755 100644 --- a/Caramel Cake.cook +++ b/Caramel Cake.cook @@ -1,3 +1,12 @@ +--- +title: Caramel Cake +description: +servings: 1 +category: uncategorized +source: Unknown +image: https://roux.roo.lol/recipe-images/caramel-cake.webp +--- + >> Servings: 10 Combine @sour cream{8 ounces} and @milk{1/4 cup}. diff --git a/Caramel Icing.cook b/Caramel Icing.cook index 316763d..735d087 100644 --- a/Caramel Icing.cook +++ b/Caramel Icing.cook @@ -1,3 +1,12 @@ +--- +title: Caramel Icing +description: +servings: 1 +category: uncategorized +source: Unknown +image: https://roux.roo.lol/recipe-images/caramel-icing.webp +--- + >> Servings: 10 Sprinkle @sugar{1/2 cup} in a shallow heavy #3½-quart Dutch oven{}. diff --git a/Chana Chickpea Salad.cook b/Chana Chickpea Salad.cook index d3dba57..0e5ddfd 100644 --- a/Chana Chickpea Salad.cook +++ b/Chana Chickpea Salad.cook @@ -7,6 +7,7 @@ servings: 6 category: side source: OCR tags: salad, indian, vegan, gluten-free, instant-pot, chickpea +image: https://roux.roo.lol/recipe-images/chana-chickpea-salad.webp --- In the inner cooking pot of the #Instant Pot, combine the @chickpea{1%can}, @bay leaf{2}, and @water{4%cups}. diff --git a/Chana Salad.cook b/Chana Salad.cook index 34c8b71..c14c1b6 100644 --- a/Chana Salad.cook +++ b/Chana Salad.cook @@ -4,7 +4,7 @@ servings: 6 category: side source: OCR description: I think my mom lied to me about this chana salaad. She said it was junk food so I would eat it, but now that I'm older I know better. After all, it's chickpeas and vegetables! But I'm glad my mom said whatever it took at time to get me to eat it, because I love this salad. It is perfect for summer and is easy to make. Serve it as a side salad or as a main dish for a vegan meal. Adjust cayenne as desired for your heat preference. SERVES 6 -image: https://kitchen.roo.lol/data/images/bd956abd-bbc8-4b7c-87e1-8c7ca70f804d.webp +image: https://roux.roo.lol/recipe-images/chana-salad.webp --- In inner cooking pot of #InstantPot, combine @chickpeas{1 can, 15-16 ounces}, @bay leaves{}, and @water{}. diff --git a/Chicken and Pumpkin Gnocchi with Ricotta.cook b/Chicken and Pumpkin Gnocchi with Ricotta.cook index de39af8..d5a9359 100644 --- a/Chicken and Pumpkin Gnocchi with Ricotta.cook +++ b/Chicken and Pumpkin Gnocchi with Ricotta.cook @@ -7,6 +7,7 @@ source: garnish-and-gather description: prep_time: 35 minutesnutes totalTime: PT35M +image: https://roux.roo.lol/recipe-images/chicken-and-pumpkin-gnocchi-with-ricotta.webp --- Remove any large stems from @spinach{2 1/2 cups} and roughly chop. diff --git a/Chickpea Butter Curry.cook b/Chickpea Butter Curry.cook index 12e6a04..462a6ca 100644 --- a/Chickpea Butter Curry.cook +++ b/Chickpea Butter Curry.cook @@ -8,6 +8,7 @@ source: Unknown description: A vegetarian curry with chickpeas, cauliflower, and coconut milk, served with spiced oil drizzle prep_time: 20 minutes cook_time: 20 minutes +image: https://roux.roo.lol/recipe-images/chickpea-butter-curry.webp --- In a small #pot{}, bring 1 1/2 cups @water{} & @basmati rice{3/4 cup} to a boil, then cover, reduce heat to low, and cook ~{12-15 minutes} or until @rice{} is tender. diff --git a/Chickpea_Butter_Curry.cook b/Chickpea_Butter_Curry.cook index 6aac1a0..2d46209 100644 --- a/Chickpea_Butter_Curry.cook +++ b/Chickpea_Butter_Curry.cook @@ -3,6 +3,7 @@ title: Chickpea Butter Curry servings: 2 category: Main source: Rebel Recipes +image: https://roux.roo.lol/recipe-images/chickpea-butter-curry-2.webp --- In a small pot, bring 1 1/2 cups water and @basmati rice{3/4%cup} to a boil, then cover, reduce heat to low, and cook 12-15 minutes or until rice is tender. diff --git a/Chinese Orange Shrimp.cook b/Chinese Orange Shrimp.cook index 47471e1..7ce7701 100644 --- a/Chinese Orange Shrimp.cook +++ b/Chinese Orange Shrimp.cook @@ -8,6 +8,7 @@ source: Unknown description: Shrimp in orange sauce with brussels sprouts and carrots served over scallion rice prep_time: 15 minutes cook_time: 15 minutes +image: https://roux.roo.lol/recipe-images/chinese-orange-shrimp.webp --- In a #pot{}, bring 1 1/2 cups @water{} & @salt{1/4 teaspoon} to a boil. diff --git a/Chocolate_Mousse_Cake_with_Raspberries.cook b/Chocolate_Mousse_Cake_with_Raspberries.cook index ba077f9..cdf86ec 100644 --- a/Chocolate_Mousse_Cake_with_Raspberries.cook +++ b/Chocolate_Mousse_Cake_with_Raspberries.cook @@ -3,6 +3,7 @@ title: Chocolate Mousse Cake with Raspberries servings: 24 category: Desserts source: King Arthur Baking +image: https://roux.roo.lol/recipe-images/chocolate-mousse-cake-with-raspberries.webp --- Preheat the oven to 325°F. Lightly grease two 8" round pans (or adjust for your pan mix) and line with parchment. diff --git a/Cilantro Pesto Shrimp Over Orzo.cook b/Cilantro Pesto Shrimp Over Orzo.cook index fa4ca42..5be7592 100644 --- a/Cilantro Pesto Shrimp Over Orzo.cook +++ b/Cilantro Pesto Shrimp Over Orzo.cook @@ -7,6 +7,7 @@ source: Unknown description: prep_time: 20 minutes totalTime: PT20M +image: https://roux.roo.lol/recipe-images/cilantro-pesto-shrimp-over-orzo.webp --- Juice HALF of @lemon{1} and cut remainder into wedges. diff --git a/Crispy Roasted Chickpeas (Garbanzo Beans).cook b/Crispy Roasted Chickpeas (Garbanzo Beans).cook index d44c934..2906769 100644 --- a/Crispy Roasted Chickpeas (Garbanzo Beans).cook +++ b/Crispy Roasted Chickpeas (Garbanzo Beans).cook @@ -3,6 +3,7 @@ title: Crispy Roasted Chickpeas (Garbanzo Beans) servings: 2 category: Snack source: Unknown +image: https://roux.roo.lol/recipe-images/crispy-roasted-chickpeas-garbanzo-beans.webp --- Preheat the oven to 400°F. diff --git a/Crispy Tofu With Cashews and Blistered Snap Peas.cook b/Crispy Tofu With Cashews and Blistered Snap Peas.cook index 741ab52..41cddc6 100644 --- a/Crispy Tofu With Cashews and Blistered Snap Peas.cook +++ b/Crispy Tofu With Cashews and Blistered Snap Peas.cook @@ -4,7 +4,7 @@ servings: 4 category: uncategorized source: https://cooking.nytimes.com/recipes/1021200-crispy-tofu-with-cashews-and-blistered-snap-peas?campaign_id=9&emc=edit_nn_20230415&instance_id=90280&nl=the-morning®i_id=123169868&segment_id=130511&te=1&user_id=c5863897ec3230a42bc044f493123ca2 description: A ginger and coconut milk reduction can coat pretty much anything that browns nicely on its own. Here, it's pieces of pan-seared tofu, but small morsels of chicken and pork will work just as well. The soy and teaspoons of molasses give sauce a little caramelization, and a little shine and gloss. For a fresh side, add some blistered snap peas, tossed with sliced scallions, a little mint and a splash of rice vinegar. Snow peas, green beans, broccoli or asparagus? If it's fresh and green, it'll work just fine. -image: https://kitchen.roo.lol/data/images/9fe7eb34-2b1c-4dba-88e8-eb4ba4abea8e.webp +image: https://roux.roo.lol/recipe-images/crispy-tofu-with-cashews-and-blistered-snap-peas.webp --- Slice @tofu{1 (14-ounce) block, firm or extra-firm, drained} in half horizontally, and leave on #paper towels{} to dry any excess liquid. diff --git a/Crispy_Roasted_Chickpeas_(Garbanzo_Beans).cook b/Crispy_Roasted_Chickpeas_(Garbanzo_Beans).cook index d44c934..604727b 100644 --- a/Crispy_Roasted_Chickpeas_(Garbanzo_Beans).cook +++ b/Crispy_Roasted_Chickpeas_(Garbanzo_Beans).cook @@ -3,6 +3,7 @@ title: Crispy Roasted Chickpeas (Garbanzo Beans) servings: 2 category: Snack source: Unknown +image: https://roux.roo.lol/recipe-images/crispy-roasted-chickpeas-garbanzo-beans-2.webp --- Preheat the oven to 400°F. diff --git a/Dried Fava Soup.cook b/Dried Fava Soup.cook index 9eaf184..e5f673f 100644 --- a/Dried Fava Soup.cook +++ b/Dried Fava Soup.cook @@ -11,6 +11,7 @@ tags: - soup description: A slow-simmered dried fava bean soup with roasted tomatoes, garlic, and onion, finished with mint and cilantro and topped with a tangy quick-pickled guajillo chile mixture. source: 101 Cookbooks (adapted from Rick Bayless’s Mexican Kitchen) +image: https://roux.roo.lol/recipe-images/dried-fava-soup.webp --- Make sure the @hulled dried fava bean{1%lb} are clean and free of dirt, then rinse them well. diff --git a/Easy Lemon Rosemary White Bean Soup.cook b/Easy Lemon Rosemary White Bean Soup.cook index 6b08f49..da730f9 100644 --- a/Easy Lemon Rosemary White Bean Soup.cook +++ b/Easy Lemon Rosemary White Bean Soup.cook @@ -3,6 +3,7 @@ title: EASY LEMON ROSEMARY WHITE BEAN SOUP servings: 4 category: Soup source: Simple Veganista +image: https://roux.roo.lol/recipe-images/easy-lemon-rosemary-white-bean-soup.webp --- Saute @olive oil{2%tbsp} in a large pot. Add @onion{1%small}, @carrots{3%large} and @celery{2 stalks}; cook for 7 minutes until softened. diff --git a/Easy Vegetarian Chili.cook b/Easy Vegetarian Chili.cook index bd22837..2e3ef55 100644 --- a/Easy Vegetarian Chili.cook +++ b/Easy Vegetarian Chili.cook @@ -4,7 +4,7 @@ servings: 6 category: uncategorized source: https://www.loveandlemons.com/vegetarian-chili-recipe/ description: You'll LOVE this easy vegetarian chili recipe! It's gluten-free, and without yogurt or sour cream on top, it's also vegan. -image: https://kitchen.roo.lol/data/images/61187b69-c326-4ad4-aa03-f3eb7c0b1806.webp +image: https://roux.roo.lol/recipe-images/easy-vegetarian-chili.webp --- Heat @extra-virgin olive oil{2 tablespoons} in a large #pot{} over medium heat. Add @yellow onion{1 small, chopped}, a few pinches of @salt{} and @pepper{}, and stir. Cook until @onion{} is translucent, ~{5 minutes}, then add @garlic{2 cloves, minced} and @red bell pepper{1, diced}. Stir and cook until soft, ~{5 to 8 minutes}, turning heat down as needed. diff --git a/Easy_Lemon_Rosemary_White_Bean_Soup.cook b/Easy_Lemon_Rosemary_White_Bean_Soup.cook index 6b08f49..a47797d 100644 --- a/Easy_Lemon_Rosemary_White_Bean_Soup.cook +++ b/Easy_Lemon_Rosemary_White_Bean_Soup.cook @@ -3,6 +3,7 @@ title: EASY LEMON ROSEMARY WHITE BEAN SOUP servings: 4 category: Soup source: Simple Veganista +image: https://roux.roo.lol/recipe-images/easy-lemon-rosemary-white-bean-soup-2.webp --- Saute @olive oil{2%tbsp} in a large pot. Add @onion{1%small}, @carrots{3%large} and @celery{2 stalks}; cook for 7 minutes until softened. diff --git a/Fettucine with spiced cherry tomato sauce.cook b/Fettucine with spiced cherry tomato sauce.cook index 05b6c9f..ddb0aa0 100644 --- a/Fettucine with spiced cherry tomato sauce.cook +++ b/Fettucine with spiced cherry tomato sauce.cook @@ -6,7 +6,7 @@ source: Mealie description: This is basically spaghetti with a sauce made from scratch. The sauce is great and I think this whole recipe is really good especially considering the ingredients are so basic. I added red pepper to the recipe for extra kick. -image: https://kitchen.roo.lol/data/images/1a3fbf92-6d4b-4f74-adf3-0b004b5f021a.webp +image: https://roux.roo.lol/recipe-images/fettucine-with-spiced-cherry-tomato-sauce.webp prep_time: 30 minutes cook_time: 1 hour --- diff --git a/Gaja's Bulgogi Lettuce Wraps.cook b/Gaja's Bulgogi Lettuce Wraps.cook index 6605da7..01841cf 100644 --- a/Gaja's Bulgogi Lettuce Wraps.cook +++ b/Gaja's Bulgogi Lettuce Wraps.cook @@ -6,6 +6,7 @@ tags: bulgogi,garnish-and-gather,korean,lettuce wraps source: Unknown description: prep_time: 20 minutes +image: https://roux.roo.lol/recipe-images/gaja-s-bulgogi-lettuce-wraps.webp --- Pat @steak bulgogi{8 oz} dry. diff --git a/Gochugaru Honey Salmon.cook b/Gochugaru Honey Salmon.cook index 729e285..98d8c8b 100644 --- a/Gochugaru Honey Salmon.cook +++ b/Gochugaru Honey Salmon.cook @@ -7,6 +7,7 @@ tags: crispy rice,garnish-and-gather,gochugaru,korean,salmon source: Unknown description: Salmon with spicy honey sauce served with crispy rice, broccoli, and carrots prep_time: 25 minutes +image: https://roux.roo.lol/recipe-images/gochugaru-honey-salmon.webp --- In a #pot{}, bring 1 1/2 cups @water{} to a boil for @rice{3/4 cup, long grain}. diff --git a/Green_Beans_with_Lemon_and_Garlic.cook b/Green_Beans_with_Lemon_and_Garlic.cook index 4624a65..8d6eb66 100644 --- a/Green_Beans_with_Lemon_and_Garlic.cook +++ b/Green_Beans_with_Lemon_and_Garlic.cook @@ -4,7 +4,7 @@ servings: 6 category: Thanksgiving source: https://www.foodnetwork.com/recipes/patrick-and-gina-neely/green-beans-with-lemon-and-garlic-recipe-1938670 description: The Neelys' healthy Green Beans with Lemon and Garlic recipe from Food Network is the perfect, simple side for any occasion. Quickly blanch and finish on the skillet, these green beans will be on the table in less than 20 minutes. -image: https://kitchen.roo.lol/data/images/704b15f5-0eda-4f7f-8762-1d8f36c2dea6.webp +image: https://roux.roo.lol/recipe-images/green-beans-with-lemon-and-garlic.webp nutrition: calories: 122 kcal carbohydrate: 11g diff --git a/Indian Spiced Chicken.cook b/Indian Spiced Chicken.cook index baecd53..ca662f7 100644 --- a/Indian Spiced Chicken.cook +++ b/Indian Spiced Chicken.cook @@ -7,6 +7,7 @@ source: Unknown description: prep_time: 20 minutes cook_time: 20 minutes +image: https://roux.roo.lol/recipe-images/indian-spiced-chicken-2.webp --- Bring 1 1/2 cups @water{} & @salt{1/4 tsp} to a boil in a #pot{}. diff --git a/Italian Sausage and Delicata Rigatoni.cook b/Italian Sausage and Delicata Rigatoni.cook index 7dd673f..1e878aa 100644 --- a/Italian Sausage and Delicata Rigatoni.cook +++ b/Italian Sausage and Delicata Rigatoni.cook @@ -1,3 +1,12 @@ +--- +title: Italian Sausage & Delicata Rigatoni +description: +servings: 1 +category: uncategorized +source: Unknown +image: https://roux.roo.lol/recipe-images/italian-sausage-and-delicata-rigatoni.webp +--- + >> title: Italian Sausage & Delicata Rigatoni >> author: Chef Robin Pridgen >> servings: 2 diff --git a/Kale and Chestnut Stew.cook b/Kale and Chestnut Stew.cook index 0203904..2cb7aea 100644 --- a/Kale and Chestnut Stew.cook +++ b/Kale and Chestnut Stew.cook @@ -8,6 +8,7 @@ source: Garnish & Gather — Chef Emily Golub description: Cozy kale-and-chestnut stew finished with cream and topped with a bright parsley–walnut pesto. Allergens: dairy, walnuts. prep_time: 20 minutes cook_time: 35 minutes +image: https://roux.roo.lol/recipe-images/kale-and-chestnut-stew.webp --- Remove any large stems from @kale{3 c} and thinly slice into ribbons. diff --git a/Kkanpoong Tofu.cook b/Kkanpoong Tofu.cook index 08cae9a..2b720e4 100644 --- a/Kkanpoong Tofu.cook +++ b/Kkanpoong Tofu.cook @@ -4,6 +4,7 @@ servings: 2 category: uncategorized source: https://thekoreanvegan.com/spicy-crunchy-garlic-tofu-kkampoong-tofu/ description: +image: https://roux.roo.lol/recipe-images/kkanpoong-tofu.webp --- To a large #bowl{}, add a pinch of @salt{} and 2 tablespoons of @potato starch{} to @tofu{1 16 ounce block, extra firm, pressed and chopped into 1/2 inch bite sized chunks}. Gently toss @tofu{} to make sure they are all evenly coated. Set aside. diff --git a/Korean Shrimp Tacos.cook b/Korean Shrimp Tacos.cook index be597ba..1544891 100644 --- a/Korean Shrimp Tacos.cook +++ b/Korean Shrimp Tacos.cook @@ -8,6 +8,7 @@ source: Unknown description: Crispy shrimp tacos with gochujang sauce and bok choy rice salad prep_time: 25 minutes cook_time: 25 minutes +image: https://roux.roo.lol/recipe-images/korean-shrimp-tacos.webp --- In a #pot{}, bring 1 1/2 cups @water{} & @salt{1/4 teaspoon} to a boil. diff --git a/Kung Pao Shrimp with Sichuan Roasted Green Beans.cook b/Kung Pao Shrimp with Sichuan Roasted Green Beans.cook index e62919e..0ef4858 100644 --- a/Kung Pao Shrimp with Sichuan Roasted Green Beans.cook +++ b/Kung Pao Shrimp with Sichuan Roasted Green Beans.cook @@ -6,6 +6,7 @@ tags: chinese,garnish-and-gather,kung pao,shrimp source: Unknown description: prep_time: 25 minutes +image: https://roux.roo.lol/recipe-images/kung-pao-shrimp-with-sichuan-roasted-green-beans.webp --- Preheat #oven{} to 425°. diff --git a/Lactation cookies.cook b/Lactation cookies.cook index 1a452ab..3d1084b 100644 --- a/Lactation cookies.cook +++ b/Lactation cookies.cook @@ -5,6 +5,7 @@ category: Cookies tags: cookies source: Mealie description: +image: https://roux.roo.lol/recipe-images/lactation-cookies.webp --- Preheat #oven{} to 350°. diff --git a/Lactation_cookies.cook b/Lactation_cookies.cook index 3ae21f5..4807d50 100644 --- a/Lactation_cookies.cook +++ b/Lactation_cookies.cook @@ -3,6 +3,7 @@ title: Lactation Cookies servings: 12 category: Cookies source: Mealie +image: https://roux.roo.lol/recipe-images/lactation-cookies-2.webp --- @butter{1%cup} diff --git a/Lentil Soup with Lemon and Turmeric.cook b/Lentil Soup with Lemon and Turmeric.cook index b99963e..df6bc15 100644 --- a/Lentil Soup with Lemon and Turmeric.cook +++ b/Lentil Soup with Lemon and Turmeric.cook @@ -4,7 +4,7 @@ servings: 8 category: uncategorized source: https://www.inspiredtaste.net/40400/lentil-soup/ description: This is our favorite lentil soup recipe. I make this soup with lentils, carrots, turmeric, and fresh lemon whenever we are in need of some healthy comfort food. It's savory, satisfying, and utterly delicious. I like quite a bit of fresh lemon in this soup and actually serve soup with slices of lemon. This adds even more lemony flavor and shows that lemon was added to soup. -image: https://kitchen.roo.lol/data/images/47a68b65-c916-4c5d-86f2-ea989ea310a7.webp +image: https://roux.roo.lol/recipe-images/lentil-soup-with-lemon-and-turmeric.webp --- Heat @olive oil{2 tablespoons} in a large #pot{} (like a #Dutch oven{}) over medium heat. Add @onions{2 cups, finely chopped (1 medium onion)}, @carrot{1 1/2 cups, chopped (2 large carrots)}, and @salt{1/4 teaspoon} of and cook, stirring occasionally until they are softened and starting to smell sweet, about ~{5 to 7 minutes}. Stir in @garlic{2 teaspoons, minced (3 cloves)}, @ground cumin{1 teaspoon}, @ground coriander{1/2 teaspoon}, @fresh ground black pepper{1/2 teaspoon}, and @ground turmeric{1/2 teaspoon} and cook for ~{30 seconds}. diff --git a/Moroccan Spiced Lentil & Chickpea Soup.cook b/Moroccan Spiced Lentil & Chickpea Soup.cook index 0eb040d..4bec2cf 100644 --- a/Moroccan Spiced Lentil & Chickpea Soup.cook +++ b/Moroccan Spiced Lentil & Chickpea Soup.cook @@ -3,6 +3,7 @@ title: Moroccan Spiced Lentil & Chickpea Soup servings: 1 category: Soup source: Rebel Recipes +image: https://roux.roo.lol/recipe-images/moroccan-spiced-lentil-chickpea-soup.webp --- In a large pan, add @olive oil{2%tbsp} and @onion{1%large}(chopped); cook on medium heat for 7-8 minutes until soft and browning. diff --git a/Moroccan_Spiced_Lentil_and_Chickpea_Soup.cook b/Moroccan_Spiced_Lentil_and_Chickpea_Soup.cook index 0eb040d..0f726b6 100644 --- a/Moroccan_Spiced_Lentil_and_Chickpea_Soup.cook +++ b/Moroccan_Spiced_Lentil_and_Chickpea_Soup.cook @@ -3,6 +3,7 @@ title: Moroccan Spiced Lentil & Chickpea Soup servings: 1 category: Soup source: Rebel Recipes +image: https://roux.roo.lol/recipe-images/moroccan-spiced-lentil-and-chickpea-soup.webp --- In a large pan, add @olive oil{2%tbsp} and @onion{1%large}(chopped); cook on medium heat for 7-8 minutes until soft and browning. diff --git a/Orange Rolls.cook b/Orange Rolls.cook index 466b20f..f55e424 100644 --- a/Orange Rolls.cook +++ b/Orange Rolls.cook @@ -8,6 +8,7 @@ tags: - breakfast - rolls - orange +image: https://roux.roo.lol/recipe-images/orange-rolls.webp --- Make the dough: Heat the #oven to 375°F. Place @light brown sugar{1/3%cup} in a small #bowl and zest the @orange{1} directly over it. Gently rub the zest into the sugar and transfer 2 tablespoons/25 grams of the orange sugar to a large #bowl to use for the dough. Save the rest of the orange sugar for the filling. diff --git a/Palak Paneer.cook b/Palak Paneer.cook index 9c605a6..2ffc2c5 100644 --- a/Palak Paneer.cook +++ b/Palak Paneer.cook @@ -3,6 +3,7 @@ title: Palak Paneer servings: 4 category: Indian source: Mealie +image: https://roux.roo.lol/recipe-images/palak-paneer.webp --- Preheat the #Instant Pot by selecting Sauté and adjust to More for high heat. When the inner cooking pot is hot, add @peanut oil{2%tbsp} and heat until it is shimmering. Add @garlic cloves{5}(minced), @ginger{2%tsp}(minced), and @serrano or jalapeño chile{1}(minced), and sauté for ~{1%minute} or until fragrant. diff --git a/Passion Fruit Curd Recipe.cook b/Passion Fruit Curd Recipe.cook index 6cc6912..0d080d1 100644 --- a/Passion Fruit Curd Recipe.cook +++ b/Passion Fruit Curd Recipe.cook @@ -4,7 +4,7 @@ servings: 10 category: uncategorized source: https://www.theflavorbender.com/make-passion-fruit-curd/#recipe description: Makes about 1 1/4 cups of passion fruit curd -image: https://kitchen.roo.lol/data/images/803d123d-d98f-4a68-a820-e47c88b7a66a.webp +image: https://roux.roo.lol/recipe-images/passion-fruit-curd-recipe.webp --- Indirect Heat Method diff --git a/Pecan-Brown Butter Trout.cook b/Pecan-Brown Butter Trout.cook index 285f630..df0f47f 100644 --- a/Pecan-Brown Butter Trout.cook +++ b/Pecan-Brown Butter Trout.cook @@ -8,6 +8,7 @@ source: Unknown description: Pan-seared trout with pecan-brown butter sauce, served with herbed sweet potatoes, radishes, and wilted greens prep_time: 30 minutes cook_time: 30 minutes +image: https://roux.roo.lol/recipe-images/pecan-brown-butter-trout.webp --- Preheat #oven{} to 400°F. diff --git a/Ribollita.cook b/Ribollita.cook index f1c626a..9433b88 100644 --- a/Ribollita.cook +++ b/Ribollita.cook @@ -4,7 +4,7 @@ servings: 10 category: uncategorized source: https://www.101cookbooks.com/ribollita-recipe/ description: Ribollita, a beautifully thick Tuscan stew made with dark greens, lots of beans, vegetables, olive oil, and thickened with day-old bread. One of my favorites. -image: https://kitchen.roo.lol/data/images/4bc005e2-168b-43bb-a75e-a463eb5bbdc6.webp +image: https://roux.roo.lol/recipe-images/ribollita.webp prep_time: 15 minutes cook_timee:25 minutesinutes totalTime: PT40M diff --git a/Roasted Pumpkin Sage.cook b/Roasted Pumpkin Sage.cook index 8f1fc5e..7c24aad 100644 --- a/Roasted Pumpkin Sage.cook +++ b/Roasted Pumpkin Sage.cook @@ -7,6 +7,7 @@ servings: 5 category: uncategorized source: https://www.skinnytaste.com/roasted-pumpkin-sage-soup tags: soup, pumpkin, fall, vegetarian-option, gluten-free +image: https://roux.roo.lol/recipe-images/roasted-pumpkin-sage.webp --- Heat the oven to 400°F. diff --git a/Saag Paneer.cook b/Saag Paneer.cook index 4ee9ed5..fffd0e8 100644 --- a/Saag Paneer.cook +++ b/Saag Paneer.cook @@ -3,6 +3,7 @@ title: Saag Paneer servings: 1 category: Indian source: Mealie +image: https://roux.roo.lol/recipe-images/saag-paneer.webp --- Preheat the #Instant Pot by selecting Sauté and adjust to More for high heat. When the inner cooking pot is hot, add @peanut oil{2%tbsp} and heat until it is shimmering. Add @garlic cloves{5}(minced), @ginger{2%tsp}(minced), and @serrano or jalapeno chile{1}(minced), and sauté for ~{1%minute} or until fragrant. diff --git a/Sauteed Asparagus with Lemon.cook b/Sauteed Asparagus with Lemon.cook index 52a4928..961726c 100644 --- a/Sauteed Asparagus with Lemon.cook +++ b/Sauteed Asparagus with Lemon.cook @@ -4,7 +4,7 @@ servings: 4 category: Thanksgiving source: https://www.marthastewart.com/316639/sauteed-asparagus-with-lemon description: -image: https://kitchen.roo.lol/data/images/15498ca3-db5d-461f-a3b7-ce6674fc6bea.webp +image: https://roux.roo.lol/recipe-images/sauteed-asparagus-with-lemon.webp --- In a large #skillet{}, heat @olive oil{1 tablespoon} over medium. Add @asparagus{2 bunches, 14 ounces each, ends trimmed}, and season with @coarse salt{} and @ground pepper{}. Cook, tossing occasionally, until lightly browned and crisp-tender, ~{10 to 15 minutes}, depending on thickness. Add @lemon zest{4 wide strips} and cook ~{1 minute}. Add @lemon juice{from 1/2 lemon}, toss to coat, and serve warm. \ No newline at end of file diff --git a/Slow Cooker Chicken Shawarma.cook b/Slow Cooker Chicken Shawarma.cook index 52d8ca2..aea2309 100644 --- a/Slow Cooker Chicken Shawarma.cook +++ b/Slow Cooker Chicken Shawarma.cook @@ -4,7 +4,7 @@ servings: 6 category: uncategorized source: https://acleanbake.com/slow-cooker-chicken-shawarma/ description: Slow cooker chicken shawarma combines the ease of a slow cooker meal with the complex flavor of a slow-roasted middle eastern chicken feast! This is a quick version of middle eastern favorite: the slow cooker does a lot of the work and it can be prepped ahead of time. Various serving options make this sensational paleo and gluten free dinner recipe adaptable for low carb and Whole30 compliance, too! -image: https://kitchen.roo.lol/data/images/0cea2c65-f549-4f57-97fd-5a1d23941297.webp +image: https://roux.roo.lol/recipe-images/slow-cooker-chicken-shawarma.webp --- Place @chicken breasts{2 lbs, boneless, skinless} in #bowl{} of your #slow cooker{}, and add @water{1/2 cup}. Cook on high ~{2 hours} until @chicken{} is cooked through (the juices run clear and @fat{} has rendered out of @chicken{}). diff --git a/Southern_Macaroni_and_Cheese.cook b/Southern_Macaroni_and_Cheese.cook index 18e8fa2..33466cc 100644 --- a/Southern_Macaroni_and_Cheese.cook +++ b/Southern_Macaroni_and_Cheese.cook @@ -4,7 +4,7 @@ servings: 10 category: Thanksgiving source: https://cooking.nytimes.com/recipes/1020515-southern-macaroni-and-cheese description: There is macaroni and cheese, and then there is special occasion macaroni and cheese like this one. Unlike most recipes, which start with a roux, this one begins with a milk-and-egg base, which gives the dish an incredibly rich, silky taste. It's adapted from Millie Peartree, the owner of Millie Peartree Fish Fry & Soul Food restaurant in the Bronx, who has been making this dish since she was a little girl. The recipe was passed down in her family for generations, but because of the generous amount of cheese used, the dish was only made for events like Christmas and Thanksgiving. Extra-sharp Cheddar adds tartness and a layer of Colby Jack creates a gooey, molten center. If you can't find a Colby Jack blend, shredded mozzarella or a Mexican-style blend will work in its place. -image: https://kitchen.roo.lol/data/images/657048ab-342f-4ca3-84cb-fe9dcb3ae2a4.webp +image: https://roux.roo.lol/recipe-images/southern-macaroni-and-cheese.webp --- Heat #oven{} to 350 degrees. Bring a large #pot{} of generously salted water to a boil. Add @elbow macaroni{1%pound} and cook according to package directions until a little under al dente, about ~{4%minutes}. Transfer to a #colander{} and rinse under cold water to stop cooking. Set aside. diff --git a/Spaghetti Carbonara.cook b/Spaghetti Carbonara.cook index 3a3a469..6c68ee1 100644 --- a/Spaghetti Carbonara.cook +++ b/Spaghetti Carbonara.cook @@ -8,6 +8,7 @@ source: Unknown description: prep_time: 15 minutes cook_time: 15 minutes +image: https://roux.roo.lol/recipe-images/spaghetti-carbonara.webp --- Trim root from @lettuce{1 head} and separate into leaves. diff --git a/Spaghetti_Squash_w_Chickpeas_and_Kale.cook b/Spaghetti_Squash_w_Chickpeas_and_Kale.cook index bc2b397..f87e977 100644 --- a/Spaghetti_Squash_w_Chickpeas_and_Kale.cook +++ b/Spaghetti_Squash_w_Chickpeas_and_Kale.cook @@ -3,6 +3,7 @@ title: Spaghetti Squash w/ Chickpeas & Kale servings: 3 category: Main source: Love and Lemons +image: https://roux.roo.lol/recipe-images/spaghetti-squash-w-chickpeas-and-kale.webp --- Preheat the oven to 400F. Prepare your squash following the directions in this post. diff --git a/Spanakopita.cook b/Spanakopita.cook index 3b2bb26..5a036b7 100644 --- a/Spanakopita.cook +++ b/Spanakopita.cook @@ -3,6 +3,7 @@ title: Skillet Spanakopita (Greek Spinach Feta Pie) servings: 8 category: Greek source: From a Chef's Kitchen +image: https://roux.roo.lol/recipe-images/spanakopita.webp --- Preheat the oven to 375 degrees. diff --git a/Spicy Shrimp Paella.cook b/Spicy Shrimp Paella.cook index 1f9b295..cc659dc 100644 --- a/Spicy Shrimp Paella.cook +++ b/Spicy Shrimp Paella.cook @@ -8,6 +8,7 @@ tags: - paella - shrimp - spanish +image: https://roux.roo.lol/recipe-images/spicy-shrimp-paella.webp --- In a large sauté #pan, cook @chorizo{2%oz} over medium for ~{3-5%minutes}, until cooked through, then remove, keeping drippings in the pan. diff --git a/Strawberry and Wild Rice Tartlets.cook b/Strawberry and Wild Rice Tartlets.cook index ff10146..72e8187 100644 --- a/Strawberry and Wild Rice Tartlets.cook +++ b/Strawberry and Wild Rice Tartlets.cook @@ -4,7 +4,7 @@ servings: 12 category: uncategorized source: https://www.bonappetit.com/recipe/strawberry-wild-rice-tartlets description: This simple six-ingredient dessert is vegan and bursting with texture (crispy wild rice crust) and flavor (rehydrated cherries with fresh strawberries for the filling). -image: https://kitchen.roo.lol/data/images/ed78da5c-1aa5-4d0b-90bc-4d317b7f7b89.webp +image: https://roux.roo.lol/recipe-images/strawberry-and-wild-rice-tartlets.webp --- Heat #oven{} to 350°. Brush the cups of one standard 12-cup #muffin pan{} or two standard 6-cup #muffin pans{} with @vegetable oil{}. Bring 6 cups lightly salted @water{} to a boil in a medium #saucepan{}. Add @wild rice{1 cup}, cover, and cook until @water{} evaporates and grains split open, about ~{1½ hours}. Spread out @rice{} on a large rimmed #baking sheet{} and let cool. Reserve #pan{}. diff --git a/Thai_Veggie_Pad_See_Ew.cook b/Thai_Veggie_Pad_See_Ew.cook index 78e7a05..5f53a0e 100644 --- a/Thai_Veggie_Pad_See_Ew.cook +++ b/Thai_Veggie_Pad_See_Ew.cook @@ -3,6 +3,7 @@ title: Thai Veggie Pad See Ew servings: 2 category: Thai source: Unknown +image: https://roux.roo.lol/recipe-images/thai-veggie-pad-see-ew.webp --- Bring water to a boil for rice noodles. diff --git a/Tiramisu.cook b/Tiramisu.cook index 3a112b4..8ad2817 100644 --- a/Tiramisu.cook +++ b/Tiramisu.cook @@ -4,7 +4,7 @@ servings: 1 category: uncategorized source: Unknown description: Georgie Grasso recipe - GGBO winner 2024 with this recipe featured! -image: https://kitchen.roo.lol/data/images/d15cdb2C-71db-42d7-a603-a29389e13bd3.webp +image: https://roux.roo.lol/recipe-images/tiramisu.webp prep_time: 15 minutes cook_time: 30 minutes --- diff --git a/Warm Up With a Quick Lemony Chicken Soup.cook b/Warm Up With a Quick Lemony Chicken Soup.cook index 65d5d9d..912800c 100644 --- a/Warm Up With a Quick Lemony Chicken Soup.cook +++ b/Warm Up With a Quick Lemony Chicken Soup.cook @@ -3,6 +3,7 @@ title: Warm Up With a Quick Lemony Chicken Soup servings: 6 category: Soup source: EatingWell +image: https://roux.roo.lol/recipe-images/warm-up-with-a-quick-lemony-chicken-soup.webp --- Heat @olive oil{1%tbsp} in a Dutch oven over medium-high. Add @carrots{3/4%cup} and @yellow onion{1/2%cup}; cook, stirring often, until vegetables are softened, 3 to 4 minutes. Add @garlic cloves{2}(minced) and @crushed red pepper flakes{3/4%tsp}, and cook, stirring constantly, until fragrant, about 1 minute. diff --git a/West African Peanut Chicken.cook b/West African Peanut Chicken.cook index 3cafd5a..f7cba51 100644 --- a/West African Peanut Chicken.cook +++ b/West African Peanut Chicken.cook @@ -7,6 +7,7 @@ source: Unknown description: prep_time: 25 minutes cook_time: 25 minutes +image: https://roux.roo.lol/recipe-images/west-african-peanut-chicken.webp --- Mince @fresno pepper{1}—remove seeds and use only half for less heat. diff --git a/Wheat Berry Salad.cook b/Wheat Berry Salad.cook index c0eb38c..d49c380 100644 --- a/Wheat Berry Salad.cook +++ b/Wheat Berry Salad.cook @@ -3,7 +3,7 @@ title: Wheat Berry Salad servings: 1 description: This healthy wheat berry salad is a delicious fall side dish or lunch with dried cranberries, fresh herbs, walnuts, and a tangy vinaigrette. source: https://www.loveandlemons.com/wheat-berry-salad/ -image: https://kitchen.roo.lol/data/images/eb72067c-28c7-4ae3-88ed-1fc0b9aba762.webp +image: https://roux.roo.lol/recipe-images/wheat-berry-salad.webp --- = Wheat berries = diff --git a/bin/batch-relink.sh b/bin/batch-relink.sh new file mode 100755 index 0000000..64d7543 --- /dev/null +++ b/bin/batch-relink.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +set -euo pipefail + +while IFS='|' read -r file slug; do + url=$(grep "^image:" "$file" | sed 's/^image:[[:space:]]*//') + echo "[$slug] Downloading from $url" + curl -sL -o "recipe-images/$slug.webp" "$url" || echo "[$slug] DOWNLOAD FAILED" +done diff --git a/bin/fetch-recipe-image.sh b/bin/fetch-recipe-image.sh new file mode 100755 index 0000000..2554253 --- /dev/null +++ b/bin/fetch-recipe-image.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash +set -euo pipefail + +slug="$1" +url="$2" + +echo "[$slug] Fetching $url" >&2 +html=$(curl -sL --max-time 15 "$url" 2>/dev/null) || { echo "[$slug] FETCH FAILED" >&2; echo ""; exit 0; } + +# Try multiple og:image patterns +img_url=$(echo "$html" | grep -oP 'property="og:image"\s+content="[^"]*"' | sed 's/.*content="//;s/"//' | head -1) + +if [ -z "$img_url" ]; then + img_url=$(echo "$html" | grep -oP 'name="og:image"\s+content="[^"]*"' | sed 's/.*content="//;s/"//' | head -1) +fi + +if [ -z "$img_url" ]; then + img_url=$(echo "$html" | grep -oP 'content="[^"]*"[^>]*property="og:image"' | sed 's/.*content="//;s/".*//' | head -1) +fi + +if [ -n "$img_url" ]; then + echo "[$slug] Found: $img_url" >&2 + echo "$img_url" +else + echo "[$slug] No og:image found" >&2 +fi diff --git a/bin/final-scrape.py b/bin/final-scrape.py new file mode 100644 index 0000000..3c3fd53 --- /dev/null +++ b/bin/final-scrape.py @@ -0,0 +1,242 @@ +#!/usr/bin/env python3 +"""Final attempt: search DDG text, scrape recipe pages for actual images.""" + +import csv +import json +import re +import sys +import time +from pathlib import Path + +import requests +from bs4 import BeautifulSoup +from ddgs import DDGS + +WORKDIR = Path("/home/jbrechtel/recipes/.worktrees/recipe-images") +HEADERS = { + "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36", +} +SKIP_DOMAINS = {"pinterest", "facebook", "instagram", "twitter", "youtube", "tiktok"} +MIN_IMAGE_SIZE = 10000 # 10KB minimum for a recipe photo + + +def search_url(query: str) -> str | None: + """Search and return first relevant recipe page URL.""" + try: + results = list(DDGS().text(query, max_results=8)) + except Exception as e: + print(f" Search error: {e}", file=sys.stderr) + return None + + for r in results: + url = r.get("href", "") + domain = url.split("/")[2] if "//" in url else "" + if any(s in domain for s in SKIP_DOMAINS): + continue + # Prefer recipe sites + if any(kw in domain for kw in ["recipe", "cook", "food", "kitchen", "nytimes", "loveandlemons"]): + return url + + # Return first non-wikipedia result + for r in results: + url = r.get("href", "") + if "wikipedia.org" not in url: + return url + return None + + +def find_recipe_images(url: str) -> list[str]: + """Fetch a page and find actual recipe/food images.""" + try: + resp = requests.get(url, headers=HEADERS, timeout=15, allow_redirects=True) + resp.raise_for_status() + except requests.RequestException: + return [] + + soup = BeautifulSoup(resp.text, "html.parser") + images = [] + + # 1. Check JSON-LD for recipe image + for script in soup.find_all("script", type="application/ld+json"): + try: + data = json.loads(script.string) + except (json.JSONDecodeError, TypeError): + continue + # Handle list or single + items = data if isinstance(data, list) else [data] + for item in items: + if not isinstance(item, dict): + continue + if item.get("@type") == "Recipe": + img = item.get("image") + if isinstance(img, str): + images.append(img) + elif isinstance(img, list): + for i in img: + if isinstance(i, str): + images.append(i) + elif isinstance(i, dict): + u = i.get("contentUrl") or i.get("url", "") + if u: + images.append(u) + elif isinstance(img, dict): + u = img.get("contentUrl") or img.get("url", "") + if u: + images.append(u) + + # 2. Check og:image + for meta in soup.find_all("meta"): + content = meta.get("content", "") + if (meta.get("property") == "og:image" or meta.get("name") == "og:image" or meta.get("name") == "twitter:image"): + if content and "logo" not in content.lower(): + images.append(content) + + # 3. Check all img tags for large, relevant images + for img in soup.find_all("img"): + src = img.get("src") or img.get("data-src") or "" + if not src.startswith("http"): + continue + src_lower = src.lower() + if any(kw in src_lower for kw in ["logo", "avatar", "icon", "banner", "pixel", "spacer", "thumb"]): + continue + # Check for recipe-related class/id + parent_classes = "" + parent = img.parent + if parent: + parent_classes = " ".join(parent.get("class", []) or []) + " " + (parent.get("id") or "") + if any(kw in parent_classes.lower() for kw in ["logo", "nav", "header", "footer", "menu", "icon"]): + continue + images.append(src) + + # Deduplicate + seen = set() + unique = [] + for img in images: + if img not in seen: + seen.add(img) + unique.append(img) + + return unique + + +def download_image(url: str, dest: Path) -> bool: + """Download image, validate it's a real image.""" + try: + resp = requests.get(url, headers=HEADERS, timeout=30, stream=True) + resp.raise_for_status() + ct = resp.headers.get("content-type", "") + if not ct.startswith("image/"): + return False + content = resp.content + if len(content) < MIN_IMAGE_SIZE: + return False + dest.write_bytes(content) + return True + except requests.RequestException: + return False + + +def get_title(filepath: Path) -> str: + content = filepath.read_text(encoding="utf-8") + m = re.search(r"^title:\s*(.+)$", content, re.MULTILINE) + if m: + return m.group(1).strip() + return filepath.stem.replace("_", " ").replace("-", " ") + + +def add_image_field(filepath: Path, slug: str): + url = f"https://roux.roo.lol/recipe-images/{slug}.webp" + content = filepath.read_text(encoding="utf-8") + if re.search(r"^image:", content, re.MULTILINE): + content = re.sub(r"^image:.*$", f"image: {url}", count=1, flags=re.MULTILINE, string=content) + else: + content = re.sub(r"^---$", f"image: {url}\n---", count=1, flags=re.MULTILINE, string=content) + filepath.write_text(content, encoding="utf-8") + print(f" Updated {filepath.name}", file=sys.stderr) + + +def get_source_url(filepath: Path) -> str | None: + content = filepath.read_text(encoding="utf-8") + m = re.search(r"^source:\s*(.+)$", content, re.MULTILINE) + if m: + val = m.group(1).strip() + if val.startswith("http"): + return val + return None + + +def main(): + csv_file = WORKDIR / "docs" / "no-image-has-fm.csv" + + recipes = [] + with open(csv_file) as f: + reader = csv.reader(f, delimiter="|") + for row in reader: + if len(row) >= 2: + recipes.append((row[0].strip(), row[1].strip())) + + success = [] + failed = [] + + for filename, slug in recipes: + filepath = WORKDIR / filename + if not filepath.exists(): + failed.append(slug) + continue + + dest = WORKDIR / "recipe-images" / f"{slug}.webp" + + # Skip if already has image AND file exists + content = filepath.read_text(encoding="utf-8") + has_field = bool(re.search(r"^image:", content, re.MULTILINE)) + has_file = dest.exists() + if has_field and has_file and dest.stat().st_size > 10000: + print(f"[{slug}] Already done, skipping", file=sys.stderr) + success.append(slug) + continue + + title = get_title(filepath) + query = f"{title} recipe" + + print(f"[{slug}] Searching: {query}", file=sys.stderr) + page_url = search_url(query) + if not page_url: + print(f" No search results", file=sys.stderr) + failed.append(slug) + continue + + print(f" Page: {page_url}", file=sys.stderr) + time.sleep(0.3) + + img_urls = find_recipe_images(page_url) + if not img_urls: + print(f" No images found on page", file=sys.stderr) + failed.append(slug) + continue + + downloaded = False + for img_url in img_urls[:5]: + print(f" Trying: {img_url[:80]}...", file=sys.stderr) + if download_image(img_url, dest): + print(f" Downloaded ({dest.stat().st_size} bytes)", file=sys.stderr) + add_image_field(filepath, slug) + downloaded = True + break + time.sleep(0.2) + + if downloaded: + success.append(slug) + else: + failed.append(slug) + + time.sleep(0.5) + + print(f"\n=== Results ===", file=sys.stderr) + print(f"Success: {len(success)}", file=sys.stderr) + print(f"Failed: {len(failed)}", file=sys.stderr) + if failed: + print(f"Failed: {', '.join(failed)}", file=sys.stderr) + + +if __name__ == "__main__": + main() diff --git a/bin/find-remaining.py b/bin/find-remaining.py new file mode 100644 index 0000000..6d32e52 --- /dev/null +++ b/bin/find-remaining.py @@ -0,0 +1,95 @@ +#!/usr/bin/env python3 +"""Find images for remaining 6 recipes.""" +import re, sys, time +from pathlib import Path +import requests +from bs4 import BeautifulSoup +from ddgs import DDGS + +WORKDIR = Path("/home/jbrechtel/recipes/.worktrees/recipe-images") +HEADERS = {"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36"} + +recipes = [ + ("Arugula Pesto Chicken with Pecans & Roasted Butternut.cook", "arugula-pesto-chicken-with-pecans-roasted-butternut", "Arugula Pesto Chicken Pecans Roasted Butternut recipe garnishandgather"), + ("Bang Bang Tofu.cook", "bang-bang-tofu", "Bang Bang Tofu recipe"), + ("Chana Chickpea Salad.cook", "chana-chickpea-salad", "Chana Chickpea Salad recipe"), + ("Gaja's Bulgogi Lettuce Wraps.cook", "gaja-s-bulgogi-lettuce-wraps", "Gaja Bulgogi Lettuce Wraps recipe garnishandgather"), + ("Pecan-Brown Butter Trout.cook", "pecan-brown-butter-trout", "Pecan Brown Butter Trout recipe"), + ("West African Peanut Chicken.cook", "west-african-peanut-chicken", "West African Peanut Chicken recipe"), +] + +for file, slug, query in recipes: + fp = WORKDIR / file + dest = WORKDIR / "recipe-images" / f"{slug}.webp" + if dest.exists() and dest.stat().st_size > 10000: + print(f"[{slug}] Already done") + continue + + print(f"[{slug}] Searching: {query}") + try: + results = list(DDGS().text(query, max_results=5)) + except Exception as e: + print(f" Search error: {e}") + continue + + found = False + for r in results: + url = r.get("href", "") + if not url or any(s in url for s in ["pinterest","facebook","instagram"]): + continue + print(f" Fetching: {url}") + try: + resp = requests.get(url, headers=HEADERS, timeout=15) + resp.raise_for_status() + except Exception as e: + print(f" Failed: {e}") + continue + + soup = BeautifulSoup(resp.text, "html.parser") + img_urls = [] + + # og:image + for meta in soup.find_all("meta"): + c = meta.get("content", "") + p = (meta.get("property") or "").lower() + n = (meta.get("name") or "").lower() + if ("og:image" in p or "og:image" in n or "twitter:image" in n) and c and "logo" not in c.lower(): + img_urls.append(c) + + # img tags + for img in soup.find_all("img"): + src = img.get("src") or img.get("data-src") or "" + if src.startswith("http") and "logo" not in src.lower() and "icon" not in src.lower(): + img_urls.append(src) + + for img_url in img_urls[:5]: + try: + r2 = requests.get(img_url, headers=HEADERS, timeout=15) + r2.raise_for_status() + ct = r2.headers.get("content-type", "") + if ct.startswith("image/") and len(r2.content) > 10000: + dest.write_bytes(r2.content) + print(f" Downloaded ({len(r2.content)} bytes): {img_url[:60]}") + found = True + break + except: + pass + if found: + break + time.sleep(0.3) + + if found: + # Add image field + url_val = f"https://roux.roo.lol/recipe-images/{slug}.webp" + content = fp.read_text(encoding="utf-8") + if re.search(r"^image:", content, re.MULTILINE): + content = re.sub(r"^image:.*$", f"image: {url_val}", count=1, flags=re.MULTILINE, string=content) + else: + content = re.sub(r"^---$", f"image: {url_val}\n---", count=1, flags=re.MULTILINE, string=content) + fp.write_text(content, encoding="utf-8") + print(f" Updated image field") + else: + print(f" FAILED") + time.sleep(0.5) + +print("\nDone!") diff --git a/bin/fix-yaml-and-images.py b/bin/fix-yaml-and-images.py new file mode 100644 index 0000000..ab8900c --- /dev/null +++ b/bin/fix-yaml-and-images.py @@ -0,0 +1,128 @@ +#!/usr/bin/env python3 +"""Fix the broken YAML frontmatter: move image field inside YAML, and convert non-WebP images.""" + +import re, subprocess, sys +from pathlib import Path + +WORKDIR = Path("/home/jbrechtel/recipes/.worktrees/recipe-images") + +def fix_frontmatter(content: str) -> str: + """Move image: field inside the YAML block if it's outside.""" + # Check if image: is before the opening --- + lines = content.split('\n') + + # Find the first --- line + first_hr = -1 + for i, line in enumerate(lines): + if line.strip() == '---': + first_hr = i + break + + if first_hr <= 0: + return content # No frontmatter or image is at first line + + # Check if the line just before the first --- has image: + if first_hr > 0 and lines[first_hr - 1].startswith('image:'): + # Extract the image line + img_line = lines[first_hr - 1] + # Remove it from before --- + del lines[first_hr - 1] + # Now first_hr is one index less (or same if we deleted the line before) + # Find the closing --- + closing_hr = -1 + for i in range(first_hr, len(lines)): + if lines[i].strip() == '---': + closing_hr = i + break + + if closing_hr > first_hr: + # Insert image line before the closing --- + lines.insert(closing_hr, img_line) + else: + # Insert after the closing --- (fallback) + lines.insert(first_hr + 1, img_line) + + return '\n'.join(lines) + + +def fix_all_frontmatter(): + """Fix frontmatter for all .cook files.""" + fixed = 0 + for f in sorted(WORKDIR.glob("*.cook")): + content = f.read_text(encoding="utf-8") + fixed_content = fix_frontmatter(content) + if fixed_content != content: + f.write_text(fixed_content, encoding="utf-8") + print(f" Fixed: {f.name}") + fixed += 1 + print(f"\nFixed {fixed} files with mis-placed image fields") + return fixed + + +def convert_images(): + """Convert non-WebP images to actual WebP format.""" + converted = 0 + for img in sorted(WORKDIR.glob("recipe-images/*.webp")): + mime = subprocess.run( + ["file", "-b", "--mime-type", str(img)], + capture_output=True, text=True + ).stdout.strip() + + if mime != "image/webp": + print(f" Converting {img.name} (mime: {mime})") + # Use temp file to avoid corruption + tmp = img.with_suffix(".webp.tmp") + result = subprocess.run( + ["convert", str(img), str(tmp)], + capture_output=True, text=True + ) + if result.returncode == 0 and tmp.exists(): + tmp.replace(img) + print(f" Converted successfully") + converted += 1 + else: + print(f" Convert failed: {result.stderr}") + + print(f"\nConverted {converted} images to proper WebP") + return converted + + +if __name__ == "__main__": + print("=== Fixing YAML frontmatter ===") + fix_all_frontmatter() + + print("\n=== Converting image formats ===") + convert_images() + + # Final check + print("\n=== Final verification ===") + bad = 0 + for f in sorted(WORKDIR.glob("*.cook")): + content = f.read_text(encoding="utf-8") + # Check if image: is between --- markers + if "image:" in content: + # Find the opening --- + parts = content.split('---', 2) + if len(parts) >= 3: + if "image:" not in parts[1]: + print(f" STILL BROKEN: {f.name}") + bad += 1 + + if bad == 0: + print(" All files have image: inside YAML block ✅") + + webp_count = 0 + non_webp_count = 0 + for img in sorted(WORKDIR.glob("recipe-images/*.webp")): + mime = subprocess.run( + ["file", "-b", "--mime-type", str(img)], + capture_output=True, text=True + ).stdout.strip() + if mime == "image/webp": + webp_count += 1 + else: + non_webp_count += 1 + if non_webp_count <= 5: + print(f" NOT WEBP: {img.name} ({mime})") + + print(f" WebP images: {webp_count}, Non-WebP: {non_webp_count}") diff --git a/bin/scrape-images.py b/bin/scrape-images.py new file mode 100644 index 0000000..0ed3f33 --- /dev/null +++ b/bin/scrape-images.py @@ -0,0 +1,171 @@ +#!/usr/bin/env python3 +"""Scrape og:image from recipe source URLs, download images, update .cook files.""" + +import csv +import os +import re +import sys +import time +from pathlib import Path + +import requests +from bs4 import BeautifulSoup + +WORKDIR = Path("/home/jbrechtel/recipes/.worktrees/recipe-images") +HEADERS = { + "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", +} + + +def get_source_url(filepath: Path) -> str | None: + """Extract the source URL from a .cook file's YAML frontmatter.""" + content = filepath.read_text(encoding="utf-8") + match = re.search(r"^source:\s*(.+)$", content, re.MULTILINE) + if not match: + return None + val = match.group(1).strip() + # Only return actual URLs + if val.startswith("http://") or val.startswith("https://"): + return val + return None + + +def fetch_og_image(url: str, timeout: int = 20) -> str | None: + """Fetch a page and extract og:image URL.""" + try: + resp = requests.get(url, headers=HEADERS, timeout=timeout, allow_redirects=True) + resp.raise_for_status() + except requests.RequestException as e: + print(f" FETCH FAILED: {e}", file=sys.stderr) + return None + + soup = BeautifulSoup(resp.text, "html.parser") + + # Try og:image meta tag + for meta in soup.find_all("meta"): + if meta.get("property") == "og:image" and meta.get("content"): + return meta["content"] + if meta.get("name") == "og:image" and meta.get("content"): + return meta["content"] + + # Try twitter:image + for meta in soup.find_all("meta"): + if meta.get("name") == "twitter:image" and meta.get("content"): + return meta["content"] + + # Try finding the first large image (common in recipe sites) + for img in soup.find_all("img"): + src = img.get("src") or "" + if "logo" in src.lower() or "avatar" in src.lower() or "icon" in src.lower(): + continue + if src.startswith("http") and any(kw in src.lower() for kw in ["upload", "wp-content", "images"]): + return src + + return None + + +def download_image(url: str, dest: Path) -> bool: + """Download an image from URL to destination path.""" + try: + resp = requests.get(url, headers=HEADERS, timeout=30, stream=True) + resp.raise_for_status() + dest.write_bytes(resp.content) + return True + except requests.RequestException as e: + print(f" DOWNLOAD FAILED: {e}", file=sys.stderr) + return False + + +def add_image_field(filepath: Path, slug: str): + """Add or update the image field in a .cook file's YAML frontmatter.""" + url = f"https://roux.roo.lol/recipe-images/{slug}.webp" + content = filepath.read_text(encoding="utf-8") + + # If image field already exists, replace it + if re.search(r"^image:", content, re.MULTILINE): + content = re.sub(r"^image:.*$", f"image: {url}", content, count=1, flags=re.MULTILINE) + else: + # Insert before closing --- + content = re.sub(r"^---$", f"image: {url}\n---", content, count=1, flags=re.MULTILINE) + + filepath.write_text(content, encoding="utf-8") + print(f" Updated image field: {filepath.name}", file=sys.stderr) + + +def process_recipe(filepath: Path, slug: str) -> bool: + """Process a single recipe: find image, download, update frontmatter.""" + dest = WORKDIR / "recipe-images" / f"{slug}.webp" + + # Skip if already downloaded + if dest.exists(): + print(f"[{slug}] Image already exists, skipping download", file=sys.stderr) + add_image_field(filepath, slug) + return True + + # Try to get source URL and scrape image + src_url = get_source_url(filepath) + if src_url: + print(f"[{slug}] Scraping {src_url}", file=sys.stderr) + img_url = fetch_og_image(src_url) + if img_url: + print(f" Found: {img_url}", file=sys.stderr) + if download_image(img_url, dest): + print(f" Downloaded to {dest.name}", file=sys.stderr) + add_image_field(filepath, slug) + return True + else: + print(f" Download failed", file=sys.stderr) + + return False + + +def main(): + csv_file = WORKDIR / "docs" / "no-image-has-fm.csv" + if not csv_file.exists(): + print(f"CSV not found: {csv_file}", file=sys.stderr) + sys.exit(1) + + recipes = [] + with open(csv_file) as f: + reader = csv.reader(f, delimiter="|") + for row in reader: + if len(row) >= 2: + recipes.append((row[0].strip(), row[1].strip())) + + print(f"Processing {len(recipes)} recipes...", file=sys.stderr) + + success = [] + failed = [] + + for filename, slug in recipes: + filepath = WORKDIR / filename + if not filepath.exists(): + print(f"[{slug}] File not found: {filepath}", file=sys.stderr) + failed.append(slug) + continue + + ok = process_recipe(filepath, slug) + if ok: + success.append(slug) + else: + failed.append(slug) + + # Be polite to servers + time.sleep(0.5) + + print(f"\n=== Results ===", file=sys.stderr) + print(f"Success: {len(success)}", file=sys.stderr) + print(f"Failed: {len(failed)}", file=sys.stderr) + if failed: + print(f"Failed slugs: {', '.join(failed)}", file=sys.stderr) + + # Write failed slugs to file for retry + if failed: + with open(WORKDIR / "docs" / "failed-images.csv", "w") as f: + for slug in failed: + f.write(f"{slug}\n") + + +if __name__ == "__main__": + main() diff --git a/bin/search-and-download.py b/bin/search-and-download.py new file mode 100644 index 0000000..96a101d --- /dev/null +++ b/bin/search-and-download.py @@ -0,0 +1,233 @@ +#!/usr/bin/env python3 +"""Search the web for recipe images, download them, and update .cook files. + +Uses DuckDuckGo search to find recipe pages, then scrapes og:image. +""" + +import csv +import os +import re +import sys +import time +from pathlib import Path + +import requests +from bs4 import BeautifulSoup +from duckduckgo_search import DDGS + +WORKDIR = Path("/home/jbrechtel/recipes/.worktrees/recipe-images") +HEADERS = { + "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36", +} + +IMAGE_EXTENSIONS = {".jpg", ".jpeg", ".png", ".webp", ".gif"} + + +def fetch_og_image(url: str) -> str | None: + """Fetch a page and extract og:image URL.""" + try: + resp = requests.get(url, headers=HEADERS, timeout=15, allow_redirects=True) + resp.raise_for_status() + except requests.RequestException: + return None + + soup = BeautifulSoup(resp.text, "html.parser") + + # Try og:image meta tag (property or name) + for meta in soup.find_all("meta"): + prop = (meta.get("property") or "").lower() + name = (meta.get("name") or "").lower() + content = meta.get("content", "") + if "og:image" in prop and content: + return content + if "og:image" in name and content: + return content + if "twitter:image" in name and content: + return content + + # Try schema.org JSON-LD + for script in soup.find_all("script", type="application/ld+json"): + import json + try: + data = json.loads(script.string) + if isinstance(data, dict): + img = data.get("image") + if isinstance(img, str) and img.startswith("http"): + return img + if isinstance(img, dict): + url = img.get("contentUrl") or img.get("url", "") + if url.startswith("http"): + return url + if isinstance(img, list) and img: + first = img[0] + if isinstance(first, str): + return first + if isinstance(first, dict): + url = first.get("contentUrl") or first.get("url", "") + if url.startswith("http"): + return url + except (json.JSONDecodeError, AttributeError): + pass + + return None + + +def search_and_find_image(query: str) -> str | None: + """Search DuckDuckGo for a recipe and find og:image.""" + try: + results = list(DDGS().text(query, max_results=5)) + except Exception as e: + print(f" Search error: {e}", file=sys.stderr) + return None + + for r in results: + url = r.get("href", "") + if not url or "pinterest" in url or "facebook" in url or "instagram" in url: + continue + print(f" Trying: {url}", file=sys.stderr) + img = fetch_og_image(url) + if img: + print(f" Found image: {img}", file=sys.stderr) + return img + time.sleep(0.3) + + return None + + +def download_image(url: str, dest: Path) -> bool: + """Download an image from URL to destination path.""" + try: + resp = requests.get(url, headers=HEADERS, timeout=30, stream=True) + resp.raise_for_status() + dest.write_bytes(resp.content) + return True + except requests.RequestException as e: + print(f" Download failed: {e}", file=sys.stderr) + return False + + +def add_image_field(filepath: Path, slug: str): + """Add or update the image field in a .cook file's YAML frontmatter.""" + url = f"https://roux.roo.lol/recipe-images/{slug}.webp" + content = filepath.read_text(encoding="utf-8") + + if re.search(r"^image:", content, re.MULTILINE): + content = re.sub(r"^image:.*$", f"image: {url}", count=1, flags=re.MULTILINE, string=content) + else: + content = re.sub(r"^---$", f"image: {url}\n---", count=1, flags=re.MULTILINE, string=content) + + filepath.write_text(content, encoding="utf-8") + print(f" Updated {filepath.name}", file=sys.stderr) + + +def get_source_url(filepath: Path) -> str | None: + """Extract source URL from .cook frontmatter.""" + content = filepath.read_text(encoding="utf-8") + match = re.search(r"^source:\s*(.+)$", content, re.MULTILINE) + if match: + val = match.group(1).strip() + if val.startswith("http://") or val.startswith("https://"): + return val + return None + + +def process_recipe(filename: str, slug: str) -> bool: + """Try to find and download an image for a recipe.""" + filepath = WORKDIR / filename + dest = WORKDIR / "recipe-images" / f"{slug}.webp" + + if dest.exists(): + print(f"[{slug}] Already exists", file=sys.stderr) + add_image_field(filepath, slug) + return True + + # Strategy 1: Try source URL if available + src_url = get_source_url(filepath) + if src_url: + print(f"[{slug}] Trying source URL: {src_url}", file=sys.stderr) + img = fetch_og_image(src_url) + if img: + if download_image(img, dest): + print(f" Downloaded from source", file=sys.stderr) + add_image_field(filepath, slug) + return True + + # Strategy 2: Search by recipe name + # Get the title from frontmatter + content = filepath.read_text(encoding="utf-8") + title_match = re.search(r"^title:\s*(.+)$", content, re.MULTILINE) + if title_match: + query = title_match.group(1).strip() + " recipe" + else: + query = filename.replace(".cook", "").replace("_", " ").replace("-", " ") + " recipe" + + print(f"[{slug}] Searching: {query}", file=sys.stderr) + img = search_and_find_image(query) + if img and download_image(img, dest): + print(f" Downloaded from search", file=sys.stderr) + add_image_field(filepath, slug) + return True + + # Strategy 3: Try with "og:image" or "recipe image" variations + query2 = query + " image" + print(f"[{slug}] Searching (alt): {query2}", file=sys.stderr) + img = search_and_find_image(query2) + if img and download_image(img, dest): + print(f" Downloaded from alt search", file=sys.stderr) + add_image_field(filepath, slug) + return True + + return False + + +def main(): + # First process the no-image-has-fm list + csv_file = WORKDIR / "docs" / "no-image-has-fm.csv" + if not csv_file.exists(): + print(f"CSV not found: {csv_file}", file=sys.stderr) + sys.exit(1) + + recipes = [] + with open(csv_file) as f: + reader = csv.reader(f, delimiter="|") + for row in reader: + if len(row) >= 2: + recipes.append((row[0].strip(), row[1].strip())) + + success = [] + failed = [] + + for filename, slug in recipes: + filepath = WORKDIR / filename + if not filepath.exists(): + failed.append(slug) + continue + + dest = WORKDIR / "recipe-images" / f"{slug}.webp" + if dest.exists() and re.search(r"^image:", filepath.read_text(), re.MULTILINE): + print(f"[{slug}] Already processed, skipping", file=sys.stderr) + success.append(slug) + continue + + ok = process_recipe(filename, slug) + if ok: + success.append(slug) + else: + failed.append(slug) + + # Be polite + time.sleep(0.5) + + print(f"\n=== Results ===", file=sys.stderr) + print(f"Success: {len(success)}", file=sys.stderr) + print(f"Failed: {len(failed)}", file=sys.stderr) + + if failed: + with open(WORKDIR / "docs" / "failed-images.csv", "w") as f: + for s in failed: + f.write(f"{s}\n") + print(f"Failed: {', '.join(failed)}", file=sys.stderr) + + +if __name__ == "__main__": + main() diff --git a/bin/search-images-ddgs.py b/bin/search-images-ddgs.py new file mode 100644 index 0000000..e171779 --- /dev/null +++ b/bin/search-images-ddgs.py @@ -0,0 +1,148 @@ +#!/usr/bin/env python3 +"""Search DuckDuckGo Images for recipe photos, download, update .cook files.""" + +import csv +import re +import sys +import time +from pathlib import Path + +import requests +from duckduckgo_search import DDGS + +WORKDIR = Path("/home/jbrechtel/recipes/.worktrees/recipe-images") +HEADERS = { + "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36", +} + + +def download_image(url: str, dest: Path) -> bool: + """Download an image from URL to destination path.""" + try: + resp = requests.get(url, headers=HEADERS, timeout=30, stream=True) + resp.raise_for_status() + # Validate it's actually an image + content_type = resp.headers.get("content-type", "") + if not content_type.startswith("image/"): + print(f" Not an image (content-type: {content_type})", file=sys.stderr) + return False + dest.write_bytes(resp.content) + return True + except requests.RequestException as e: + print(f" Download failed: {e}", file=sys.stderr) + return False + + +def add_image_field(filepath: Path, slug: str): + """Add or update the image field in a .cook file.""" + url = f"https://roux.roo.lol/recipe-images/{slug}.webp" + content = filepath.read_text(encoding="utf-8") + + if re.search(r"^image:", content, re.MULTILINE): + content = re.sub(r"^image:.*$", f"image: {url}", count=1, flags=re.MULTILINE, string=content) + else: + content = re.sub(r"^---$", f"image: {url}\n---", count=1, flags=re.MULTILINE, string=content) + + filepath.write_text(content, encoding="utf-8") + print(f" Updated {filepath.name}", file=sys.stderr) + + +def search_images(query: str, max_results: int = 5): + """Search DuckDuckGo Images for a recipe and return image URLs.""" + try: + results = list(DDGS().images(query, max_results=max_results)) + return [r["image"] for r in results if r.get("image")] + except Exception as e: + print(f" Image search error: {e}", file=sys.stderr) + return [] + + +def get_title(filepath: Path) -> str: + """Extract title from .cook frontmatter.""" + content = filepath.read_text(encoding="utf-8") + match = re.search(r"^title:\s*(.+)$", content, re.MULTILINE) + if match: + return match.group(1).strip() + # Fall back to filename + name = filepath.stem + return name.replace("_", " ").replace("-", " ") + + +def main(): + csv_file = WORKDIR / "docs" / "failed-images.csv" + # Also check which are actually missing + existing_csv = WORKDIR / "docs" / "no-image-has-fm.csv" + + recipes = [] + with open(existing_csv) as f: + reader = csv.reader(f, delimiter="|") + for row in reader: + if len(row) >= 2: + recipes.append((row[0].strip(), row[1].strip())) + + # Filter to those without an image file or without image field + to_process = [] + for filename, slug in recipes: + filepath = WORKDIR / filename + dest = WORKDIR / "recipe-images" / f"{slug}.webp" + has_image_file = dest.exists() + has_image_field = False + if filepath.exists(): + content = filepath.read_text(encoding="utf-8") + has_image_field = bool(re.search(r"^image:", content, re.MULTILINE)) + + if not has_image_file or not has_image_field: + to_process.append((filename, slug)) + + print(f"Processing {len(to_process)} remaining recipes...", file=sys.stderr) + + success = [] + failed = [] + + for filename, slug in to_process: + filepath = WORKDIR / filename + dest = WORKDIR / "recipe-images" / f"{slug}.webp" + + if not filepath.exists(): + failed.append(slug) + continue + + title = get_title(filepath) + queries = [ + f"{title} recipe", + title, + ] + + found = False + for query in queries: + print(f"[{slug}] Searching images: {query}", file=sys.stderr) + urls = search_images(query) + for img_url in urls: + # Skip tiny icons, logos + if any(kw in img_url.lower() for kw in ["logo", "icon", "avatar", "merriam", "wikipedia"]): + continue + print(f" Trying: {img_url[:80]}...", file=sys.stderr) + if download_image(img_url, dest): + print(f" Downloaded!", file=sys.stderr) + add_image_field(filepath, slug) + found = True + break + time.sleep(0.2) + if found: + break + time.sleep(0.5) + + if found: + success.append(slug) + else: + failed.append(slug) + + print(f"\n=== Results ===", file=sys.stderr) + print(f"Success: {len(success)}", file=sys.stderr) + print(f"Failed: {len(failed)}", file=sys.stderr) + if failed: + print(f"Failed: {', '.join(failed)}", file=sys.stderr) + + +if __name__ == "__main__": + main() diff --git a/bin/task3-frontmatter.py b/bin/task3-frontmatter.py new file mode 100644 index 0000000..24f3996 --- /dev/null +++ b/bin/task3-frontmatter.py @@ -0,0 +1,156 @@ +#!/usr/bin/env python3 +"""Add frontmatter and images to 9 recipes without frontmatter.""" + +import re, sys, time +from pathlib import Path + +import requests +from bs4 import BeautifulSoup +from ddgs import DDGS + +WORKDIR = Path("/home/jbrechtel/recipes/.worktrees/recipe-images") +HEADERS = {"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36"} + +# (filename, slug, title, source_url_or_empty) +recipes = [ + ("Black Pepper Tofu (Ottolenghi).cook", "black-pepper-tofu-ottolenghi", "Black Pepper Tofu (Ottolenghi)", ""), + ("Black Pepper Tofu with Bok Choy.cook", "black-pepper-tofu-with-bok-choy", "Black Pepper Tofu with Bok Choy", ""), + ("butternut-turkey-chili.cook", "butternut-turkey-chili", "Butternut & Turkey Chili", ""), + ("Caramel Cake.cook", "caramel-cake", "Caramel Cake", ""), + ("Caramel Icing.cook", "caramel-icing", "Caramel Icing", ""), + ("example-fried-rice.cook", "example-fried-rice", "Fried Rice", ""), + ("indian-spiced-chicken.cook", "indian-spiced-chicken", "Indian Spiced Chicken", ""), + ("Italian Sausage and Delicata Rigatoni.cook", "italian-sausage-and-delicata-rigatoni", "Italian Sausage & Delicata Rigatoni", ""), + ("shrimp-feta.cook", "shrimp-feta", "Orzo with shrimp, tomato and marinated feta", "https://thehappyfoodie.co.uk/recipes/ottolenghis-orzo-with-prawns-tomato-and-marinated-feta/"), +] + + +def fetch_og_image(url: str) -> str | None: + try: + resp = requests.get(url, headers=HEADERS, timeout=15) + resp.raise_for_status() + except: + return None + soup = BeautifulSoup(resp.text, "html.parser") + for meta in soup.find_all("meta"): + c = meta.get("content", "") + p = (meta.get("property") or "").lower() + n = (meta.get("name") or "").lower() + if ("og:image" in p or "og:image" in n or "twitter:image" in n) and c: + return c + # JSON-LD + for script in soup.find_all("script", type="application/ld+json"): + try: + import json + data = json.loads(script.string) + items = data if isinstance(data, list) else [data] + for item in items: + if isinstance(item, dict) and item.get("@type") == "Recipe": + img = item.get("image") + if isinstance(img, str): return img + if isinstance(img, list): + for i in img: + if isinstance(i, str): return i + if isinstance(i, dict): + u = i.get("contentUrl") or i.get("url", "") + if u: return u + if isinstance(img, dict): + u = img.get("contentUrl") or img.get("url", "") + if u: return u + except: + pass + return None + + +def search_and_scrape(query: str) -> str | None: + try: + results = list(DDGS().text(query, max_results=5)) + except: + return None + for r in results: + url = r.get("href", "") + if not url or "pinterest" in url or "facebook" in url: + continue + img = fetch_og_image(url) + if img: + return img + time.sleep(0.3) + return None + + +def download_image(url: str, dest: Path) -> bool: + try: + resp = requests.get(url, headers=HEADERS, timeout=30) + resp.raise_for_status() + ct = resp.headers.get("content-type", "") + if not ct.startswith("image/"): + return False + content = resp.content + if len(content) < 5000: + return False + dest.write_bytes(content) + return True + except: + return False + + +def add_frontmatter(filepath: Path, slug: str, title: str): + url = f"https://roux.roo.lol/recipe-images/{slug}.webp" + content = filepath.read_text(encoding="utf-8") + + frontmatter = f"""--- +title: {title} +description: +servings: 1 +category: uncategorized +source: Unknown +image: {url} +--- + +""" + filepath.write_text(frontmatter + content, encoding="utf-8") + print(f" Added frontmatter to {filepath.name}", file=sys.stderr) + + +def main(): + for filename, slug, title, src_url in recipes: + fp = WORKDIR / filename + dest = WORKDIR / "recipe-images" / f"{slug}.webp" + + print(f"[{slug}] Processing {filename}", file=sys.stderr) + + # Find and download image + img_url = None + if src_url: + print(f" Trying source URL: {src_url}", file=sys.stderr) + img_url = fetch_og_image(src_url) + time.sleep(0.3) + + if not img_url: + print(f" Searching: {title} recipe", file=sys.stderr) + img_url = search_and_scrape(f"{title} recipe") + time.sleep(0.3) + + if not img_url: + print(f" Searching (alt): {title}", file=sys.stderr) + img_url = search_and_scrape(title) + time.sleep(0.3) + + if img_url: + print(f" Found: {img_url[:80]}", file=sys.stderr) + if download_image(img_url, dest): + print(f" Downloaded ({dest.stat().st_size} bytes)", file=sys.stderr) + else: + print(f" Download failed, will still add frontmatter", file=sys.stderr) + else: + print(f" No image found, will still add frontmatter", file=sys.stderr) + + # Add frontmatter (with or without image) + add_frontmatter(fp, slug, title) + print(f" Done", file=sys.stderr) + + print("\n=== Task 3 complete ===", file=sys.stderr) + + +if __name__ == "__main__": + main() diff --git a/bin/update-image-field.sh b/bin/update-image-field.sh new file mode 100755 index 0000000..5af4bdd --- /dev/null +++ b/bin/update-image-field.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +set -euo pipefail + +while IFS='|' read -r file slug; do + new_url="https://roux.roo.lol/recipe-images/$slug.webp" + sed -i "s|^image:.*|image: $new_url|" "$file" + echo "[$slug] Updated image field" +done diff --git a/butternut-turkey-chili.cook b/butternut-turkey-chili.cook index b3e305d..ed5d9e9 100644 --- a/butternut-turkey-chili.cook +++ b/butternut-turkey-chili.cook @@ -1,3 +1,12 @@ +--- +title: Butternut & Turkey Chili +description: +servings: 1 +category: uncategorized +source: Unknown +image: https://roux.roo.lol/recipe-images/butternut-turkey-chili.webp +--- + >> title: Butternut & Turkey Chili >> author: Chef Torie Cox >> servings: 2 diff --git a/cauliflower-milanese.cook b/cauliflower-milanese.cook index 3b923d7..d078709 100644 --- a/cauliflower-milanese.cook +++ b/cauliflower-milanese.cook @@ -10,6 +10,7 @@ totalTime: 55 minutes prepTime: 15 minutes cookTime: 40 minutes tags: arugula, bread crumb, budget, cauliflower, parmesan, sheet-pan, fall, vegetarian +image: https://roux.roo.lol/recipe-images/cauliflower-milanese.webp --- == Ingredients == diff --git a/docs/plans/2026-05-21-recipe-images-plan.md b/docs/plans/2026-05-21-recipe-images-plan.md index 253f3e0..c172bc9 100644 --- a/docs/plans/2026-05-21-recipe-images-plan.md +++ b/docs/plans/2026-05-21-recipe-images-plan.md @@ -4,7 +4,7 @@ **Goal:** Give every `.cook` recipe file an `image:` field in YAML frontmatter pointing to `https://roux.roo.lol/recipe-images/.webp`, and download each image locally. -**Architecture:** Three parallel batches — (1) relink the 19 existing images, (2) discover + download + link 48 missing images (recipes with frontmatter), (3) create frontmatter + discover + link 9 more (recipes without frontmatter). Use subagent parallel dispatch for image discovery to keep wall-clock time manageable. +**Architecture:** Three parallel batches — (1) relink the 19 existing images, (2) discover + download + link 50 missing images (recipes with frontmatter), (3) create frontmatter + discover + link 9 more (recipes without frontmatter). Use subagent parallel dispatch for image discovery to keep wall-clock time manageable. **Tech Stack:** bash, curl, ImageMagick (convert), subagent researcher for web image search @@ -13,50 +13,56 @@ ### Task 0: Setup — slug map, image dir, helper script **Files:** -- Create: `/home/jbrechtel/recipes/docs/slugs.csv` -- Modify: none yet +- Create: `docs/slugs.csv` +- Create: `docs/has-image.csv` +- Create: `docs/no-image-has-fm.csv` +- Create: `docs/no-fm.csv` - [ ] **Step 1: Generate slug mapping** -Run a one-liner that prints every `.cook` file with its slugified stem: +Run a one-liner that prints every `.cook` file with its slugified stem, then deduplicate any collisions: ```bash -cd /home/jbrechtel/recipes +cd /home/jbrechtel/recipes/.worktrees/recipe-images for f in *.cook; do stem="${f%.cook}" slug=$(echo "$stem" \ | tr '[:upper:]' '[:lower:]' \ | sed -e 's/[^a-z0-9]/-/g' -e 's/--*/-/g' -e 's/^-//' -e 's/-$//') echo "$f|$slug" -done > docs/slugs.csv -head docs/slugs.csv +done | awk -F'|' ' +{ + slug=$2 + count[slug]++ + if (count[slug] > 1) { + slug = slug "-" count[slug] + } + print $1 "|" slug +}' > docs/slugs.csv ``` -Expected: a pipe-delimited CSV like `Alain-Ducase-Bread.cook|alain-ducase-bread`. +Total: 78 unique slugs (6 duplicate pairs get `-2` suffix). - [ ] **Step 2: Create image directory** ```bash -mkdir -p /home/jbrechtel/recipes/recipe-images +mkdir -p recipe-images ``` - [ ] **Step 3: Classify each recipe** ```bash -cd /home/jbrechtel/recipes -echo "=== Already has image ===" +cd /home/jbrechtel/recipes/.worktrees/recipe-images while IFS='|' read -r f slug; do if grep -q "^image:" "$f" 2>/dev/null; then echo "$f|$slug"; fi done < docs/slugs.csv > docs/has-image.csv -echo "=== Has frontmatter, no image ===" while IFS='|' read -r f slug; do if head -1 "$f" 2>/dev/null | grep -q "^---"; then if ! grep -q "^image:" "$f" 2>/dev/null; then echo "$f|$slug"; fi fi done < docs/slugs.csv > docs/no-image-has-fm.csv -echo "=== No frontmatter ===" while IFS='|' read -r f slug; do if ! head -1 "$f" 2>/dev/null | grep -q "^---"; then echo "$f|$slug"; fi done < docs/slugs.csv > docs/no-fm.csv @@ -64,12 +70,11 @@ done < docs/slugs.csv > docs/no-fm.csv wc -l docs/has-image.csv docs/no-image-has-fm.csv docs/no-fm.csv ``` -Expected: 19 / 48 / 9 lines respectively. +Expected: 19 / 50 / 9 = 78 total. - [ ] **Step 4: Commit setup** ```bash -cd /home/jbrechtel/recipes git add docs/slugs.csv docs/has-image.csv docs/no-image-has-fm.csv docs/no-fm.csv git commit -m "chore: add recipe slug mapping and classification CSVs" ``` diff --git a/example-fried-rice.cook b/example-fried-rice.cook index 2f289c5..93932ed 100644 --- a/example-fried-rice.cook +++ b/example-fried-rice.cook @@ -1,3 +1,12 @@ +--- +title: Fried Rice +description: +servings: 1 +category: uncategorized +source: Unknown +image: https://roux.roo.lol/recipe-images/example-fried-rice.webp +--- + -- TODO add source Mix together @oyster sauce{1%tbsp}, @soy sauce{5%tbsp} and @sesame oil{5%tsp}, set aside. diff --git a/indian-spiced-chicken.cook b/indian-spiced-chicken.cook index 33f4d3b..34c2f5a 100644 --- a/indian-spiced-chicken.cook +++ b/indian-spiced-chicken.cook @@ -1,3 +1,12 @@ +--- +title: Indian Spiced Chicken +description: +servings: 1 +category: uncategorized +source: Gather and Garnish +image: https://roux.roo.lol/recipe-images/indian-spiced-chicken.webp +--- + >> source: Gather and Garnish >> time required: 35 minutes diff --git a/recipe-images/alain-ducase-bread.webp b/recipe-images/alain-ducase-bread.webp new file mode 100644 index 0000000..b25344d Binary files /dev/null and b/recipe-images/alain-ducase-bread.webp differ diff --git a/recipe-images/apple-cider-vinegar-dressing.webp b/recipe-images/apple-cider-vinegar-dressing.webp new file mode 100644 index 0000000..8423285 Binary files /dev/null and b/recipe-images/apple-cider-vinegar-dressing.webp differ diff --git a/recipe-images/arugula-pesto-chicken-with-pecans-roasted-butternut.webp b/recipe-images/arugula-pesto-chicken-with-pecans-roasted-butternut.webp new file mode 100644 index 0000000..f77cf61 Binary files /dev/null and b/recipe-images/arugula-pesto-chicken-with-pecans-roasted-butternut.webp differ diff --git a/recipe-images/arugula-pesto-wheat-berries-recipe.webp b/recipe-images/arugula-pesto-wheat-berries-recipe.webp new file mode 100644 index 0000000..c015c7f Binary files /dev/null and b/recipe-images/arugula-pesto-wheat-berries-recipe.webp differ diff --git a/recipe-images/asparagus-salad.webp b/recipe-images/asparagus-salad.webp new file mode 100644 index 0000000..c92dc80 Binary files /dev/null and b/recipe-images/asparagus-salad.webp differ diff --git a/recipe-images/authentic-cacio-e-pepe-recipe.webp b/recipe-images/authentic-cacio-e-pepe-recipe.webp new file mode 100644 index 0000000..1a8e3c2 Binary files /dev/null and b/recipe-images/authentic-cacio-e-pepe-recipe.webp differ diff --git a/recipe-images/baked-chile-relleno-with-black-beans.webp b/recipe-images/baked-chile-relleno-with-black-beans.webp new file mode 100644 index 0000000..1b6a1b1 Binary files /dev/null and b/recipe-images/baked-chile-relleno-with-black-beans.webp differ diff --git a/recipe-images/bang-bang-tofu.webp b/recipe-images/bang-bang-tofu.webp new file mode 100644 index 0000000..70ee011 Binary files /dev/null and b/recipe-images/bang-bang-tofu.webp differ diff --git a/recipe-images/barbecue-chicken-with-crispy-pan-fried-okra-cheddar-biscuits.webp b/recipe-images/barbecue-chicken-with-crispy-pan-fried-okra-cheddar-biscuits.webp new file mode 100644 index 0000000..c829e57 Binary files /dev/null and b/recipe-images/barbecue-chicken-with-crispy-pan-fried-okra-cheddar-biscuits.webp differ diff --git a/recipe-images/black-bean-and-corn-salad.webp b/recipe-images/black-bean-and-corn-salad.webp new file mode 100644 index 0000000..69bd891 Binary files /dev/null and b/recipe-images/black-bean-and-corn-salad.webp differ diff --git a/recipe-images/black-pepper-tofu-ottolenghi.webp b/recipe-images/black-pepper-tofu-ottolenghi.webp new file mode 100644 index 0000000..e9e0b30 Binary files /dev/null and b/recipe-images/black-pepper-tofu-ottolenghi.webp differ diff --git a/recipe-images/black-pepper-tofu-with-bok-choy.webp b/recipe-images/black-pepper-tofu-with-bok-choy.webp new file mode 100644 index 0000000..6f401a1 Binary files /dev/null and b/recipe-images/black-pepper-tofu-with-bok-choy.webp differ diff --git a/recipe-images/blackened-shrimp-and-gouda-grits.webp b/recipe-images/blackened-shrimp-and-gouda-grits.webp new file mode 100644 index 0000000..c639e6c Binary files /dev/null and b/recipe-images/blackened-shrimp-and-gouda-grits.webp differ diff --git a/recipe-images/butter-tofu.webp b/recipe-images/butter-tofu.webp new file mode 100644 index 0000000..d88788d Binary files /dev/null and b/recipe-images/butter-tofu.webp differ diff --git a/recipe-images/butternut-turkey-chili-2.webp b/recipe-images/butternut-turkey-chili-2.webp new file mode 100644 index 0000000..deec135 Binary files /dev/null and b/recipe-images/butternut-turkey-chili-2.webp differ diff --git a/recipe-images/butternut-turkey-chili-with-sweet-peppers-spiced-pepitas-queso-fresco.webp b/recipe-images/butternut-turkey-chili-with-sweet-peppers-spiced-pepitas-queso-fresco.webp new file mode 100644 index 0000000..9e81c2c Binary files /dev/null and b/recipe-images/butternut-turkey-chili-with-sweet-peppers-spiced-pepitas-queso-fresco.webp differ diff --git a/recipe-images/butternut-turkey-chili.webp b/recipe-images/butternut-turkey-chili.webp new file mode 100644 index 0000000..f0a6160 Binary files /dev/null and b/recipe-images/butternut-turkey-chili.webp differ diff --git a/recipe-images/cabbage-salad.webp b/recipe-images/cabbage-salad.webp new file mode 100644 index 0000000..7836bbf Binary files /dev/null and b/recipe-images/cabbage-salad.webp differ diff --git a/recipe-images/cajun-shrimp-and-sausage-vegetable-foil-packets.webp b/recipe-images/cajun-shrimp-and-sausage-vegetable-foil-packets.webp new file mode 100644 index 0000000..49a9d0b Binary files /dev/null and b/recipe-images/cajun-shrimp-and-sausage-vegetable-foil-packets.webp differ diff --git a/recipe-images/cajun-spice-mix-for-pecans-oysters-etc.webp b/recipe-images/cajun-spice-mix-for-pecans-oysters-etc.webp new file mode 100644 index 0000000..c0d158d Binary files /dev/null and b/recipe-images/cajun-spice-mix-for-pecans-oysters-etc.webp differ diff --git a/recipe-images/caramel-cake.webp b/recipe-images/caramel-cake.webp new file mode 100644 index 0000000..5f38405 Binary files /dev/null and b/recipe-images/caramel-cake.webp differ diff --git a/recipe-images/caramel-icing.webp b/recipe-images/caramel-icing.webp new file mode 100644 index 0000000..5505b58 Binary files /dev/null and b/recipe-images/caramel-icing.webp differ diff --git a/recipe-images/cauliflower-milanese.webp b/recipe-images/cauliflower-milanese.webp new file mode 100644 index 0000000..563c223 Binary files /dev/null and b/recipe-images/cauliflower-milanese.webp differ diff --git a/recipe-images/chana-chickpea-salad.webp b/recipe-images/chana-chickpea-salad.webp new file mode 100644 index 0000000..e93690c Binary files /dev/null and b/recipe-images/chana-chickpea-salad.webp differ diff --git a/recipe-images/chana-salad.webp b/recipe-images/chana-salad.webp new file mode 100644 index 0000000..37f150a Binary files /dev/null and b/recipe-images/chana-salad.webp differ diff --git a/recipe-images/chicken-and-pumpkin-gnocchi-with-ricotta.webp b/recipe-images/chicken-and-pumpkin-gnocchi-with-ricotta.webp new file mode 100644 index 0000000..600d594 Binary files /dev/null and b/recipe-images/chicken-and-pumpkin-gnocchi-with-ricotta.webp differ diff --git a/recipe-images/chickpea-butter-curry-2.webp b/recipe-images/chickpea-butter-curry-2.webp new file mode 100644 index 0000000..822063b Binary files /dev/null and b/recipe-images/chickpea-butter-curry-2.webp differ diff --git a/recipe-images/chickpea-butter-curry.webp b/recipe-images/chickpea-butter-curry.webp new file mode 100644 index 0000000..851b1ed Binary files /dev/null and b/recipe-images/chickpea-butter-curry.webp differ diff --git a/recipe-images/chinese-orange-shrimp.webp b/recipe-images/chinese-orange-shrimp.webp new file mode 100644 index 0000000..2f0dd92 Binary files /dev/null and b/recipe-images/chinese-orange-shrimp.webp differ diff --git a/recipe-images/chocolate-mousse-cake-with-raspberries.webp b/recipe-images/chocolate-mousse-cake-with-raspberries.webp new file mode 100644 index 0000000..f0b757f Binary files /dev/null and b/recipe-images/chocolate-mousse-cake-with-raspberries.webp differ diff --git a/recipe-images/cilantro-pesto-shrimp-over-orzo.webp b/recipe-images/cilantro-pesto-shrimp-over-orzo.webp new file mode 100644 index 0000000..7a0d54a Binary files /dev/null and b/recipe-images/cilantro-pesto-shrimp-over-orzo.webp differ diff --git a/recipe-images/crispy-roasted-chickpeas-garbanzo-beans-2.webp b/recipe-images/crispy-roasted-chickpeas-garbanzo-beans-2.webp new file mode 100644 index 0000000..a3956bf Binary files /dev/null and b/recipe-images/crispy-roasted-chickpeas-garbanzo-beans-2.webp differ diff --git a/recipe-images/crispy-roasted-chickpeas-garbanzo-beans.webp b/recipe-images/crispy-roasted-chickpeas-garbanzo-beans.webp new file mode 100644 index 0000000..f03b06f Binary files /dev/null and b/recipe-images/crispy-roasted-chickpeas-garbanzo-beans.webp differ diff --git a/recipe-images/crispy-tofu-with-cashews-and-blistered-snap-peas.webp b/recipe-images/crispy-tofu-with-cashews-and-blistered-snap-peas.webp new file mode 100644 index 0000000..f10f69f Binary files /dev/null and b/recipe-images/crispy-tofu-with-cashews-and-blistered-snap-peas.webp differ diff --git a/recipe-images/dried-fava-soup.webp b/recipe-images/dried-fava-soup.webp new file mode 100644 index 0000000..f03b06f Binary files /dev/null and b/recipe-images/dried-fava-soup.webp differ diff --git a/recipe-images/easy-lemon-rosemary-white-bean-soup-2.webp b/recipe-images/easy-lemon-rosemary-white-bean-soup-2.webp new file mode 100644 index 0000000..3dff8a9 Binary files /dev/null and b/recipe-images/easy-lemon-rosemary-white-bean-soup-2.webp differ diff --git a/recipe-images/easy-lemon-rosemary-white-bean-soup.webp b/recipe-images/easy-lemon-rosemary-white-bean-soup.webp new file mode 100644 index 0000000..471241c Binary files /dev/null and b/recipe-images/easy-lemon-rosemary-white-bean-soup.webp differ diff --git a/recipe-images/easy-vegetarian-chili.webp b/recipe-images/easy-vegetarian-chili.webp new file mode 100644 index 0000000..a90f02d Binary files /dev/null and b/recipe-images/easy-vegetarian-chili.webp differ diff --git a/recipe-images/example-fried-rice.webp b/recipe-images/example-fried-rice.webp new file mode 100644 index 0000000..f53af2c Binary files /dev/null and b/recipe-images/example-fried-rice.webp differ diff --git a/recipe-images/fettucine-with-spiced-cherry-tomato-sauce.webp b/recipe-images/fettucine-with-spiced-cherry-tomato-sauce.webp new file mode 100644 index 0000000..58d1f68 Binary files /dev/null and b/recipe-images/fettucine-with-spiced-cherry-tomato-sauce.webp differ diff --git a/recipe-images/gaja-s-bulgogi-lettuce-wraps.webp b/recipe-images/gaja-s-bulgogi-lettuce-wraps.webp new file mode 100644 index 0000000..b2ebe6b Binary files /dev/null and b/recipe-images/gaja-s-bulgogi-lettuce-wraps.webp differ diff --git a/recipe-images/gochugaru-honey-salmon.webp b/recipe-images/gochugaru-honey-salmon.webp new file mode 100644 index 0000000..b6e6e30 Binary files /dev/null and b/recipe-images/gochugaru-honey-salmon.webp differ diff --git a/recipe-images/green-beans-with-lemon-and-garlic.webp b/recipe-images/green-beans-with-lemon-and-garlic.webp new file mode 100644 index 0000000..6d0137d Binary files /dev/null and b/recipe-images/green-beans-with-lemon-and-garlic.webp differ diff --git a/recipe-images/indian-spiced-chicken-2.webp b/recipe-images/indian-spiced-chicken-2.webp new file mode 100644 index 0000000..1975b89 Binary files /dev/null and b/recipe-images/indian-spiced-chicken-2.webp differ diff --git a/recipe-images/indian-spiced-chicken.webp b/recipe-images/indian-spiced-chicken.webp new file mode 100644 index 0000000..4f2f5c9 Binary files /dev/null and b/recipe-images/indian-spiced-chicken.webp differ diff --git a/recipe-images/italian-sausage-and-delicata-rigatoni.webp b/recipe-images/italian-sausage-and-delicata-rigatoni.webp new file mode 100644 index 0000000..153fdc2 Binary files /dev/null and b/recipe-images/italian-sausage-and-delicata-rigatoni.webp differ diff --git a/recipe-images/kale-and-chestnut-stew.webp b/recipe-images/kale-and-chestnut-stew.webp new file mode 100644 index 0000000..616a20a Binary files /dev/null and b/recipe-images/kale-and-chestnut-stew.webp differ diff --git a/recipe-images/kkanpoong-tofu.webp b/recipe-images/kkanpoong-tofu.webp new file mode 100644 index 0000000..a942b89 Binary files /dev/null and b/recipe-images/kkanpoong-tofu.webp differ diff --git a/recipe-images/korean-shrimp-tacos.webp b/recipe-images/korean-shrimp-tacos.webp new file mode 100644 index 0000000..7d84260 Binary files /dev/null and b/recipe-images/korean-shrimp-tacos.webp differ diff --git a/recipe-images/kung-pao-shrimp-with-sichuan-roasted-green-beans.webp b/recipe-images/kung-pao-shrimp-with-sichuan-roasted-green-beans.webp new file mode 100644 index 0000000..7a696b4 Binary files /dev/null and b/recipe-images/kung-pao-shrimp-with-sichuan-roasted-green-beans.webp differ diff --git a/recipe-images/lactation-cookies-2.webp b/recipe-images/lactation-cookies-2.webp new file mode 100644 index 0000000..2053fcd Binary files /dev/null and b/recipe-images/lactation-cookies-2.webp differ diff --git a/recipe-images/lactation-cookies.webp b/recipe-images/lactation-cookies.webp new file mode 100644 index 0000000..8a9b53e Binary files /dev/null and b/recipe-images/lactation-cookies.webp differ diff --git a/recipe-images/lentil-soup-with-lemon-and-turmeric.webp b/recipe-images/lentil-soup-with-lemon-and-turmeric.webp new file mode 100644 index 0000000..7352fe0 Binary files /dev/null and b/recipe-images/lentil-soup-with-lemon-and-turmeric.webp differ diff --git a/recipe-images/moroccan-spiced-lentil-and-chickpea-soup.webp b/recipe-images/moroccan-spiced-lentil-and-chickpea-soup.webp new file mode 100644 index 0000000..917a0bc Binary files /dev/null and b/recipe-images/moroccan-spiced-lentil-and-chickpea-soup.webp differ diff --git a/recipe-images/moroccan-spiced-lentil-chickpea-soup.webp b/recipe-images/moroccan-spiced-lentil-chickpea-soup.webp new file mode 100644 index 0000000..b2a4eba Binary files /dev/null and b/recipe-images/moroccan-spiced-lentil-chickpea-soup.webp differ diff --git a/recipe-images/orange-rolls.webp b/recipe-images/orange-rolls.webp new file mode 100644 index 0000000..b0c8905 Binary files /dev/null and b/recipe-images/orange-rolls.webp differ diff --git a/recipe-images/palak-paneer.webp b/recipe-images/palak-paneer.webp new file mode 100644 index 0000000..c5d20f5 Binary files /dev/null and b/recipe-images/palak-paneer.webp differ diff --git a/recipe-images/passion-fruit-curd-recipe.webp b/recipe-images/passion-fruit-curd-recipe.webp new file mode 100644 index 0000000..78ee7f4 Binary files /dev/null and b/recipe-images/passion-fruit-curd-recipe.webp differ diff --git a/recipe-images/pecan-brown-butter-trout.webp b/recipe-images/pecan-brown-butter-trout.webp new file mode 100644 index 0000000..124170d Binary files /dev/null and b/recipe-images/pecan-brown-butter-trout.webp differ diff --git a/recipe-images/ribollita.webp b/recipe-images/ribollita.webp new file mode 100644 index 0000000..c057e2a Binary files /dev/null and b/recipe-images/ribollita.webp differ diff --git a/recipe-images/roasted-pumpkin-sage.webp b/recipe-images/roasted-pumpkin-sage.webp new file mode 100644 index 0000000..3fc5c12 Binary files /dev/null and b/recipe-images/roasted-pumpkin-sage.webp differ diff --git a/recipe-images/saag-paneer.webp b/recipe-images/saag-paneer.webp new file mode 100644 index 0000000..364be50 Binary files /dev/null and b/recipe-images/saag-paneer.webp differ diff --git a/recipe-images/sauteed-asparagus-with-lemon.webp b/recipe-images/sauteed-asparagus-with-lemon.webp new file mode 100644 index 0000000..b6147b5 Binary files /dev/null and b/recipe-images/sauteed-asparagus-with-lemon.webp differ diff --git a/recipe-images/sheet-pan-miso-chicken-with-radishes-and-lime.webp b/recipe-images/sheet-pan-miso-chicken-with-radishes-and-lime.webp new file mode 100644 index 0000000..8cca93f Binary files /dev/null and b/recipe-images/sheet-pan-miso-chicken-with-radishes-and-lime.webp differ diff --git a/recipe-images/sheet-pan-shrimp-oreganata.webp b/recipe-images/sheet-pan-shrimp-oreganata.webp new file mode 100644 index 0000000..e8406c8 Binary files /dev/null and b/recipe-images/sheet-pan-shrimp-oreganata.webp differ diff --git a/recipe-images/shrimp-feta.webp b/recipe-images/shrimp-feta.webp new file mode 100644 index 0000000..0e9320c Binary files /dev/null and b/recipe-images/shrimp-feta.webp differ diff --git a/recipe-images/slow-cooker-chicken-shawarma.webp b/recipe-images/slow-cooker-chicken-shawarma.webp new file mode 100644 index 0000000..c7d23c4 Binary files /dev/null and b/recipe-images/slow-cooker-chicken-shawarma.webp differ diff --git a/recipe-images/southern-macaroni-and-cheese.webp b/recipe-images/southern-macaroni-and-cheese.webp new file mode 100644 index 0000000..fec4ab1 Binary files /dev/null and b/recipe-images/southern-macaroni-and-cheese.webp differ diff --git a/recipe-images/spaghetti-carbonara.webp b/recipe-images/spaghetti-carbonara.webp new file mode 100644 index 0000000..c0d3a0b Binary files /dev/null and b/recipe-images/spaghetti-carbonara.webp differ diff --git a/recipe-images/spaghetti-squash-w-chickpeas-and-kale.webp b/recipe-images/spaghetti-squash-w-chickpeas-and-kale.webp new file mode 100644 index 0000000..0313827 Binary files /dev/null and b/recipe-images/spaghetti-squash-w-chickpeas-and-kale.webp differ diff --git a/recipe-images/spanakopita.webp b/recipe-images/spanakopita.webp new file mode 100644 index 0000000..f66a3e8 Binary files /dev/null and b/recipe-images/spanakopita.webp differ diff --git a/recipe-images/spicy-shrimp-paella.webp b/recipe-images/spicy-shrimp-paella.webp new file mode 100644 index 0000000..a8695b8 Binary files /dev/null and b/recipe-images/spicy-shrimp-paella.webp differ diff --git a/recipe-images/strawberry-and-wild-rice-tartlets.webp b/recipe-images/strawberry-and-wild-rice-tartlets.webp new file mode 100644 index 0000000..0343fb6 Binary files /dev/null and b/recipe-images/strawberry-and-wild-rice-tartlets.webp differ diff --git a/recipe-images/thai-veggie-pad-see-ew.webp b/recipe-images/thai-veggie-pad-see-ew.webp new file mode 100644 index 0000000..9aa432d Binary files /dev/null and b/recipe-images/thai-veggie-pad-see-ew.webp differ diff --git a/recipe-images/tiramisu.webp b/recipe-images/tiramisu.webp new file mode 100644 index 0000000..1dad650 Binary files /dev/null and b/recipe-images/tiramisu.webp differ diff --git a/recipe-images/warm-up-with-a-quick-lemony-chicken-soup.webp b/recipe-images/warm-up-with-a-quick-lemony-chicken-soup.webp new file mode 100644 index 0000000..f03b06f Binary files /dev/null and b/recipe-images/warm-up-with-a-quick-lemony-chicken-soup.webp differ diff --git a/recipe-images/west-african-peanut-chicken.webp b/recipe-images/west-african-peanut-chicken.webp new file mode 100644 index 0000000..ac8e836 Binary files /dev/null and b/recipe-images/west-african-peanut-chicken.webp differ diff --git a/recipe-images/wheat-berry-salad.webp b/recipe-images/wheat-berry-salad.webp new file mode 100644 index 0000000..33212b6 Binary files /dev/null and b/recipe-images/wheat-berry-salad.webp differ diff --git a/sheet-pan-miso-chicken-with-radishes-and-lime.cook b/sheet-pan-miso-chicken-with-radishes-and-lime.cook index ad0fcc3..08dc2e3 100644 --- a/sheet-pan-miso-chicken-with-radishes-and-lime.cook +++ b/sheet-pan-miso-chicken-with-radishes-and-lime.cook @@ -8,6 +8,7 @@ cuisine: servings: 4 servings totalTime: 45 minutes tags: chicken, chicken thigh, ghee, miso, radish, spring +image: https://roux.roo.lol/recipe-images/sheet-pan-miso-chicken-with-radishes-and-lime.webp --- == Ingredients == diff --git a/sheet-pan-shrimp-oreganata.cook b/sheet-pan-shrimp-oreganata.cook index 30a9428..f9c5e34 100644 --- a/sheet-pan-shrimp-oreganata.cook +++ b/sheet-pan-shrimp-oreganata.cook @@ -10,7 +10,7 @@ totalTime: 20 minutes prepTime: 10 minutes cookTime: 10 minutes tags: bread crumb, italian american, oregano, party, sheet-pan, shrimp, white wine -image: https://static01.nyt.com/images/2025/06/11/multimedia/afg-sheet-pan-shrimp-oreganata-jtmv/afg-sheet-pan-shrimp-oreganata-jtmv-threeByTwoMediumAt2X.jpg?quality=75&auto=webp +image: https://roux.roo.lol/recipe-images/sheet-pan-shrimp-oreganata.webp --- == Ingredients == diff --git a/shrimp-feta.cook b/shrimp-feta.cook index 23cbc0a..ab594ca 100644 --- a/shrimp-feta.cook +++ b/shrimp-feta.cook @@ -1,3 +1,12 @@ +--- +title: Orzo with shrimp, tomato and marinated feta +description: +servings: 1 +category: uncategorized +source: https://thehappyfoodie.co.uk/recipes/ottolenghis-orzo-with-prawns-tomato-and-marinated-feta/ +image: https://roux.roo.lol/recipe-images/shrimp-feta.webp +--- + >> title: Orzo with shrimp, tomato and marinated feta >> source: https://thehappyfoodie.co.uk/recipes/ottolenghis-orzo-with-prawns-tomato-and-marinated-feta/ >> servings: 4