data.go 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. package howtocook
  2. import (
  3. "context"
  4. "fmt"
  5. "net/http"
  6. "time"
  7. "github.com/bytedance/sonic"
  8. )
  9. // fetchRecipes fetches recipes from remote URL
  10. func (s *Server) fetchRecipes(ctx context.Context) ([]Recipe, error) {
  11. client := &http.Client{
  12. Timeout: 30 * time.Second,
  13. }
  14. req, err := http.NewRequestWithContext(ctx, http.MethodGet, RecipesURL, nil)
  15. if err != nil {
  16. return nil, fmt.Errorf("failed to create request: %w", err)
  17. }
  18. resp, err := client.Do(req)
  19. if err != nil {
  20. return nil, fmt.Errorf("failed to fetch recipes: %w", err)
  21. }
  22. defer resp.Body.Close()
  23. if resp.StatusCode != http.StatusOK {
  24. return nil, fmt.Errorf("HTTP error: %d", resp.StatusCode)
  25. }
  26. var recipes []Recipe
  27. if err := sonic.ConfigDefault.NewDecoder(resp.Body).Decode(&recipes); err != nil {
  28. return nil, fmt.Errorf("failed to parse recipes: %w", err)
  29. }
  30. return recipes, nil
  31. }
  32. // getAllCategories returns all unique categories from recipes
  33. func (s *Server) getAllCategories() []string {
  34. categorySet := make(map[string]bool)
  35. for _, recipe := range s.recipes {
  36. if recipe.Category != "" {
  37. categorySet[recipe.Category] = true
  38. }
  39. }
  40. categories := make([]string, len(categorySet))
  41. for category := range categorySet {
  42. categories = append(categories, category)
  43. }
  44. return categories
  45. }