Skip to content

Commit

Permalink
add support for recipe subtype (#13)
Browse files Browse the repository at this point in the history
  • Loading branch information
jdpedrie authored Jul 23, 2024
1 parent 06e1beb commit 785d74e
Show file tree
Hide file tree
Showing 3 changed files with 226 additions and 21 deletions.
24 changes: 24 additions & 0 deletions brave_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (

"dev.freespoke.com/brave-search"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestWeb(t *testing.T) {
Expand Down Expand Up @@ -125,6 +126,29 @@ func TestDuration(t *testing.T) {
}
}

func TestRecipe(t *testing.T) {
svr := getTestServer("testdata/web_recipe.json", 200)

client, err := brave.New("fake", brave.WithHTTPClient(svr.Client()), brave.WithBaseURL(svr.URL))
if err != nil {
t.Fatal(err)
}

res, err := client.WebSearch(context.Background(), "speaker of the house")
require.Nil(t, err)
require.NotNil(t, res)

results := res.Web.Results
require.Len(t, results, 1)
r := results[0]
require.NotNil(t, r.Recipe)
require.Equal(t, "recipe", r.Subtype)

assert.Equal(t, "Chicken Alfredo", r.Recipe.Title)
assert.Equal(t, "desc", r.Recipe.Description)
assert.Equal(t, 40*time.Minute, *r.Recipe.Time.Duration())
}

func getTestServer(file string, status int) *httptest.Server {
body, err := os.ReadFile(file)
if err != nil {
Expand Down
153 changes: 153 additions & 0 deletions testdata/web_recipe.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
{
"web": {
"type": "search",
"results": [
{
"title": "Chicken Alfredo - Budget Bytes",
"url": "https://www.budgetbytes.com/chicken-alfredo/",
"is_source_local": false,
"is_source_both": false,
"description": "This <strong>Chicken</strong> <strong>Alfredo</strong> features pasta drenched in an ultra-rich and creamy sauce and topped with juicy strips of seared <strong>chicken</strong>.",
"page_age": "2023-03-01T13:33:51",
"profile": {
"name": "Budget Bytes",
"url": "https://www.budgetbytes.com/chicken-alfredo/",
"long_name": "budgetbytes.com",
"img": "https://imgs.search.brave.com/pTJbHVZz_ZBD3RWwYBcuyh5zjzyCR6QLy5afccTBe4U/rs:fit:32:32:1:0/g:ce/aHR0cDovL2Zhdmlj/b25zLnNlYXJjaC5i/cmF2ZS5jb20vaWNv/bnMvZTIwZWZjYTcz/MWI2MTdiNzhiZDAy/ZGJkNzcwMjQ4NTVk/YjIxMjYyMTBlYmYy/ODRhYzJjYWM0NjMz/YjI1ZWIwOC93d3cu/YnVkZ2V0Ynl0ZXMu/Y29tLw"
},
"language": "en",
"family_friendly": true,
"type": "search_result",
"subtype": "recipe",
"meta_url": {
"scheme": "https",
"netloc": "budgetbytes.com",
"hostname": "www.budgetbytes.com",
"favicon": "https://imgs.search.brave.com/pTJbHVZz_ZBD3RWwYBcuyh5zjzyCR6QLy5afccTBe4U/rs:fit:32:32:1:0/g:ce/aHR0cDovL2Zhdmlj/b25zLnNlYXJjaC5i/cmF2ZS5jb20vaWNv/bnMvZTIwZWZjYTcz/MWI2MTdiNzhiZDAy/ZGJkNzcwMjQ4NTVk/YjIxMjYyMTBlYmYy/ODRhYzJjYWM0NjMz/YjI1ZWIwOC93d3cu/YnVkZ2V0Ynl0ZXMu/Y29tLw",
"path": " › budget bytes › recipes › meat recipes › chicken recipes › chicken alfredo"
},
"thumbnail": {
"src": "https://imgs.search.brave.com/cmhiGR62ts8HtdJ-2BiFON9OdFaFLFQiE5D0ybUe9ck/rs:fit:200:200:1:0/g:ce/aHR0cHM6Ly93d3cu/YnVkZ2V0Ynl0ZXMu/Y29tL3dwLWNvbnRl/bnQvdXBsb2Fkcy8y/MDIyLzA3L0NoaWNr/ZW4tQWxmcmVkby1i/b3dsLmpwZw",
"original": "https://www.budgetbytes.com/wp-content/uploads/2022/07/Chicken-Alfredo-bowl.jpg",
"logo": false
},
"age": "March 1, 2023",
"video": {
"duration": "00:52",
"thumbnail": {
"src": "https://imgs.search.brave.com/P1KRHUV8JVXCRAc1KSF529sEXyvqQPJy4L7pk9aZ1Lc/rs:fit:200:200:1:0/g:ce/aHR0cHM6Ly9tZWRp/YXZpbmUtcmVzLmNs/b3VkaW5hcnkuY29t/L2ltYWdlL3VwbG9h/ZC9zLS1VMFMzdHRT/Zi0tL2NfbGltaXQs/Zl9hdXRvLGZsX2xv/c3N5LGhfMTA4MCxx/X2F1dG8sd18xOTIw/L3YxNjY1MTUyMTYz/L2MxYWlncGdndnZv/dHlkcXhhY2duLmpw/Zw",
"original": "https://mediavine-res.cloudinary.com/image/upload/s--U0S3ttSf--/c_limit,f_auto,fl_lossy,h_1080,q_auto,w_1920/v1665152163/c1aigpggvvotydqxacgn.jpg"
}
},
"article": {
"author": [
{
"type": "person",
"name": "Beth - Budget Bytes"
}
],
"date": "Jul 25, 2022",
"publisher": {
"type": "organization",
"name": "Budget Bytes",
"url": "https://www.budgetbytes.com/",
"thumbnail": {
"src": "https://imgs.search.brave.com/8Shgd_Y8noQ0XbCBZRR_A9CDr60fX2JaqoNVceYzQ4o/rs:fit:200:200:1:0/g:ce/aHR0cHM6Ly93d3cu/YnVkZ2V0Ynl0ZXMu/Y29tL3dwLWNvbnRl/bnQvdXBsb2Fkcy8y/MDIwLzExL2J1ZGdl/dGJ5dGVzX3NxdWFy/ZV9pY29uX3RyYW5z/cGFyZW50LnBuZw",
"original": "https://www.budgetbytes.com/wp-content/uploads/2020/11/budgetbytes_square_icon_transparent.png"
}
}
},
"recipe": {
"title": "Chicken Alfredo",
"description": "desc",
"thumbnail": {
"src": "https://imgs.search.brave.com/DYRTJR9GHBYwCOUuT--74UX5K_g2j1XkMyRsgTQ4r-Q/rs:fit:200:200:1:0/g:ce/aHR0cHM6Ly93d3cu/YnVkZ2V0Ynl0ZXMu/Y29tL3dwLWNvbnRl/bnQvdXBsb2Fkcy8y/MDIyLzA3L0NoaWNr/ZW4tQWxmcmVkby1h/Ym92ZS5qcGc",
"original": "https://www.budgetbytes.com/wp-content/uploads/2022/07/Chicken-Alfredo-above.jpg"
},
"url": "https://www.budgetbytes.com/chicken-alfredo/",
"domain": "budgetbytes.com",
"favicon": "https://imgs.search.brave.com/pTJbHVZz_ZBD3RWwYBcuyh5zjzyCR6QLy5afccTBe4U/rs:fit:32:32:1:0/g:ce/aHR0cDovL2Zhdmlj/b25zLnNlYXJjaC5i/cmF2ZS5jb20vaWNv/bnMvZTIwZWZjYTcz/MWI2MTdiNzhiZDAy/ZGJkNzcwMjQ4NTVk/YjIxMjYyMTBlYmYy/ODRhYzJjYWM0NjMz/YjI1ZWIwOC93d3cu/YnVkZ2V0Ynl0ZXMu/Y29tLw",
"time": "40:00",
"prep_time": "05:00",
"cook_time": "35:00",
"ingredients": "2 boneless, skinless chicken breasts (about 1.3 lb. total) ($6.49), 2 tsp Italian seasoning ($0.20), 1 Tbsp cooking oil ($0.04), 2 Tbsp butter ($0.22), 4 cloves garlic, minced ($0.32), 1 cup heavy cream ($1.25), 3/4 cup grated Parmesan ($1.08), 1/4 tsp salt ($0.02), 1/4 tsp pepper ($0.02), 1 Tbsp chopped parsley (optional garnish) ($0.10), 8 oz. fettuccine ($0.88)",
"instructions": [
{
"text": "Season both sides of the chicken breast with Italian seasoning and a pinch of salt.",
"name": "Season both sides of the chicken breast with Italian seasoning and a pinch of salt.",
"url": "https://www.budgetbytes.com/chicken-alfredo/#wprm-recipe-67806-step-0-0",
"image": []
},
{
"text": "Heat a large skillet over medium. Once hot, add the cooking oil and swirl to coat the surface. Add the chicken to the skillet and cook for about 7-8 minutes on each side, or until browned on the outside and cooked through.",
"name": "Heat a large skillet over medium. Once hot, add the cooking oil and swirl to coat the surface. Add the chicken to the skillet and cook for about 7-8 minutes on each side, or until browned on the outside and cooked through.",
"url": "https://www.budgetbytes.com/chicken-alfredo/#wprm-recipe-67806-step-0-1",
"image": []
},
{
"text": "Remove the chicken to a clean plate and turn the heat under the skillet down to medium-low.",
"name": "Remove the chicken to a clean plate and turn the heat under the skillet down to medium-low.",
"url": "https://www.budgetbytes.com/chicken-alfredo/#wprm-recipe-67806-step-0-2",
"image": []
},
{
"text": "Add the butter and minced garlic to the skillet. Stir and cook the garlic in the melted butter for about two minutes, dissolving the browned bits from the bottom of the skillet as you stir.",
"name": "Add the butter and minced garlic to the skillet. Stir and cook the garlic in the melted butter for about two minutes, dissolving the browned bits from the bottom of the skillet as you stir.",
"url": "https://www.budgetbytes.com/chicken-alfredo/#wprm-recipe-67806-step-0-3",
"image": []
},
{
"text": "Add the heavy cream and whisk to combine, dissolving any remaining browned bits. Allow the cream to come up to a simmer.",
"name": "Add the heavy cream and whisk to combine, dissolving any remaining browned bits. Allow the cream to come up to a simmer.",
"url": "https://www.budgetbytes.com/chicken-alfredo/#wprm-recipe-67806-step-0-4",
"image": []
},
{
"text": "While waiting for the cream to simmer, bring a pot of water to a boil for the fettuccine. Once boiling, add the pasta and continue to boil until tender (about 7 minutes). Reserve about ½ cup of the starchy cooking water just before draining the pasta.",
"name": "While waiting for the cream to simmer, bring a pot of water to a boil for the fettuccine. Once boiling, add the pasta and continue to boil until tender (about 7 minutes). Reserve about ½ cup of the starchy cooking water just before draining the pasta.",
"url": "https://www.budgetbytes.com/chicken-alfredo/#wprm-recipe-67806-step-0-5",
"image": []
},
{
"text": "Once the cream is simmering, add the grated Parmesan to the skillet. Continue to whisk and stir until the Parmesan has melted into the sauce and the sauce has begun to simmer. Simmer the sauce for a few minutes, or until it becomes slightly thicker. Add salt and pepper to the sauce to taste.",
"name": "Once the cream is simmering, add the grated Parmesan to the skillet. Continue to whisk and stir until the Parmesan has melted into the sauce and the sauce has begun to simmer. Simmer the sauce for a few minutes, or until it becomes slightly thicker. Add salt and pepper to the sauce to taste.",
"url": "https://www.budgetbytes.com/chicken-alfredo/#wprm-recipe-67806-step-0-6",
"image": []
},
{
"text": "Add the drained pasta to the skillet with the creamy sauce and toss to combine. If the sauce becomes too thick, add a couple of tablespoons of the reserved pasta water and toss to combine with the sauce.",
"name": "Add the drained pasta to the skillet with the creamy sauce and toss to combine. If the sauce becomes too thick, add a couple of tablespoons of the reserved pasta water and toss to combine with the sauce.",
"url": "https://www.budgetbytes.com/chicken-alfredo/#wprm-recipe-67806-step-0-7",
"image": []
},
{
"text": "Slice the cooked chicken breasts and serve it atop the creamy pasta. Garnish with chopped parsley, if desired.",
"name": "Slice the cooked chicken breasts and serve it atop the creamy pasta. Garnish with chopped parsley, if desired.",
"url": "https://www.budgetbytes.com/chicken-alfredo/#wprm-recipe-67806-step-0-8",
"image": []
}
],
"servings": 4,
"calories": 756,
"publisher": "Beth - Budget Bytes",
"rating": {
"ratingValue": 4.4,
"bestRating": 5,
"reviewCount": 20,
"is_tripadvisor": false
},
"recipeCategory": "Dinner",
"recipeCuisine": "American",
"video": {
"duration": "00:52",
"thumbnail": {
"src": "https://imgs.search.brave.com/P1KRHUV8JVXCRAc1KSF529sEXyvqQPJy4L7pk9aZ1Lc/rs:fit:200:200:1:0/g:ce/aHR0cHM6Ly9tZWRp/YXZpbmUtcmVzLmNs/b3VkaW5hcnkuY29t/L2ltYWdlL3VwbG9h/ZC9zLS1VMFMzdHRT/Zi0tL2NfbGltaXQs/Zl9hdXRvLGZsX2xv/c3N5LGhfMTA4MCxx/X2F1dG8sd18xOTIw/L3YxNjY1MTUyMTYz/L2MxYWlncGdndnZv/dHlkcXhhY2duLmpw/Zw",
"original": "https://mediavine-res.cloudinary.com/image/upload/s--U0S3ttSf--/c_limit,f_auto,fl_lossy,h_1080,q_auto,w_1920/v1665152163/c1aigpggvvotydqxacgn.jpg"
}
}
}
}
],
"family_friendly": true
}
}
70 changes: 49 additions & 21 deletions types.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,32 +153,33 @@ type Thumbnail struct {

type SearchResult struct {
Result
Type string `json:"type"`
Subtype string `json:"subtype"`
DeepResults *DeepResult `json:"deep_results"`
Schemas any `json:"schemas"`
MetaURL MetaURL `json:"meta_url"`
Thumbnail *Thumbnail `json:"thumbnail"`
Age *Timestamp `json:"age"`
Language string `json:"language"`
Restaurant *LocationResult `json:"restaurant"`
Locations *Locations `json:"locations"`
Video *VideoData `json:"video"`
Movie *MovieData `json:"movie"`
FAQ *FAQ `json:"faq"`
QA *QAPage `json:"qa"`
Book *Book `json:"book"`
Rating *Rating `json:"rating"`
Article *Article `json:"article"`
// Product any `json:"product"`
ProductCluster []Product `json:"product_cluster"`
ClusterType string `json:"cluster_type"`
Type string `json:"type"`
DeepResults *DeepResult `json:"deep_results"`
Schemas any `json:"schemas"`
MetaURL MetaURL `json:"meta_url"`
Thumbnail *Thumbnail `json:"thumbnail"`
Age *Timestamp `json:"age"`
Language string `json:"language"`
ContentType string `json:"content_type"`

Subtype string `json:"subtype"`
Article *Article `json:"article"`
Book *Book `json:"book"`
Cluster []Result `json:"cluster"`
ClusterType string `json:"cluster_type"`
CreativeWork *CreativeWork `json:"creative_work"`
FAQ *FAQ `json:"faq"`
Locations *Locations `json:"locations"`
Movie *MovieData `json:"movie"`
MusicRecording *MusicRecording `json:"music_recording"`
ProductCluster []Product `json:"product_cluster"`
QA *QAPage `json:"qa"`
Rating *Rating `json:"rating"`
Recipe *Recipe `json:"recipe"`
Restaurant *LocationResult `json:"restaurant"`
Review *Review `json:"review"`
Software *Software `json:"software"`
ContentType string `json:"content_type"`
Video *VideoData `json:"video"`
}

type ImageResult struct {
Expand Down Expand Up @@ -309,6 +310,33 @@ type Rating struct {
IsTripadvisor bool `json:"is_tripadvisor"`
}

type Recipe struct {
Title string `json:"title"`
Description string `json:"description"`
Thumbnail *Thumbnail `json:"thumbnail"`
URL string `json:"url"`
Domain string `json:"domain"`
Favicon string `json:"favicon"`
Time *Duration `json:"time"`
PrepTime *Duration `json:"prep_time"`
CookTime *Duration `json:"cook_time"`
Ingredients string `json:"ingredients"`
Instructions []HowTo `json:"instructions"`
Servings int `json:"servings"`
Calories int `json:"calories"`
Rating *Rating `json:"rating"`
RecipeCategory string `json:"recipeCategory"`
RecipeCuisine string `json:"recipeCuisine"`
Video *VideoData `json:"video"`
}

type HowTo struct {
Text string `json:"text"`
Name string `json:"name"`
URL string `json:"url"`
Image []string `json:"image"`
}

type DataProvider struct {
Type string `json:"type"`
Name string `json:"name"`
Expand Down

0 comments on commit 785d74e

Please sign in to comment.