diff --git a/controller/codereview.go b/controller/codereview.go index a2a6f2e..85ac750 100644 --- a/controller/codereview.go +++ b/controller/codereview.go @@ -1,32 +1,30 @@ package controller import ( - "encoding/json" + "errors" "net/http" "github.com/Gornak40/crosspawn/internal/alerts" + "github.com/Gornak40/crosspawn/models" "github.com/gin-contrib/sessions" "github.com/gin-gonic/gin" ) +var ( + errInvalidSessionSubmit = errors.New("invalid submit in session") +) + +type codereviewFrom struct { + RatingDelta int `binding:"required" form:"ratingDelta"` +} + func (s *Server) CodereviewGET(c *gin.Context) { session := sessions.Default(c) user := session.Get("user") - submitEn, ok := session.Get("submit").(string) + submit, ok := session.Get("submit").(reviewContext) if !ok { - _ = alerts.Add(session, alerts.Alert{ - Message: "Select contest and problem", - Type: alerts.TypeInfo, - }) - c.Redirect(http.StatusFound, "/") - - return - } - - var submit reviewContext - if err := json.Unmarshal([]byte(submitEn), &submit); err != nil { - c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": "failed to unmarshal submit"}) + c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": errInvalidSessionSubmit.Error()}) return } @@ -46,3 +44,65 @@ func (s *Server) CodereviewGET(c *gin.Context) { "Flashes": alerts.Get(session), }) } + +func (s *Server) CodereviewPOST(c *gin.Context) { + var form codereviewFrom + + if err := c.ShouldBind(&form); err != nil { + c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + + return + } + + session := sessions.Default(c) + + submit, ok := session.Get("submit").(reviewContext) + if !ok { + c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": errInvalidSessionSubmit.Error()}) + + return + } + + var dbRun models.Run + quRun := models.Run{EjudgeID: submit.RunID, EjudgeContestID: submit.ContestID} + if err := s.db.Where(&quRun).First(&dbRun).Error; err != nil { + c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + + return + } + + dbRun.ReviewCount++ + dbRun.Rating += form.RatingDelta + + if err := s.db.Save(&dbRun).Error; err != nil { + c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + + return + } + + session.Delete("submit") + _ = session.Save() + + _ = alerts.Add(session, alerts.Alert{ + Message: "Review processed", + Type: alerts.TypeSuccess, + }) + c.Redirect(http.StatusFound, "/") +} + +func (s *Server) codereviewMiddleware(c *gin.Context) { + session := sessions.Default(c) + + if session.Get("submit") == nil { + _ = alerts.Add(session, alerts.Alert{ + Message: "Select contest and problem", + Type: alerts.TypeInfo, + }) + c.Redirect(http.StatusFound, "/") + c.Abort() + + return + } + + c.Next() +} diff --git a/controller/index.go b/controller/index.go index e0d4c6e..8284918 100644 --- a/controller/index.go +++ b/controller/index.go @@ -119,8 +119,8 @@ func (s *Server) IndexPOST(c *gin.Context) { ContestID: dbRun.EjudgeContestID, Problem: dbRun.EjudgeName, } - data, _ := json.Marshal(rctx) //nolint:errchkjson // It's my JSON - session.Set("submit", string(data)) + _, _ = json.Marshal(rctx) //nolint:errchkjson // It's my JSON + session.Set("submit", &rctx) _ = session.Save() _ = alerts.Add(session, alerts.Alert{ diff --git a/controller/login.go b/controller/login.go index d8c7357..d3ab436 100644 --- a/controller/login.go +++ b/controller/login.go @@ -20,9 +20,18 @@ func (s *Server) LoginGET(c *gin.Context) { session := sessions.Default(c) user := session.Get("user") + if user != nil { + _ = alerts.Add(session, alerts.Alert{ + Message: "Logout first", + Type: alerts.TypeWarning, + }) + c.Redirect(http.StatusFound, "/profile") + + return + } + c.HTML(http.StatusOK, "login.html", gin.H{ "Title": "Login", - "User": user, "Flashes": alerts.Get(session), }) } diff --git a/controller/profile.go b/controller/profile.go new file mode 100644 index 0000000..4eb3741 --- /dev/null +++ b/controller/profile.go @@ -0,0 +1,20 @@ +package controller + +import ( + "net/http" + + "github.com/Gornak40/crosspawn/internal/alerts" + "github.com/gin-contrib/sessions" + "github.com/gin-gonic/gin" +) + +func (s *Server) ProfileGET(c *gin.Context) { + session := sessions.Default(c) + user := session.Get("user") + + c.HTML(http.StatusOK, "profile.html", gin.H{ + "Title": "Profile GET", + "User": user, + "Flashes": alerts.Get(session), + }) +} diff --git a/controller/server.go b/controller/server.go index 50249ad..b8e261f 100644 --- a/controller/server.go +++ b/controller/server.go @@ -1,6 +1,8 @@ package controller import ( + "encoding/gob" + "github.com/Gornak40/crosspawn/config" "github.com/Gornak40/crosspawn/pkg/ejudge" "github.com/gin-contrib/sessions" @@ -28,6 +30,8 @@ func NewServer(db *gorm.DB, ej *ejudge.EjClient, cfg *config.ServerConfig) *Serv func (s *Server) InitRouter() *gin.Engine { r := gin.Default() + gob.Register(reviewContext{}) + store := cookie.NewStore([]byte(s.cfg.GinSecret)) r.Use(sessions.Sessions(sessionName, store)) @@ -42,18 +46,27 @@ func (s *Server) InitRouter() *gin.Engine { ua := r.Group("/", s.userMiddleware) { ua.GET("/", s.IndexGET) - ua.GET("/codereview", s.CodereviewGET) + ua.POST("/", s.IndexPOST) + ua.GET("/admin", s.AdminGET) + ua.POST("/admin", s.AdminPOST) + + ua.GET("/profile", s.ProfileGET) ua.POST("/logout", s.LogoutPOST) - ua.POST("/", s.IndexPOST) - ua.POST("/admin", s.AdminPOST) + } + + ca := ua.Group("/codereview", s.codereviewMiddleware) + { + ca.GET("/", s.CodereviewGET) + ca.POST("/", s.CodereviewPOST) } aa := ua.Group("/manage", s.adminMiddleware) { aa.GET("/", s.ManageGET) aa.POST("/", s.ManagePOST) + aa.POST("/flip", s.ManageFlipPOST) } diff --git a/models/run.go b/models/run.go index eb37d82..cc1bfde 100644 --- a/models/run.go +++ b/models/run.go @@ -14,6 +14,7 @@ type Run struct { EjudgeName string `gorm:"not null;type:varchar(32)"` ReviewCount uint `gorm:"not null"` + Rating int `gorm:"not null"` } func NewRunFromEj(run *ejudge.EjRun) *Run { diff --git a/templates/codereview.html b/templates/codereview.html index 57cb8bf..4522c67 100644 --- a/templates/codereview.html +++ b/templates/codereview.html @@ -10,7 +10,7 @@
{{ .Source }}
@@ -25,9 +25,15 @@