diff --git a/cmd/web_server/handler/auth.go b/cmd/web_server/handler/auth.go index 4e2bc8e..5cbb8d8 100644 --- a/cmd/web_server/handler/auth.go +++ b/cmd/web_server/handler/auth.go @@ -7,10 +7,10 @@ import ( "github.com/gin-gonic/gin" "github.com/oj-lab/oj-lab-platform/cmd/web_server/middleware" user_model "github.com/oj-lab/oj-lab-platform/models/user" - "github.com/oj-lab/oj-lab-platform/modules" gorm_agent "github.com/oj-lab/oj-lab-platform/modules/agent/gorm" auth_module "github.com/oj-lab/oj-lab-platform/modules/auth" log_module "github.com/oj-lab/oj-lab-platform/modules/log" + gin_utils "github.com/oj-lab/oj-lab-platform/modules/utils/gin" user_service "github.com/oj-lab/oj-lab-platform/services/user" ) @@ -30,14 +30,14 @@ func githubCallback(ginCtx *gin.Context) { code := ginCtx.Query("code") tokenResponse, err := auth_module.GetGithubAccessToken(code) if err != nil { - modules.NewInternalError(fmt.Sprintf("failed to get github access token: %v", err)).AppendToGin(ginCtx) + gin_utils.NewInternalError(ginCtx, fmt.Sprintf("failed to get github access token: %v", err)) return } log_module.AppLogger().WithField("tokenResponse", tokenResponse).Info("github callback") githubUser, err := auth_module.GetGithubUser(tokenResponse.AccessToken) if err != nil { - modules.NewInternalError(fmt.Sprintf("failed to get github user: %v", err)).AppendToGin(ginCtx) + gin_utils.NewInternalError(ginCtx, fmt.Sprintf("failed to get github user: %v", err)) return } @@ -50,14 +50,14 @@ func githubCallback(ginCtx *gin.Context) { AvatarURL: githubUser.AvatarURL, }) if err != nil { - modules.NewInternalError(fmt.Sprintf("failed to create user: %v", err)).AppendToGin(ginCtx) + gin_utils.NewInternalError(ginCtx, fmt.Sprintf("failed to create user: %v", err)) return } } ls, err := user_service.StartLoginSession(ginCtx, user.Account) if err != nil { - modules.NewInternalError(fmt.Sprintf("failed to start login session: %v", err)).AppendToGin(ginCtx) + gin_utils.NewInternalError(ginCtx, fmt.Sprintf("failed to start login session: %v", err)) } middleware.SetLoginSessionKeyCookie(ginCtx, ls.Key) @@ -68,7 +68,7 @@ func githubCallback(ginCtx *gin.Context) { func loginGithub(ginCtx *gin.Context) { u, err := auth_module.GetGithubOauthEntryURL(callbackURL) if err != nil { - modules.NewInternalError(fmt.Sprintf("failed to get github oauth entry url: %v", err)).AppendToGin(ginCtx) + gin_utils.NewInternalError(ginCtx, fmt.Sprintf("failed to get github oauth entry url: %v", err)) } ginCtx.Redirect(http.StatusFound, u.String()) } @@ -91,19 +91,19 @@ func loginByPassword(ginCtx *gin.Context) { body := &loginBody{} err := ginCtx.BindJSON(body) if err != nil { - modules.NewInvalidParamError("body", "invalid body").AppendToGin(ginCtx) + gin_utils.NewInvalidParamError(ginCtx, "body", "invalid body") return } db := gorm_agent.GetDefaultDB() user, err := user_model.GetUserByAccountPassword(db, body.Account, body.Password) if err != nil { - modules.NewUnauthorizedError("account or password incorrect").AppendToGin(ginCtx) + gin_utils.NewUnauthorizedError(ginCtx, "account or password incorrect") } ls, err := user_service.StartLoginSession(ginCtx, user.Account) if err != nil { - modules.NewInternalError(fmt.Sprintf("failed to login: %v", err)).AppendToGin(ginCtx) + gin_utils.NewInternalError(ginCtx, fmt.Sprintf("failed to login: %v", err)) return } middleware.SetLoginSessionKeyCookie(ginCtx, ls.Key) diff --git a/cmd/web_server/handler/judge.go b/cmd/web_server/handler/judge.go index 62db11b..674761e 100644 --- a/cmd/web_server/handler/judge.go +++ b/cmd/web_server/handler/judge.go @@ -8,7 +8,7 @@ import ( "github.com/google/uuid" "github.com/oj-lab/oj-lab-platform/models" judge_model "github.com/oj-lab/oj-lab-platform/models/judge" - "github.com/oj-lab/oj-lab-platform/modules" + gin_utils "github.com/oj-lab/oj-lab-platform/modules/utils/gin" judge_service "github.com/oj-lab/oj-lab-platform/services/judge" ) @@ -24,13 +24,13 @@ func getJudge(ginCtx *gin.Context) { uidString := ginCtx.Param("uid") uid, err := uuid.Parse(uidString) if err != nil { - modules.NewInvalidParamError("uid", "invalid uid").AppendToGin(ginCtx) + gin_utils.NewInvalidParamError(ginCtx, "uid", "invalid uid") return } judge, err := judge_service.GetJudge(ginCtx, uid) if err != nil { - modules.NewInternalError(fmt.Sprintf("failed to get judge: %v", err)).AppendToGin(ginCtx) + gin_utils.NewInternalError(ginCtx, fmt.Sprintf("failed to get judge: %v", err)) return } @@ -63,12 +63,12 @@ func getJudgeList(ginCtx *gin.Context) { limit, err := strconv.Atoi(limitQuery) if err != nil { - modules.NewInvalidParamError("limit", "invalid limit").AppendToGin(ginCtx) + gin_utils.NewInvalidParamError(ginCtx, "limit", "invalid limit") return } offset, err := strconv.Atoi(offsetQuery) if err != nil { - modules.NewInvalidParamError("offset", "invalid offset").AppendToGin(ginCtx) + gin_utils.NewInvalidParamError(ginCtx, "offset", "invalid offset") return } @@ -80,7 +80,7 @@ func getJudgeList(ginCtx *gin.Context) { judges, total, err := judge_service.GetJudgeList(ginCtx, options) if err != nil { - modules.NewInternalError(fmt.Sprintf("failed to get judge list: %v", err)).AppendToGin(ginCtx) + gin_utils.NewInternalError(ginCtx, fmt.Sprintf("failed to get judge list: %v", err)) return } diff --git a/cmd/web_server/handler/judge_result.go b/cmd/web_server/handler/judge_result.go index 119cba6..9223e3a 100644 --- a/cmd/web_server/handler/judge_result.go +++ b/cmd/web_server/handler/judge_result.go @@ -4,7 +4,7 @@ import ( "github.com/gin-gonic/gin" "github.com/google/uuid" judge_model "github.com/oj-lab/oj-lab-platform/models/judge" - "github.com/oj-lab/oj-lab-platform/modules" + gin_utils "github.com/oj-lab/oj-lab-platform/modules/utils/gin" judge_service "github.com/oj-lab/oj-lab-platform/services/judge" ) @@ -24,20 +24,20 @@ type ReportJudgeResultCountBody struct { func putReportJudgeResultCount(ginCtx *gin.Context) { body := ReportJudgeResultCountBody{} if err := ginCtx.ShouldBindJSON(&body); err != nil { - modules.NewInvalidParamError("body", "invalid body").AppendToGin(ginCtx) + gin_utils.NewInvalidParamError(ginCtx, "body", "invalid body") return } judgeUID, err := uuid.Parse(body.JudgeUID) if err != nil { - modules.NewInvalidParamError("judgeUID", "invalid judgeUID").AppendToGin(ginCtx) + gin_utils.NewInvalidParamError(ginCtx, "judgeUID", "invalid judgeUID") return } if err := judge_service.ReportJudgeResultCount( ginCtx, judgeUID, body.ResultCount, ); err != nil { - modules.NewInternalError(err.Error()).AppendToGin(ginCtx) + gin_utils.NewInternalError(ginCtx, err.Error()) return } @@ -56,17 +56,17 @@ type ReportJudgeResultBody struct { func postReportJudgeResult(ginCtx *gin.Context) { body := ReportJudgeResultBody{} if err := ginCtx.ShouldBindJSON(&body); err != nil { - modules.NewInvalidParamError("body", "invalid body").AppendToGin(ginCtx) + gin_utils.NewInvalidParamError(ginCtx, "body", "invalid body") } judgeUID, err := uuid.Parse(body.JudgeUIDString) if err != nil { - modules.NewInvalidParamError("judgeUID", "invalid judgeUID").AppendToGin(ginCtx) + gin_utils.NewInvalidParamError(ginCtx, "judgeUID", "invalid judgeUID") return } verdict := judge_model.JudgeVerdict(body.VerdictString) if !verdict.IsValid() { - modules.NewInvalidParamError("verdict", "invalid verdict").AppendToGin(ginCtx) + gin_utils.NewInvalidParamError(ginCtx, "verdict", "invalid verdict") return } @@ -77,7 +77,7 @@ func postReportJudgeResult(ginCtx *gin.Context) { MemoryUsageByte: body.MemoryUsageByte, }) if err != nil { - modules.NewInternalError(err.Error()).AppendToGin(ginCtx) + gin_utils.NewInternalError(ginCtx, err.Error()) return } } diff --git a/cmd/web_server/handler/judge_task.go b/cmd/web_server/handler/judge_task.go index 6acde2a..8297fc7 100644 --- a/cmd/web_server/handler/judge_task.go +++ b/cmd/web_server/handler/judge_task.go @@ -3,7 +3,7 @@ package handler import ( "github.com/gin-gonic/gin" judge_model "github.com/oj-lab/oj-lab-platform/models/judge" - "github.com/oj-lab/oj-lab-platform/modules" + gin_utils "github.com/oj-lab/oj-lab-platform/modules/utils/gin" judge_service "github.com/oj-lab/oj-lab-platform/services/judge" "github.com/redis/go-redis/v9" ) @@ -58,7 +58,7 @@ func putReportJudgeTask(ginCtx *gin.Context) { verdict := judge_model.JudgeVerdict(body.VerdictString) if !verdict.IsValid() { - modules.NewInvalidParamError("verdict", "invalid verdict").AppendToGin(ginCtx) + gin_utils.NewInvalidParamError(ginCtx, "verdict", "invalid verdict") return } diff --git a/cmd/web_server/handler/problem.go b/cmd/web_server/handler/problem.go index 5e1e4c1..186bac6 100644 --- a/cmd/web_server/handler/problem.go +++ b/cmd/web_server/handler/problem.go @@ -2,11 +2,12 @@ package handler import ( "net/http" + "strconv" "github.com/gin-gonic/gin" judge_model "github.com/oj-lab/oj-lab-platform/models/judge" problem_model "github.com/oj-lab/oj-lab-platform/models/problem" - "github.com/oj-lab/oj-lab-platform/modules" + gin_utils "github.com/oj-lab/oj-lab-platform/modules/utils/gin" judge_service "github.com/oj-lab/oj-lab-platform/services/judge" problem_service "github.com/oj-lab/oj-lab-platform/services/problem" ) @@ -94,9 +95,32 @@ func deleteProblem(ginCtx *gin.Context) { // @Accept json // @Success 200 func getProblemInfoList(ginCtx *gin.Context) { - problemInfoList, total, err := problem_service.GetProblemInfoList(ginCtx) + limitStr := ginCtx.Query("limit") + offsetStr := ginCtx.Query("offset") + if limitStr == "" { + limitStr = "10" + } + if offsetStr == "" { + offsetStr = "0" + } + limit, err := strconv.Atoi(limitStr) if err != nil { - _ = ginCtx.Error(err) + gin_utils.NewInvalidParamError(ginCtx, "limit", err.Error()) + return + } + offset, err := strconv.Atoi(offsetStr) + if err != nil { + gin_utils.NewInvalidParamError(ginCtx, "offset", err.Error()) + return + } + + problemInfoList, total, err := problem_service.GetProblemInfoList( + ginCtx, + &limit, + &offset, + ) + if err != nil { + gin_utils.NewInternalError(ginCtx, err.Error()) return } @@ -189,7 +213,7 @@ func postJudge(ginCtx *gin.Context) { judge := judge_model.NewJudge("", slug, body.Code, body.Language) result, err := judge_service.CreateJudge(ginCtx, judge) if err != nil { - modules.NewInternalError(err.Error()).AppendToGin(ginCtx) + gin_utils.NewInternalError(ginCtx, err.Error()) return } diff --git a/cmd/web_server/handler/user.go b/cmd/web_server/handler/user.go index ec2a653..00b8e79 100644 --- a/cmd/web_server/handler/user.go +++ b/cmd/web_server/handler/user.go @@ -9,8 +9,8 @@ import ( "github.com/gin-gonic/gin" "github.com/oj-lab/oj-lab-platform/cmd/web_server/middleware" user_model "github.com/oj-lab/oj-lab-platform/models/user" - "github.com/oj-lab/oj-lab-platform/modules" casbin_agent "github.com/oj-lab/oj-lab-platform/modules/agent/casbin" + gin_utils "github.com/oj-lab/oj-lab-platform/modules/utils/gin" user_service "github.com/oj-lab/oj-lab-platform/services/user" ) @@ -68,7 +68,7 @@ func GetUserList(ginCtx *gin.Context) { users, total, err := user_service.GetUserList(ginCtx, options) if err != nil { - modules.NewInternalError(fmt.Sprintf("failed to get user list: %v", err)).AppendToGin(ginCtx) + gin_utils.NewInternalError(ginCtx, fmt.Sprintf("failed to get user list: %v", err)) return } @@ -89,12 +89,12 @@ func GetUserList(ginCtx *gin.Context) { func me(ginCtx *gin.Context) { ls, err := middleware.GetLoginSessionFromGinCtx(ginCtx) if err != nil { - modules.NewUnauthorizedError("cannot load login session from cookie").AppendToGin(ginCtx) + gin_utils.NewUnauthorizedError(ginCtx, "cannot load login session from cookie") return } user, err := user_service.GetUser(ginCtx, ls.Key.Account) if err != nil { - modules.NewInternalError(fmt.Sprintf("failed to get user: %v", err)).AppendToGin(ginCtx) + gin_utils.NewInternalError(ginCtx, fmt.Sprintf("failed to get user: %v", err)) return } @@ -111,13 +111,13 @@ func grantUserRole(ginCtx *gin.Context) { body := &grantUserRoleBody{} err := ginCtx.BindJSON(body) if err != nil { - modules.NewInvalidParamError("body", "invalid body").AppendToGin(ginCtx) + gin_utils.NewInvalidParamError(ginCtx, "body", "invalid body") return } err = user_service.GrantUserRole(ginCtx, account, body.Role, body.Domain) if err != nil { - modules.NewInternalError(fmt.Sprintf("failed to grant user role: %v", err)).AppendToGin(ginCtx) + gin_utils.NewInternalError(ginCtx, fmt.Sprintf("failed to grant user role: %v", err)) return } @@ -134,13 +134,13 @@ func revokeUserRole(ginCtx *gin.Context) { body := &revokeUserRoleBody{} err := ginCtx.BindJSON(body) if err != nil { - modules.NewInvalidParamError("body", "invalid body").AppendToGin(ginCtx) + gin_utils.NewInvalidParamError(ginCtx, "body", "invalid body") return } err = user_service.RevokeUserRole(ginCtx, account, body.Role, body.Domain) if err != nil { - modules.NewInternalError(fmt.Sprintf("failed to revoke user role: %v", err)).AppendToGin(ginCtx) + gin_utils.NewInternalError(ginCtx, fmt.Sprintf("failed to revoke user role: %v", err)) return } diff --git a/cmd/web_server/middleware/casbin.go b/cmd/web_server/middleware/casbin.go index 27fbe82..52e20f1 100644 --- a/cmd/web_server/middleware/casbin.go +++ b/cmd/web_server/middleware/casbin.go @@ -2,9 +2,9 @@ package middleware import ( "github.com/gin-gonic/gin" - "github.com/oj-lab/oj-lab-platform/modules" casbin_agent "github.com/oj-lab/oj-lab-platform/modules/agent/casbin" log_module "github.com/oj-lab/oj-lab-platform/modules/log" + gin_utils "github.com/oj-lab/oj-lab-platform/modules/utils/gin" ) func BuildCasbinEnforceHandlerWithDomain(domain string) gin.HandlerFunc { @@ -14,7 +14,7 @@ func BuildCasbinEnforceHandlerWithDomain(domain string) gin.HandlerFunc { method := ginCtx.Request.Method ls, err := GetLoginSessionFromGinCtx(ginCtx) if err != nil { - modules.NewUnauthorizedError("cannot load login session from cookie").AppendToGin(ginCtx) + gin_utils.NewUnauthorizedError(ginCtx, "cannot load login session from cookie") ginCtx.Abort() return } @@ -22,12 +22,12 @@ func BuildCasbinEnforceHandlerWithDomain(domain string) gin.HandlerFunc { allow, err := enforcer.Enforce(casbin_agent.UserSubjectPrefix+ls.Key.Account, "_", domain, path, method) if err != nil { log_module.AppLogger().Errorf("Failed to enforce: %v", err) - modules.NewInternalError("Failed to enforce").AppendToGin(ginCtx) + gin_utils.NewInternalError(ginCtx, "Failed to enforce") ginCtx.Abort() return } if !allow { - modules.NewUnauthorizedError("Unauthorized").AppendToGin(ginCtx) + gin_utils.NewUnauthorizedError(ginCtx, "Unauthorized") ginCtx.Abort() return } diff --git a/cmd/web_server/middleware/error.go b/cmd/web_server/middleware/error.go index 9b2c2f1..7d4ffe2 100644 --- a/cmd/web_server/middleware/error.go +++ b/cmd/web_server/middleware/error.go @@ -2,19 +2,23 @@ package middleware import ( "fmt" + "net/http" "github.com/gin-gonic/gin" - "github.com/oj-lab/oj-lab-platform/modules" log_module "github.com/oj-lab/oj-lab-platform/modules/log" + gin_utils "github.com/oj-lab/oj-lab-platform/modules/utils/gin" ) -func GetServiceError(ginErr gin.Error) *modules.SeviceError { - if modules.IsServiceError(ginErr.Meta) { - return ginErr.Meta.(*modules.SeviceError) +func GetServiceError(ginErr gin.Error) *gin_utils.SeviceError { + if gin_utils.IsServiceError(ginErr.Meta) { + return ginErr.Meta.(*gin_utils.SeviceError) } else { - serviceErr := modules.NewInternalError(fmt.Sprintf("%v", ginErr.Err)) + serviceErr := gin_utils.SeviceError{ + Code: http.StatusInternalServerError, + Msg: fmt.Sprintf("%v", ginErr.Err), + } serviceErr.CaptureStackTrace() - return serviceErr + return &serviceErr } } diff --git a/cmd/web_server/middleware/login_session.go b/cmd/web_server/middleware/login_session.go index da3de2a..3c16941 100644 --- a/cmd/web_server/middleware/login_session.go +++ b/cmd/web_server/middleware/login_session.go @@ -5,8 +5,8 @@ import ( "github.com/gin-gonic/gin" "github.com/google/uuid" - "github.com/oj-lab/oj-lab-platform/modules" auth_module "github.com/oj-lab/oj-lab-platform/modules/auth" + gin_utils "github.com/oj-lab/oj-lab-platform/modules/utils/gin" ) const ( @@ -20,7 +20,7 @@ func BuildHandleRequireLoginWithRoles(roles []string) gin.HandlerFunc { return func(ginCtx *gin.Context) { ls, err := GetLoginSessionFromGinCtx(ginCtx) if err != nil { - modules.NewUnauthorizedError("cannot load login session from cookie").AppendToGin(ginCtx) + gin_utils.NewUnauthorizedError(ginCtx, "cannot load login session from cookie") ginCtx.Abort() return } @@ -33,7 +33,7 @@ func BuildHandleRequireLoginWithRoles(roles []string) gin.HandlerFunc { func HandleRequireLogin(ginCtx *gin.Context) { ls, err := GetLoginSessionFromGinCtx(ginCtx) if err != nil { - modules.NewUnauthorizedError("cannot load login session from cookie").AppendToGin(ginCtx) + gin_utils.NewUnauthorizedError(ginCtx, "cannot load login session from cookie") ginCtx.Abort() return } diff --git a/models/problem/problem_db.go b/models/problem/problem_db.go index 174ec97..1161557 100644 --- a/models/problem/problem_db.go +++ b/models/problem/problem_db.go @@ -50,7 +50,8 @@ func buildGetProblemTXByOptions(tx *gorm.DB, options GetProblemOptions, isCount tx = tx.Select(options.Selection) } if len(tagsList) > 0 { - tx = tx.Joins("JOIN problem_algorithm_tags ON problem_algorithm_tags.problem_slug = problems.slug"). + tx = tx. + Joins("JOIN problem_algorithm_tags ON problem_algorithm_tags.problem_slug = problems.slug"). Where("problem_algorithm_tags.algorithm_tag_name in ?", tagsList) } if options.Slug != nil { diff --git a/models/user/user_db.go b/models/user/user_db.go index 280123a..49bf5d5 100644 --- a/models/user/user_db.go +++ b/models/user/user_db.go @@ -1,7 +1,6 @@ package user_model import ( - "crypto/md5" "fmt" "net/url" "strings" @@ -9,12 +8,11 @@ import ( "github.com/alexedwards/argon2id" "github.com/oj-lab/oj-lab-platform/models" casbin_agent "github.com/oj-lab/oj-lab-platform/modules/agent/casbin" + gravatar_utils "github.com/oj-lab/oj-lab-platform/modules/utils/gravatar" "gorm.io/gorm" "gorm.io/gorm/clause" ) -const gravatarURLFormat = "https://www.gravatar.com/avatar/%x?d=identicon&s=512" - // Account, Password, Roles will be used to create a new user. func CreateUser(tx *gorm.DB, request User) (*User, error) { user := User{ @@ -28,11 +26,9 @@ func CreateUser(tx *gorm.DB, request User) (*User, error) { _, err := url.Parse(user.AvatarURL) if err != nil || user.AvatarURL == "" { if user.Email != nil { - md5sum := md5.Sum([]byte(*user.Email)) - user.AvatarURL = fmt.Sprintf(gravatarURLFormat, md5sum) + user.AvatarURL = gravatar_utils.GetAvatarURL(*user.Email) } else { - md5sum := md5.Sum([]byte(user.Account)) - user.AvatarURL = fmt.Sprintf(gravatarURLFormat, md5sum) + user.AvatarURL = gravatar_utils.GetAvatarURL(user.Account) } } diff --git a/modules/error.go b/modules/utils/gin/error.go similarity index 71% rename from modules/error.go rename to modules/utils/gin/error.go index 7b809b0..52e620e 100644 --- a/modules/error.go +++ b/modules/utils/gin/error.go @@ -1,4 +1,4 @@ -package modules +package gin_utils import ( "fmt" @@ -38,28 +38,31 @@ func IsServiceError(err interface{}) bool { return ok } -func NewInternalError(msg string) *SeviceError { - return &SeviceError{ +func NewInternalError(ginCtx *gin.Context, msg string) { + serviceErr := SeviceError{ Code: http.StatusInternalServerError, Msg: msg, } + serviceErr.AppendToGin(ginCtx) } -func NewUnauthorizedError(msg string) *SeviceError { - return &SeviceError{ +func NewUnauthorizedError(ginCtx *gin.Context, msg string) { + serviceErr := SeviceError{ Code: http.StatusUnauthorized, Msg: msg, } + serviceErr.AppendToGin(ginCtx) } -func NewInvalidParamError(param string, hints ...string) *SeviceError { +func NewInvalidParamError(ginCtx *gin.Context, param string, hints ...string) { msg := fmt.Sprintf("invalid param: %s", param) for _, hint := range hints { msg += fmt.Sprintf(", %s", hint) } - return &SeviceError{ + serviceErr := SeviceError{ Code: http.StatusBadRequest, Msg: msg, } + serviceErr.AppendToGin(ginCtx) } diff --git a/modules/utils/gin/query.go b/modules/utils/gin/query.go new file mode 100644 index 0000000..6b9dff0 --- /dev/null +++ b/modules/utils/gin/query.go @@ -0,0 +1,15 @@ +package gin_utils + +import ( + "strconv" + + "github.com/gin-gonic/gin" +) + +func QueryInt(ginCtx *gin.Context, key string, defaultValue int) (int, error) { + ValueStr := ginCtx.Query(key) + if ValueStr == "" { + return defaultValue, nil + } + return strconv.Atoi(ValueStr) +} diff --git a/modules/utils/gravatar/url.go b/modules/utils/gravatar/url.go new file mode 100644 index 0000000..8661109 --- /dev/null +++ b/modules/utils/gravatar/url.go @@ -0,0 +1,13 @@ +package gravatar_utils + +import ( + "crypto/md5" + "fmt" +) + +const gravatarURLFormat = "https://www.gravatar.com/avatar/%x?d=identicon&s=512" + +func GetAvatarURL(identityStr string) string { + md5sum := md5.Sum([]byte(identityStr)) + return fmt.Sprintf(gravatarURLFormat, md5sum) +} diff --git a/services/problem/problem_info.go b/services/problem/problem_info.go index dea9345..7876763 100644 --- a/services/problem/problem_info.go +++ b/services/problem/problem_info.go @@ -7,10 +7,12 @@ import ( gorm_agent "github.com/oj-lab/oj-lab-platform/modules/agent/gorm" ) -func GetProblemInfoList(_ context.Context) ([]problem_model.Problem, int64, error) { +func GetProblemInfoList(_ context.Context, limit, offset *int) ([]problem_model.Problem, int64, error) { db := gorm_agent.GetDefaultDB() getOptions := problem_model.GetProblemOptions{ Selection: problem_model.ProblemInfoSelection, + Limit: limit, + Offset: offset, } problemList, total, err := problem_model.GetProblemInfoListByOptions(db, getOptions)