From 38440f457344f503723cbb27c4fb293cd56b80f8 Mon Sep 17 00:00:00 2001 From: Yaroslav Podorvanov <63663261+YaroslavPodorvanov@users.noreply.github.com> Date: Thu, 28 Dec 2023 19:38:26 +0200 Subject: [PATCH] pixel (#26) --- cmd/v3/main.go | 1 + internal/controllers/stats_controller.go | 49 ++++++++++++++++++++++++ internal/services/stats_service.go | 13 +++++++ 3 files changed, 63 insertions(+) diff --git a/cmd/v3/main.go b/cmd/v3/main.go index a96f1ca..ab72c6c 100644 --- a/cmd/v3/main.go +++ b/cmd/v3/main.go @@ -52,6 +52,7 @@ func main() { r.GET("/api/v1/github/profiles/:social_provider_user_id/views/count.json", statsController.GitHubDayWeekMonthTotalCount) r.GET("/api/v1/github/profiles/:social_provider_user_id/views/stats.json", statsController.GitHubStats) r.GET("/api/v1/github/profiles/:social_provider_user_id/views/day-week-month-total-count.svg", statsController.GitHubDayWeekMonthTotalCountBadge) + r.GET("/api/v1/github/profiles/:social_provider_user_id/views/pixel.svg", statsController.Pixel) r.GET("/api/v1/github/profiles/:social_provider_user_id/views/total-count.svg", statsController.TotalCountBadge) r.GET("/api/v1/github/profiles/:social_provider_user_id/referrals/stats.json", statsController.ReferralsStats) r.GET("/api/v1/users/stats.json", statsController.UsersCreatedAtStatsByDay) diff --git a/internal/controllers/stats_controller.go b/internal/controllers/stats_controller.go index 14869c9..0fee084 100644 --- a/internal/controllers/stats_controller.go +++ b/internal/controllers/stats_controller.go @@ -88,6 +88,25 @@ func (c *StatsController) GitHubDayWeekMonthTotalCountBadge(ctx *gin.Context) { ctx.Data(http.StatusOK, "image/svg+xml", []byte(tmv2.Badge(statsCount))) } +func (c *StatsController) Pixel(ctx *gin.Context) { + const ( + // language=SVG + pixel = ` + +` + ) + + done := c.increment(ctx, dbs.SocialProviderGithub) + if done { + return + } + + ctx.Header("Cache-Control", "no-cache, no-store, must-revalidate") + ctx.Header("Pragma", "no-cache") + ctx.Header("Expires", "0") + ctx.Data(http.StatusOK, "image/svg+xml", []byte(pixel)) +} + func (c *StatsController) GitHubStats(ctx *gin.Context) { socialProviderUserID, done := c.parseSocialProviderUserID(ctx) if done { @@ -188,6 +207,36 @@ func (c *StatsController) statsCount(ctx *gin.Context, provider dbs.SocialProvid return statsCount, false } +func (c *StatsController) increment(ctx *gin.Context, provider dbs.SocialProvider) (done bool) { + socialProviderUserID, done := c.parseSocialProviderUserID(ctx) + if done { + return + } + + userID, done := c.toUserID(ctx, provider, socialProviderUserID) + if done { + return + } + + increment := strings.HasPrefix(ctx.GetHeader("User-Agent"), "github-camo") + if !increment { + return + } + + err := c.statsService.Increment(ctx, userID) + if err != nil { + log.Printf("Database error (stats) %s\n", err) + + ctx.JSON(http.StatusInternalServerError, &ErrorResponse{ + ErrorMessage: "Database error", + }) + + return true + } + + return false +} + func (c *StatsController) parseSocialProviderUserID(ctx *gin.Context) (string, bool) { var uri ProfileCountURI diff --git a/internal/services/stats_service.go b/internal/services/stats_service.go index a86ce2e..52cb1d0 100644 --- a/internal/services/stats_service.go +++ b/internal/services/stats_service.go @@ -58,6 +58,19 @@ func (s *StatsService) StatsCount(ctx context.Context, userID int64, increment b }, nil } +func (s *StatsService) Increment(ctx context.Context, userID int64) (err error) { + now := time.Now().UTC().Truncate(time.Hour) + + go func() { + err := s.increment(context.Background(), userID, now) + if err != nil { + log.Printf("Database err %s\n", err) + } + }() + + return nil +} + func (s *StatsService) UserDayWeekMonthViewsStatsMap(ctx context.Context, userIDs []int64, now time.Time) (map[int64]models.DayWeekMonthViewsStats, error) { rows, err := s.repository.Queries().ProfileHourlyViewsStats(ctx, dbs.ProfileHourlyViewsStatsParams{ Day: now.AddDate(0, 0, -1),