Skip to content

Commit 09d7172

Browse files
authored
Merge pull request #59 from CodeChefVIT/feat/cron
Feat/cron
2 parents 2c8ee6b + 0119554 commit 09d7172

File tree

11 files changed

+185
-35
lines changed

11 files changed

+185
-35
lines changed

.env.sample

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,5 @@ SENDING_EMAIL = [email protected]
2222

2323
REPO_OWNER = CodeChefVIT
2424
REPO_NAME = devsoc-be-25
25+
26+
RECIPIENTS =

cmd/api/main.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,7 @@ func main() {
3131
router.AuthRoutes(e)
3232
router.PanelRoutes(e)
3333
router.InfoRoutes(e)
34+
utils.Cron()
35+
3436
e.Start(":" + utils.Config.Port)
3537
}

database/queries/user.sql

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ WHERE id > $1
44
ORDER BY id ASC
55
LIMIT $2;
66

7+
-- name: GetUsers :many
8+
SELECT * FROM users;
9+
710
-- name: GetAllVitians :many
811
SELECT * FROM users WHERE is_vitian = TRUE;
912

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ require (
1313
github.com/labstack/echo-jwt/v4 v4.3.0
1414
github.com/labstack/echo/v4 v4.13.2
1515
github.com/redis/go-redis/v9 v9.7.0
16+
github.com/robfig/cron v1.2.0
1617
go.uber.org/zap v1.27.0
1718
golang.org/x/crypto v0.31.0
1819
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
5050
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
5151
github.com/redis/go-redis/v9 v9.7.0 h1:HhLSs+B6O021gwzl+locl0zEDnyNkxMtf/Z3NNBMa9E=
5252
github.com/redis/go-redis/v9 v9.7.0/go.mod h1:f6zhXITC7JUJIlPEiBOTXxJgPLdZcA93GewI7inzyWw=
53+
github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ=
54+
github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k=
5355
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
5456
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
5557
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=

pkg/controller/admin.go

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -456,7 +456,7 @@ func GetAllTeamMembers(c echo.Context) error {
456456
}
457457

458458
return c.JSON(http.StatusOK, models.Response{
459-
Status:"success",
459+
Status: "success",
460460
Data: map[string]interface{}{
461461
"message": "Team fetched successfully",
462462
"team": team_members,
@@ -466,12 +466,12 @@ func GetAllTeamMembers(c echo.Context) error {
466466

467467
//Ban Team
468468

469-
func BanTeam (c echo.Context) error {
469+
func BanTeam(c echo.Context) error {
470470
var payload models.UnBanTeam
471471

472472
if err := c.Bind(&payload); err != nil {
473473
return c.JSON(http.StatusBadRequest, models.Response{
474-
Status:"fail",
474+
Status: "fail",
475475
Data: map[string]string{
476476
"message": "Improper request",
477477
"error": err.Error(),
@@ -481,8 +481,8 @@ func BanTeam (c echo.Context) error {
481481

482482
if err := utils.Validate.Struct(payload); err != nil {
483483
return c.JSON(http.StatusBadRequest, models.Response{
484-
Status:"fail",
485-
Data:utils.FormatValidationErrors(err),
484+
Status: "fail",
485+
Data: utils.FormatValidationErrors(err),
486486
})
487487
}
488488

@@ -493,18 +493,18 @@ func BanTeam (c echo.Context) error {
493493
if errors.Is(err, sql.ErrNoRows) {
494494
return c.JSON(http.StatusNotFound, &models.Response{
495495
Status: "fail",
496-
Data: "Team Does not exists",
496+
Data: "Team Does not exists",
497497
})
498498
}
499499
return c.JSON(http.StatusInternalServerError, &models.Response{
500500
Status: "fail",
501-
Data: err,
501+
Data: err,
502502
})
503503
}
504504

505505
if err := utils.Queries.BanTeam(ctx, team.ID); err != nil {
506506
return c.JSON(http.StatusBadRequest, models.Response{
507-
Status:"fail",
507+
Status: "fail",
508508
Data: map[string]string{
509509
"message": "Failed to Ban Team",
510510
"error": err.Error(),
@@ -513,19 +513,19 @@ func BanTeam (c echo.Context) error {
513513
}
514514

515515
return c.JSON(http.StatusOK, models.Response{
516-
Status:"success",
517-
Data:"Team Banned Successfully",
516+
Status: "success",
517+
Data: "Team Banned Successfully",
518518
})
519519
}
520520

521521
//UnBan Team
522522

523-
func UnBanTeam (c echo.Context) error {
523+
func UnBanTeam(c echo.Context) error {
524524
var payload models.UnBanTeam
525525

526526
if err := c.Bind(&payload); err != nil {
527527
return c.JSON(http.StatusBadRequest, models.Response{
528-
Status:"fail",
528+
Status: "fail",
529529
Data: map[string]string{
530530
"message": "Improper request",
531531
"error": err.Error(),
@@ -535,8 +535,8 @@ func UnBanTeam (c echo.Context) error {
535535

536536
if err := utils.Validate.Struct(payload); err != nil {
537537
return c.JSON(http.StatusBadRequest, models.Response{
538-
Status:"fail",
539-
Data:utils.FormatValidationErrors(err),
538+
Status: "fail",
539+
Data: utils.FormatValidationErrors(err),
540540
})
541541
}
542542

@@ -555,29 +555,29 @@ func UnBanTeam (c echo.Context) error {
555555
}
556556
return c.JSON(http.StatusInternalServerError, &models.Response{
557557
Status: "fail",
558-
Data: err,
558+
Data: err,
559559
})
560560
}
561561

562562
if err := utils.Queries.UnBanTeam(ctx, team.ID); err != nil {
563563
return c.JSON(http.StatusBadRequest, models.Response{
564-
Status:"fail",
565-
Data:"Failed to unban Team",
564+
Status: "fail",
565+
Data: "Failed to unban Team",
566566
})
567567
}
568568

569569
return c.JSON(http.StatusOK, models.Response{
570-
Status:"success",
571-
Data:"Team UnBanned Successfully",
570+
Status: "success",
571+
Data: "Team UnBanned Successfully",
572572
})
573573
}
574574

575-
func UpdateTeamRounds (c echo.Context) error {
575+
func UpdateTeamRounds(c echo.Context) error {
576576

577577
var payload models.TeamRoundQualified
578578

579579
if err := c.Bind(&payload); err != nil {
580-
return c.JSON(http.StatusBadRequest,models.Response{
580+
return c.JSON(http.StatusBadRequest, models.Response{
581581
Status: "fail",
582582
Data: map[string]string{
583583
"message": "Improper request",
@@ -588,33 +588,33 @@ func UpdateTeamRounds (c echo.Context) error {
588588

589589
if err := utils.Validate.Struct(payload); err != nil {
590590
return c.JSON(http.StatusBadRequest, models.Response{
591-
Status:"fail",
592-
Data: utils.FormatValidationErrors(err),
591+
Status: "fail",
592+
Data: utils.FormatValidationErrors(err),
593593
})
594594
}
595595

596596
ctx := c.Request().Context()
597597

598-
team,err := utils.Queries.GetTeamById(ctx,payload.TeamId)
598+
team, err := utils.Queries.GetTeamById(ctx, payload.TeamId)
599599
if err != nil {
600600
return c.JSON(http.StatusBadRequest, models.Response{
601-
Status:"fail",
601+
Status: "fail",
602602
Data: map[string]string{
603603
"message": "Team does not exists",
604604
"error": err.Error(),
605605
},
606606
})
607607
}
608608

609-
if err:= utils.Queries.UpdateTeamRound(ctx, db.UpdateTeamRoundParams{
609+
if err := utils.Queries.UpdateTeamRound(ctx, db.UpdateTeamRoundParams{
610610
RoundQualified: (pgtype.Int4{
611611
Int32: int32(payload.RoundQualified),
612-
Valid:true,
612+
Valid: true,
613613
}),
614614
ID: team.ID,
615615
}); err != nil {
616-
return c.JSON(http.StatusBadRequest,models.Response{
617-
Status:"fail",
616+
return c.JSON(http.StatusBadRequest, models.Response{
617+
Status: "fail",
618618
Data: map[string]string{
619619
"message": "failed ot update round",
620620
"error": err.Error(),
@@ -623,7 +623,7 @@ func UpdateTeamRounds (c echo.Context) error {
623623
}
624624

625625
return c.JSON(http.StatusOK, models.Response{
626-
Status:"success",
627-
Data:"Rounds qualified by team Updated",
626+
Status: "success",
627+
Data: "Rounds qualified by team Updated",
628628
})
629629
}

pkg/db/user.sql.go

Lines changed: 43 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/middleware/admin_check.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ func CheckAdmin(next echo.HandlerFunc) echo.HandlerFunc {
2424
return c.JSON(http.StatusForbidden, &models.Response{
2525
Status: "fail",
2626
Data: map[string]string{
27-
"error": "Access denied. Not panel",
27+
"error": "Access denied. Not admin",
2828
},
2929
})
3030
}
@@ -49,7 +49,7 @@ func CheckPanel(next echo.HandlerFunc) echo.HandlerFunc {
4949
return c.JSON(http.StatusForbidden, &models.Response{
5050
Status: "fail",
5151
Data: map[string]string{
52-
"message": "Access denied",
52+
"message": "Access denied. Not panel",
5353
},
5454
})
5555
}

pkg/utils/config.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ type cfg struct {
2828
SendingEmail string `env:"SENDING_EMAIL,notEmpty"`
2929
RepoOwner string `env:"REPO_OWNER,notEmpty"`
3030
RepoName string `env:"REPO_NAME,notEmpty"`
31-
CookieSecure bool `env:"SECURE" envDefault:"false"`
31+
Recipients string `env:"RECIPIENETS"`
32+
CookieSecure bool `env:"SECURE" envDefault:"false"`
3233
}
3334

3435
var Config cfg

pkg/utils/cron.go

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
package utils
2+
3+
import (
4+
"context"
5+
"encoding/csv"
6+
"fmt"
7+
"os"
8+
"strconv"
9+
"strings"
10+
11+
logger "github.com/CodeChefVIT/devsoc-be-24/pkg/logging"
12+
"github.com/robfig/cron"
13+
)
14+
15+
func Cron() {
16+
subject := fmt.Sprintf("Users Details")
17+
body := fmt.Sprintf("This mail contails details of all the users")
18+
19+
recipients := Config.Recipients
20+
21+
if recipients == "" {
22+
logger.Errorf("error in getenv")
23+
}
24+
25+
ToSendMail := strings.Split(recipients, ",")
26+
27+
cr := cron.New()
28+
err := cr.AddFunc("@daily", func() {
29+
ctx := context.Background()
30+
31+
users, err := Queries.GetUsers(ctx)
32+
if err != nil {
33+
logger.Errorf("DB error: %v", err)
34+
}
35+
36+
file, err := os.Create("users.csv")
37+
if err != nil {
38+
logger.Errorf("error creating file", err)
39+
}
40+
41+
defer file.Close()
42+
43+
csvWriter := csv.NewWriter(file)
44+
headers := []string{"ID", "FirstName", "LastName", "Email", "PhoneNo", "Gender", "RegNo", "TeamID", "VitEmail", "Hostel", "RoomNo", "GitHub", "Role", "IsLeader", "IsVerified", "IsBanned", "IsProfComplete"}
45+
46+
if err := csvWriter.Write(headers); err != nil {
47+
logger.Errorf("failed to write headers", err)
48+
return
49+
}
50+
51+
for _, user := range users {
52+
record := []string{
53+
user.ID.String(),
54+
user.FirstName,
55+
user.LastName,
56+
user.Email,
57+
user.PhoneNo.String,
58+
user.Gender,
59+
*user.RegNo,
60+
user.TeamID.UUID.String(),
61+
*user.VitEmail,
62+
user.HostelBlock,
63+
strconv.Itoa(int(user.RoomNo)),
64+
user.GithubProfile,
65+
user.Role,
66+
strconv.FormatBool(user.IsLeader),
67+
strconv.FormatBool(user.IsVerified),
68+
strconv.FormatBool(user.IsBanned),
69+
strconv.FormatBool(user.IsProfileComplete),
70+
}
71+
72+
if err := csvWriter.Write(record); err != nil {
73+
logger.Errorf("failed to write data", err)
74+
return
75+
}
76+
}
77+
78+
csvWriter.Flush()
79+
for _, user := range ToSendMail {
80+
SendEmail(user, subject, body, "users.csv")
81+
}
82+
logger.Infof("Mail Sent")
83+
})
84+
85+
if err != nil {
86+
logger.Errorf("Error in cron", err)
87+
}
88+
cr.Start()
89+
logger.Infof("Cron started")
90+
}

0 commit comments

Comments
 (0)