From f78e9ff03bd1ee5863a7a421df4ba58fb0b82364 Mon Sep 17 00:00:00 2001 From: Shubham Prajapati Date: Thu, 10 Oct 2024 18:19:36 +0530 Subject: [PATCH] "Added new functions to leaderboard API, updated database operations, and implemented cron job for auto calculating scoreboards" --- api/v1/leaderboard/cron.job.operation.go | 69 ++++++++++++++ .../leaderboard/leaderboard.db.operations.go | 23 +++++ api/v1/leaderboard/leaderboard.go | 93 ++++++++++++++++++- config/dbconfig/dbconfig.go | 2 +- go.mod | 5 +- go.sum | 2 + main.go | 17 +++- models/leaderboard.go | 27 ++++++ 8 files changed, 234 insertions(+), 4 deletions(-) create mode 100644 api/v1/leaderboard/cron.job.operation.go diff --git a/api/v1/leaderboard/cron.job.operation.go b/api/v1/leaderboard/cron.job.operation.go new file mode 100644 index 0000000..4a4e77c --- /dev/null +++ b/api/v1/leaderboard/cron.job.operation.go @@ -0,0 +1,69 @@ +package leaderboard + +import ( + "log" + + "github.com/NetSepio/gateway/config/dbconfig" + "github.com/google/uuid" + "gorm.io/gorm" +) + +func CronJobLeaderBoardUpdate(column_name string, leaderboard Leaderboard) { + // Database connection setup (replace with your actual connection details) + db := dbconfig.GetDb() + + // // Check if the user_id exists in the LeaderBoard table + // var leaderboard ScoreBoard + + var scoreBoard ScoreBoard + + data, err := GetActivityUnitXpByActivity(column_name) + if err != nil { + log.Printf("failed to get the ScoreBoard by ID: %v", err) + } + // leaderboard.UserId = user_id + err = db.Debug().Where("user_id = ?", leaderboard.UserId).First(&scoreBoard).Error + + if err != nil { + if err == gorm.ErrRecordNotFound { + + CreateScoreBoard(ScoreBoard{ + ID: uuid.New().String(), + Reviews: leaderboard.Reviews, + Domain: leaderboard.Domain, + UserId: leaderboard.UserId, + Nodes: leaderboard.Nodes, + DWifi: leaderboard.DWifi, + Discord: leaderboard.Discord, + Twitter: leaderboard.Twitter, + Telegram: leaderboard.Telegram, + CreatedAt: leaderboard.CreatedAt, + UpdatedAt: leaderboard.UpdatedAt, + }) + log.Println("New record inserted and " + column_name + " count initialized successfully!") + return + } + log.Printf("failed to query the ScoreBoard: %v", err) + } else { + + err = UpdateScoreBoard(leaderboard.ID, ScoreBoard{ + ID: uuid.New().String(), + Reviews: leaderboard.Reviews, + Domain: leaderboard.Domain, + UserId: leaderboard.UserId, + Nodes: leaderboard.Nodes, + DWifi: leaderboard.DWifi, + Discord: leaderboard.Discord, + Twitter: leaderboard.Twitter, + Telegram: leaderboard.Telegram, + CreatedAt: leaderboard.CreatedAt, + UpdatedAt: leaderboard.UpdatedAt, + }, column_name, data.XP) + if err != nil { + log.Printf("failed to update the Reviews count: %v", err) + return + } + log.Println(column_name + " count incremented successfully!") + return + } +} diff --git a/api/v1/leaderboard/leaderboard.db.operations.go b/api/v1/leaderboard/leaderboard.db.operations.go index aaa4f83..c7e7478 100644 --- a/api/v1/leaderboard/leaderboard.db.operations.go +++ b/api/v1/leaderboard/leaderboard.db.operations.go @@ -250,3 +250,26 @@ func DeleteActivityUnitXp(activity string) error { } return nil } + +func GetAllLeaderBoard() ([]Leaderboard, error) { + var leaderBoards []Leaderboard + db := dbconfig.GetDb() + + result := db.Find(&leaderBoards) + if result.Error != nil { + return nil, result.Error + } + return leaderBoards, nil +} + +func GetAllUserIdFromLeaderBoard() ([]string, error) { + var userIds []string + db := dbconfig.GetDb() + // Select only UserId column from the Leaderboard table + if err := db.Model(&Leaderboard{}).Select("user_id").Find(&userIds).Error; err != nil { + return nil, err + } + + return userIds, nil +} + diff --git a/api/v1/leaderboard/leaderboard.go b/api/v1/leaderboard/leaderboard.go index 3be326d..985509e 100644 --- a/api/v1/leaderboard/leaderboard.go +++ b/api/v1/leaderboard/leaderboard.go @@ -1,12 +1,17 @@ package leaderboard import ( + "fmt" "net/http" + "strings" + "time" "github.com/NetSepio/gateway/config/dbconfig" "github.com/NetSepio/gateway/models" "github.com/NetSepio/gateway/util/pkg/logwrapper" "github.com/TheLazarusNetwork/go-helpers/httpo" + "github.com/sirupsen/logrus" + "gorm.io/gorm" "github.com/gin-gonic/gin" ) @@ -44,6 +49,8 @@ func getLeaderboard(c *gin.Context) { func getScoreBoard(c *gin.Context) { db := dbconfig.GetDb() + var response []models.UserScoreBoard + var scoreBoard []models.ScoreBoard if err := db.Order("reviews desc").Find(&scoreBoard).Error; err != nil { @@ -57,5 +64,89 @@ func getScoreBoard(c *gin.Context) { return } - httpo.NewSuccessResponseP(200, "ScoreBoard fetched successfully", scoreBoard).SendD(c) + for _, data := range scoreBoard { + + total := data.Reviews + data.Domain + data.Nodes + data.DWifi + data.Discord + data.Twitter + data.Telegram + UserScoreBoard := models.UserScoreBoard{ + ID: data.ID, + Reviews: data.Reviews, + Domain: data.Domain, + UserId: data.UserId, + Nodes: data.Nodes, + DWifi: data.DWifi, + Discord: data.Discord, + Twitter: data.Twitter, + Telegram: data.Telegram, + CreatedAt: data.CreatedAt, + UpdatedAt: data.UpdatedAt, + TotalScore: total, + } + + var user models.User + err := db.Model(&models.User{}).Select("user_id, name, profile_picture_url,country, wallet_address, discord, twitter, email_id").Where("user_id = ?", data.UserId).First(&user).Error + if err != nil { + if err == gorm.ErrRecordNotFound { + response = append(response, UserScoreBoard) + continue + } else { + logrus.Error(err) + httpo.NewErrorResponse(http.StatusInternalServerError, "Unexpected error occured").SendD(c) + return + } + + } + + payload := models.GetProfilePayload{UserId: user.UserId, Name: user.Name, WalletAddress: user.WalletAddress, ProfilePictureUrl: user.ProfilePictureUrl, Country: user.Country, Discord: user.Discord, Twitter: user.Twitter, Email: user.EmailId} + + UserScoreBoard.UserDetails = payload + + response = append(response, UserScoreBoard) + } + fmt.Printf("%+v\n", response) + + httpo.NewSuccessResponseP(200, "ScoreBoard fetched successfully", response).SendD(c) +} +func AutoCalculateScoreBoard() { + + // fmt.Println("STARTING AUTO CALCULATE SCOREBOARD AT ", time.Now()) + border := strings.Repeat("=", 50) // Creates a border line + + func() { + fmt.Println(border) + fmt.Println("🚀 STARTING AUTO CALCULATE SCOREBOARD") + fmt.Println("📅 Date & Time:", time.Now().Format("02-Jan-2006 15:04:05 MST")) + fmt.Println("🔄 Status: In Progress") + fmt.Println(border) + }() + + // var leaderboard ScoreBoard + + leaderboards, err := GetAllLeaderBoard() + if err != nil { + logrus.Error(err) + return + } + + fmt.Println("leaderboards len : ", len(leaderboards)) + + for _, leaderboard := range leaderboards { + CronJobLeaderBoardUpdate("reviews", leaderboard) + CronJobLeaderBoardUpdate("domain", leaderboard) + CronJobLeaderBoardUpdate("nodes", leaderboard) + CronJobLeaderBoardUpdate("d_wifi", leaderboard) + CronJobLeaderBoardUpdate("discord", leaderboard) + CronJobLeaderBoardUpdate("twitter", leaderboard) + CronJobLeaderBoardUpdate("telegram", leaderboard) + } + + func() { + // After the task completes, print the "Completed" status + // border := strings.Repeat("=", 50) // Creates a border line + fmt.Println(border) + fmt.Println("✅ SCOREBOARD CALCULATION COMPLETED") + fmt.Println("📅 Date & Time:", time.Now().Format("02-Jan-2006 15:04:05 MST")) + fmt.Println("✔️ Status: Completed") + fmt.Println(border) + }() + } diff --git a/config/dbconfig/dbconfig.go b/config/dbconfig/dbconfig.go index 6e26661..c3fdb92 100644 --- a/config/dbconfig/dbconfig.go +++ b/config/dbconfig/dbconfig.go @@ -50,7 +50,7 @@ func GetDb() *gorm.DB { return db } -func Init() error { +func Migrate() error { db := GetDb() // db.Exec(`ALTER TABLE leader_boards DROP COLUMN IF EXISTS users;`) diff --git a/go.mod b/go.mod index bddfe19..148a943 100644 --- a/go.mod +++ b/go.mod @@ -24,7 +24,10 @@ require ( gorm.io/gorm v1.23.7 ) -require github.com/sashabaranov/go-openai v1.24.1 +require ( + github.com/robfig/cron v1.2.0 + github.com/sashabaranov/go-openai v1.24.1 +) require ( cloud.google.com/go/auth v0.5.1 // indirect diff --git a/go.sum b/go.sum index 5823b49..c94eb90 100644 --- a/go.sum +++ b/go.sum @@ -510,6 +510,8 @@ github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40T github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52/go.mod h1:RDpi1RftBQPUCDRw6SmxeaREsAaRKnOclghuzp/WRzc= github.com/rjeczalik/notify v0.9.1 h1:CLCKso/QK1snAlnhNR/CNvNiFU2saUtjV0bx3EwNeCE= github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho= +github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ= +github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= diff --git a/main.go b/main.go index 87561f7..dfd7e12 100644 --- a/main.go +++ b/main.go @@ -7,6 +7,7 @@ import ( "os" "strings" + leaderboard "github.com/NetSepio/gateway/api/v1/leaderboard" "github.com/NetSepio/gateway/app" "github.com/NetSepio/gateway/config/dbconfig" "github.com/NetSepio/gateway/config/envconfig" @@ -14,6 +15,7 @@ import ( "github.com/NetSepio/gateway/models/claims" "github.com/NetSepio/gateway/util/pkg/auth" "github.com/NetSepio/gateway/util/pkg/logwrapper" + "github.com/robfig/cron" ) func main() { @@ -43,7 +45,20 @@ func main() { } fmt.Printf("========TEST TOKEN========\n%s\n========TEST TOKEN========\n", token) } - dbconfig.Init() + dbconfig.Migrate() + go func() { + c := cron.New() + // Schedule the function to run every day at midnight (or adjust the schedule as needed) + c.AddFunc("0 0 0 * * *", func() { + leaderboard.AutoCalculateScoreBoard() + }) + + // Start the cron scheduler in the background + c.Start() + + // Keep the application running + select {} + }() logwrapper.Log.Info("Starting app") addr := fmt.Sprintf(":%d", envconfig.EnvVars.APP_PORT) err := app.GinApp.Run(addr) diff --git a/models/leaderboard.go b/models/leaderboard.go index 344117c..d601735 100644 --- a/models/leaderboard.go +++ b/models/leaderboard.go @@ -37,3 +37,30 @@ type ScoreBoard struct { CreatedAt time.Time `gorm:"autoCreateTime"` UpdatedAt time.Time `gorm:"autoUpdateTime"` } + +type UserScoreBoard struct { + ID string `gorm:"type:uuid;default:uuid_generate_v4();primary_key"` + Reviews int + Domain int + UserId string `gorm:"type:uuid;not null"` + Nodes int + DWifi int + Discord int + Twitter int + Telegram int + CreatedAt time.Time `gorm:"autoCreateTime"` + UpdatedAt time.Time `gorm:"autoUpdateTime"` + TotalScore int `json:"totalScore"` + UserDetails GetProfilePayload `json:"getProfilePayload"` +} + +type GetProfilePayload struct { + UserId string `json:"userId,omitempty"` + Name string `json:"name,omitempty"` + WalletAddress *string `json:"walletAddress,omitempty"` + ProfilePictureUrl string `json:"profilePictureUrl,omitempty"` + Country string `json:"country,omitempty"` + Discord string `json:"discord,omitempty"` + Twitter string `json:"twitter,omitempty"` + Email *string `json:"email,omitempty"` +}