From b82454e24aafb09e213b345e5d235a68d6c1db60 Mon Sep 17 00:00:00 2001 From: yash Date: Sat, 12 Aug 2023 15:59:33 +0530 Subject: [PATCH 1/2] feat: codechef and codeforces institute level rank feature added --- controllers/rank.go | 143 ++++++++++++++++++++++++++++++++++++++++++++ controllers/user.go | 2 + models/user.go | 3 +- routers/router.go | 5 ++ 4 files changed, 152 insertions(+), 1 deletion(-) create mode 100644 controllers/rank.go diff --git a/controllers/rank.go b/controllers/rank.go new file mode 100644 index 0000000..aac9f17 --- /dev/null +++ b/controllers/rank.go @@ -0,0 +1,143 @@ +package controllers + +import ( + // "context" + // "encoding/json" + "log" + "net/http" + "sort" + "strconv" + + // "os" + // "time" + + // "github.com/google/uuid" + // "github.com/mdg-iitr/Codephile/services/mail" + + "github.com/astaxie/beego" + // "github.com/dgrijalva/jwt-go" + // "github.com/dgrijalva/jwt-go/request" + "github.com/getsentry/sentry-go" + // "github.com/globalsign/mgo/bson" + // "github.com/gorilla/schema" + // . "github.com/mdg-iitr/Codephile/conf" + . "github.com/mdg-iitr/Codephile/errors" + "github.com/mdg-iitr/Codephile/models" + "github.com/mdg-iitr/Codephile/models/types" + // "github.com/mdg-iitr/Codephile/scrappers" + // "github.com/mdg-iitr/Codephile/services/auth" + // "github.com/mdg-iitr/Codephile/services/firebase" + // "github.com/mdg-iitr/Codephile/services/redis" + // "github.com/mdg-iitr/Codephile/services/worker" +) + + + +// Operations about the User's CP institute level rank +type RankController struct { + beego.Controller +} + +// @Title Codechef rank +// @Description Codechef inistitute level rank based on codechef worldrank +// @Security token_auth read:user +// @Param institute query string true "institute" +// @Success 200 {object} []types.SearchDoc +// @Failure 409 no user to belongs to this institute or user doesnt have codechef handle +// @Failure 400 bad request no institute parameter +// @Failure 500 server_error +// @router /codechef[get] +func (u *UserController) codechefRank() { + instituteName := u.GetString("institute") + res, err := models.FilterUsers(instituteName) + if err != nil { + hub := sentry.GetHubFromContext(u.Ctx.Request.Context()) + hub.CaptureException(err) + log.Println(err.Error()) + u.Ctx.ResponseWriter.WriteHeader(http.StatusInternalServerError) + u.Data["json"] = InternalServerError("server error.. report to admin") + u.ServeJSON() + return + } + if len(res) == 0 { + u.Ctx.ResponseWriter.WriteHeader(http.StatusNotFound) + u.Data["json"] = NotFoundError("no user belongs to this institute") + u.ServeJSON() + return + } + userWithCodechefHandle:= []types.SearchDoc{} + + for _,user := range res { + if(user.Handle.Codechef!=""){ + userWithCodechefHandle= append(userWithCodechefHandle,user) + } + } + if len(userWithCodechefHandle) == 0 { + u.Ctx.ResponseWriter.WriteHeader(http.StatusNotFound) + u.Data["json"] = NotFoundError("no user have codechef handle") + u.ServeJSON() + return + } + sort.Slice(userWithCodechefHandle,func(i,j int)bool{ + p1,_ := models.GetProfiles(userWithCodechefHandle[i].ID) + p2,_ := models.GetProfiles(userWithCodechefHandle[i].ID) + rank1,_ := strconv.Atoi(p1.CodechefProfile.WorldRank) + rank2,_ := strconv.Atoi(p2.CodechefProfile.WorldRank) + return rank1>rank2 + }) + + u.Data["json"] = userWithCodechefHandle + u.ServeJSON() +} + +// @Title Codeforces rank +// @Description Codechef inistitute level rank based on codeforces worldrank +// @Security token_auth read:user +// @Param institute query string true "institute" +// @Success 200 {object} []types.SearchDoc +// @Failure 409 no user to belongs to this institute or user doesnt have codechef handle +// @Failure 400 bad request no institute parameter +// @Failure 500 server_error +// @router /codeforces[get] +func (u *UserController) codeforcesRank() { + instituteName := u.GetString("institute") + res, err := models.FilterUsers(instituteName) + if err != nil { + hub := sentry.GetHubFromContext(u.Ctx.Request.Context()) + hub.CaptureException(err) + log.Println(err.Error()) + u.Ctx.ResponseWriter.WriteHeader(http.StatusInternalServerError) + u.Data["json"] = InternalServerError("server error.. report to admin") + u.ServeJSON() + return + } + if len(res) == 0 { + u.Ctx.ResponseWriter.WriteHeader(http.StatusNotFound) + u.Data["json"] = NotFoundError("no user belongs to this institute") + u.ServeJSON() + return + } + userWithCodeforcesHandle:= []types.SearchDoc{} + + for _,user := range res { + if(user.Handle.Codechef!=""){ + userWithCodeforcesHandle= append(userWithCodeforcesHandle,user) + } + } + if len(userWithCodeforcesHandle) == 0 { + u.Ctx.ResponseWriter.WriteHeader(http.StatusNotFound) + u.Data["json"] = NotFoundError("no user have codeforces handle") + u.ServeJSON() + return + } + sort.Slice(userWithCodeforcesHandle,func(i,j int)bool{ + p1,_ := models.GetProfiles(userWithCodeforcesHandle[i].ID) + p2,_ := models.GetProfiles(userWithCodeforcesHandle[i].ID) + rank1,_ := strconv.Atoi(p1.CodeforcesProfile.WorldRank) + rank2,_ := strconv.Atoi(p2.CodeforcesProfile.WorldRank) + return rank1>rank2 + }) + + u.Data["json"] = userWithCodeforcesHandle + u.ServeJSON() +} \ No newline at end of file diff --git a/controllers/user.go b/controllers/user.go index 1dfb077..958f159 100644 --- a/controllers/user.go +++ b/controllers/user.go @@ -55,6 +55,7 @@ type UserController struct { // @router /signup [post] func (u *UserController) CreateUser() { user, err := u.parseRequestBody() + if err != nil { u.Ctx.ResponseWriter.WriteHeader(http.StatusBadRequest) u.Data["json"] = BadInputError(err.Error()) @@ -229,6 +230,7 @@ func (u *UserController) Put() { func (u *UserController) Login() { username := u.Ctx.Request.FormValue("username") password := u.Ctx.Request.FormValue("password") + user, err := models.AuthenticateUser(username, password) if err == UserNotFoundError { u.Data["json"] = map[string]string{"error": "invalid user credential"} diff --git a/models/user.go b/models/user.go index a9e8a38..f71899b 100644 --- a/models/user.go +++ b/models/user.go @@ -7,7 +7,7 @@ import ( "log" "math/rand" "time" - + "github.com/astaxie/beego" "github.com/getsentry/sentry-go" "github.com/mdg-iitr/Codephile/services/firebase" @@ -120,6 +120,7 @@ func AddUser(u types.User) (string, error) { } u.Password = string(hash) err = collection.Collection.Insert(u) + if err != nil { return "", UserAlreadyExistError } diff --git a/routers/router.go b/routers/router.go index ccb914a..c397144 100644 --- a/routers/router.go +++ b/routers/router.go @@ -51,6 +51,11 @@ func init() { &controllers.GraphController{}, ), ), + beego.NSNamespace("/rank", + beego.NSInclude( + &controllers.RankController{}, + ), + ), ) beego.SetStaticPath("/static", "static") beego.Router("/", &controllers.HomePageController{}) From 4ce8d78d9ec56aa6941182d152ea2cd52182d765 Mon Sep 17 00:00:00 2001 From: yash Date: Sat, 12 Aug 2023 16:28:25 +0530 Subject: [PATCH 2/2] bfix: fixed a bug in rankController --- controllers/rank.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/controllers/rank.go b/controllers/rank.go index aac9f17..ec8b8bf 100644 --- a/controllers/rank.go +++ b/controllers/rank.go @@ -47,7 +47,7 @@ type RankController struct { // @Failure 400 bad request no institute parameter // @Failure 500 server_error // @router /codechef[get] -func (u *UserController) codechefRank() { +func (u *RankController) codechefRank() { instituteName := u.GetString("institute") res, err := models.FilterUsers(instituteName) if err != nil { @@ -99,7 +99,7 @@ func (u *UserController) codechefRank() { // @Failure 400 bad request no institute parameter // @Failure 500 server_error // @router /codeforces[get] -func (u *UserController) codeforcesRank() { +func (u *RankController) codeforcesRank() { instituteName := u.GetString("institute") res, err := models.FilterUsers(instituteName) if err != nil {