google.go 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. package handlers
  2. import (
  3. "net/http"
  4. "git.linuxforward.com/byom/byom-trends/common"
  5. "git.linuxforward.com/byom/byom-trends/logger"
  6. "git.linuxforward.com/byom/byom-trends/services/google"
  7. "git.linuxforward.com/byom/byom-trends/store"
  8. "github.com/gin-gonic/gin"
  9. "github.com/google/uuid"
  10. "github.com/sirupsen/logrus"
  11. )
  12. type GoogleHandler struct {
  13. store *store.DataStore
  14. googleSvc *google.Client
  15. logger *logrus.Entry
  16. }
  17. type GoogleTrendsRequest struct {
  18. Keywords []string `json:"keywords" binding:"required,min=1,max=5"`
  19. TimeRange string `json:"time_range" binding:"required,oneof=daily weekly monthly yearly"`
  20. Region string `json:"region" binding:"omitempty"`
  21. }
  22. func NewGoogleHandler(
  23. store *store.DataStore,
  24. googleSvc *google.Client,
  25. ) *GoogleHandler {
  26. return &GoogleHandler{
  27. store: store,
  28. googleSvc: googleSvc,
  29. logger: logger.NewLogger("google-handler"),
  30. }
  31. }
  32. // AnalyzeGoogleTrends analyzes Google Trends data for given keywords
  33. func (h *GoogleHandler) AnalyzeGoogleTrends(c *gin.Context) {
  34. var req GoogleTrendsRequest
  35. if err := c.ShouldBindJSON(&req); err != nil {
  36. c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request"})
  37. return
  38. }
  39. // Get trends data for each keyword
  40. results, err := h.googleSvc.CompareKeywords(req.Keywords, req.TimeRange)
  41. if err != nil {
  42. h.logger.WithError(err).Error("failed to get Google Trends data")
  43. c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to get trends data"})
  44. return
  45. }
  46. // Get related topics for each keyword
  47. relatedTopics := make(map[string][]google.RelatedTopic)
  48. for _, keyword := range req.Keywords {
  49. topics, err := h.googleSvc.GetRelatedTopics(keyword)
  50. if err != nil {
  51. h.logger.WithError(err).Warnf("failed to get related topics for %s", keyword)
  52. continue
  53. }
  54. relatedTopics[keyword] = topics
  55. }
  56. // Get regional interest if region is specified
  57. var regionalInterest map[string]int
  58. if req.Region != "" {
  59. // Combine all keywords for regional analysis
  60. combinedKeywords := req.Keywords[0]
  61. for _, keyword := range req.Keywords[1:] {
  62. combinedKeywords += " " + keyword
  63. }
  64. regionalInterest, err = h.googleSvc.GetRegionalInterest(combinedKeywords, req.Region)
  65. if err != nil {
  66. h.logger.WithError(err).Warn("failed to get regional interest")
  67. }
  68. }
  69. // Create trend analysis record
  70. trend := &common.GoogleTrend{
  71. ID: uuid.New(),
  72. Keywords: req.Keywords,
  73. TrendData: nil, // Will be set after marshaling
  74. }
  75. // Combine all data
  76. analysisData := map[string]interface{}{
  77. "trends": results,
  78. "related_topics": relatedTopics,
  79. "regional_interest": regionalInterest,
  80. "time_range": req.TimeRange,
  81. "region": req.Region,
  82. }
  83. // Store the analysis
  84. if err := h.store.CreateGoogleTrend(c, trend); err != nil {
  85. h.logger.WithError(err).Error("failed to store Google Trends analysis")
  86. c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to store analysis"})
  87. return
  88. }
  89. c.JSON(http.StatusOK, analysisData)
  90. }
  91. // GetTrendAnalysis retrieves a specific Google Trends analysis
  92. func (h *GoogleHandler) GetTrendAnalysis(c *gin.Context) {
  93. id, err := uuid.Parse(c.Param("id"))
  94. if err != nil {
  95. c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid analysis ID"})
  96. return
  97. }
  98. trend, err := h.store.GetGoogleTrend(c, id)
  99. if err != nil {
  100. h.logger.WithError(err).Error("failed to get Google Trends analysis")
  101. c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to get analysis"})
  102. return
  103. }
  104. if trend == nil {
  105. c.JSON(http.StatusNotFound, gin.H{"error": "Analysis not found"})
  106. return
  107. }
  108. c.JSON(http.StatusOK, trend)
  109. }
  110. // GetRelatedTopics gets related topics for a keyword
  111. func (h *GoogleHandler) GetRelatedTopics(c *gin.Context) {
  112. keyword := c.Query("keyword")
  113. if keyword == "" {
  114. c.JSON(http.StatusBadRequest, gin.H{"error": "Keyword is required"})
  115. return
  116. }
  117. topics, err := h.googleSvc.GetRelatedTopics(keyword)
  118. if err != nil {
  119. h.logger.WithError(err).Error("failed to get related topics")
  120. c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to get related topics"})
  121. return
  122. }
  123. c.JSON(http.StatusOK, topics)
  124. }
  125. // GetRegionalInterest gets regional interest data for keywords
  126. func (h *GoogleHandler) GetRegionalInterest(c *gin.Context) {
  127. keyword := c.Query("keyword")
  128. region := c.Query("region")
  129. if keyword == "" {
  130. c.JSON(http.StatusBadRequest, gin.H{"error": "Keyword is required"})
  131. return
  132. }
  133. interest, err := h.googleSvc.GetRegionalInterest(keyword, region)
  134. if err != nil {
  135. h.logger.WithError(err).Error("failed to get regional interest")
  136. c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to get regional interest"})
  137. return
  138. }
  139. c.JSON(http.StatusOK, interest)
  140. }