From e6efde0bcb842a0e2ea875effede53741cc929de Mon Sep 17 00:00:00 2001 From: chenyifan01 Date: Sat, 8 Oct 2022 15:32:43 +0800 Subject: [PATCH 01/29] #2908 1. add medal category api 2. add medal api(list,operate) --- models/medal.go | 103 ++++++++++++++++++++++++++++++ models/medal_category.go | 79 +++++++++++++++++++++++ models/models.go | 2 + models/user_medal.go | 10 +++ routers/medal/category.go | 46 +++++++++++++ routers/medal/medal.go | 46 +++++++++++++ routers/routes/routes.go | 14 +++- services/admin/operate_log/operate_log.go | 38 +++++++++++ services/medal/category.go | 64 +++++++++++++++++++ services/medal/medal.go | 64 +++++++++++++++++++ 10 files changed, 465 insertions(+), 1 deletion(-) create mode 100644 models/medal.go create mode 100644 models/medal_category.go create mode 100644 models/user_medal.go create mode 100644 routers/medal/category.go create mode 100644 routers/medal/medal.go create mode 100644 services/medal/category.go create mode 100644 services/medal/medal.go diff --git a/models/medal.go b/models/medal.go new file mode 100644 index 000000000..d2508b3b1 --- /dev/null +++ b/models/medal.go @@ -0,0 +1,103 @@ +package models + +import ( + "code.gitea.io/gitea/modules/timeutil" + "xorm.io/builder" +) + +type Medal struct { + ID int64 `xorm:"pk autoincr"` + Name string + LightedIcon string `xorm:"varchar(2048)"` + GreyedIcon string `xorm:"varchar(2048)"` + Url string `xorm:"varchar(2048)"` + CategoryId int64 + CreatedUnix timeutil.TimeStamp `xorm:"created"` + UpdatedUnix timeutil.TimeStamp `xorm:"updated"` + DeletedAt timeutil.TimeStamp `xorm:"deleted"` +} + +type GetMedalOpts struct { + MedalType MedalType +} + +type MedalAndCategory struct { + Medal Medal `xorm:"extends"` + Category MedalCategory `xorm:"extends"` +} + +func (*MedalAndCategory) TableName() string { + return "medal" +} + +func (m *MedalAndCategory) ToShow() *Medal4Show { + return &Medal4Show{ + ID: m.Medal.ID, + Name: m.Medal.Name, + LightedIcon: m.Medal.LightedIcon, + GreyedIcon: m.Medal.GreyedIcon, + Url: m.Medal.Url, + CategoryName: m.Category.Name, + CategoryId: m.Category.ID, + CreatedUnix: m.Medal.CreatedUnix, + UpdatedUnix: m.Medal.UpdatedUnix, + } +} + +type Medal4Show struct { + ID int64 + Name string + LightedIcon string + GreyedIcon string + Url string + CategoryName string + CategoryId int64 + CreatedUnix timeutil.TimeStamp + UpdatedUnix timeutil.TimeStamp +} + +func (m Medal4Show) ToDTO() Medal { + return Medal{ + Name: m.Name, + LightedIcon: m.LightedIcon, + GreyedIcon: m.GreyedIcon, + Url: m.Url, + CategoryId: m.CategoryId, + } +} + +func GetMedalList(opts GetMedalOpts) ([]*MedalAndCategory, error) { + var cond = builder.NewCond() + if opts.MedalType > 0 { + cond = cond.And(builder.Eq{"medal_category.type": opts.MedalType}) + } + + r := make([]*MedalAndCategory, 0) + if err := x.Join("INNER", "medal_category", "medal_category.ID = medal.category_id").Where(cond).OrderBy("medal.created_unix desc").Find(&r); err != nil { + return nil, err + } + return r, nil +} + +func AddMedal(m Medal) (int64, error) { + return x.Insert(&m) +} + +func UpdateMedalById(id int64, param Medal) (int64, error) { + return x.ID(id).Update(¶m) +} + +func DelMedal(id int64) (int64, error) { + return x.ID(id).Delete(&Medal{}) +} + +func GetMedalById(id int64) (*Medal, error) { + m := &Medal{} + has, err := x.ID(id).Get(m) + if err != nil { + return nil, err + } else if !has { + return nil, &ErrRecordNotExist{} + } + return m, nil +} diff --git a/models/medal_category.go b/models/medal_category.go new file mode 100644 index 000000000..3c8769650 --- /dev/null +++ b/models/medal_category.go @@ -0,0 +1,79 @@ +package models + +import "code.gitea.io/gitea/modules/timeutil" + +type MedalType int + +const ( + CustomizeMedal = iota + 1 + SystemMedal +) + +type MedalCategory struct { + ID int64 `xorm:"pk autoincr"` + Name string + Position int64 + Type MedalType + CreatedUnix timeutil.TimeStamp `xorm:"created"` + UpdatedUnix timeutil.TimeStamp `xorm:"updated"` + DeletedAt timeutil.TimeStamp `xorm:"deleted"` +} + +func (m *MedalCategory) ToShow() *MedalCategory4Show { + return &MedalCategory4Show{ + ID: m.ID, + Name: m.Name, + Position: m.Position, + Type: m.Type, + CreatedUnix: m.CreatedUnix, + } +} + +type MedalCategory4Show struct { + ID int64 `xorm:"pk autoincr"` + Name string + Position int64 + Type MedalType + CreatedUnix timeutil.TimeStamp `xorm:"created"` +} + +func (m MedalCategory4Show) ToDTO() MedalCategory { + return MedalCategory{ + ID: m.ID, + Name: m.Name, + Position: m.Position, + Type: m.Type, + CreatedUnix: m.CreatedUnix, + } +} + +func GetMedalCategoryList() ([]*MedalCategory, error) { + r := make([]*MedalCategory, 0) + if err := x.OrderBy("position asc,created_unix desc").Find(&r); err != nil { + return nil, err + } + return r, nil +} + +func AddMedalCategory(m MedalCategory) (int64, error) { + return x.Insert(&m) +} + +func UpdateMedalCategoryById(id int64, param MedalCategory) (int64, error) { + return x.ID(id).Update(¶m) +} + +func DelMedalCategory(id int64) (int64, error) { + return x.ID(id).Delete(&MedalCategory{}) +} + +func GetMedalCategoryById(id int64) (*MedalCategory, error) { + m := &MedalCategory{} + has, err := x.ID(id).Get(m) + if err != nil { + return nil, err + } else if !has { + return nil, &ErrRecordNotExist{} + } + return m, nil +} diff --git a/models/models.go b/models/models.go index 4c2079cd8..910bfde65 100755 --- a/models/models.go +++ b/models/models.go @@ -161,6 +161,8 @@ func init() { new(CloudbrainSpec), new(CloudbrainTemp), new(DatasetReference), + new(MedalCategory), + new(Medal), ) tablesStatistic = append(tablesStatistic, diff --git a/models/user_medal.go b/models/user_medal.go new file mode 100644 index 000000000..a4421df13 --- /dev/null +++ b/models/user_medal.go @@ -0,0 +1,10 @@ +package models + +import "code.gitea.io/gitea/modules/timeutil" + +type UserMedal struct { + ID int64 `xorm:"pk autoincr"` + UserId int64 `xorm:"index"` + MedalId int64 `xorm:"index"` + CreatedUnix timeutil.TimeStamp `xorm:"created"` +} diff --git a/routers/medal/category.go b/routers/medal/category.go new file mode 100644 index 000000000..b010af586 --- /dev/null +++ b/routers/medal/category.go @@ -0,0 +1,46 @@ +package medal + +import ( + "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/routers/response" + "code.gitea.io/gitea/services/medal" + "errors" + "net/http" +) + +func GetCategoryList(ctx *context.Context) { + r, err := medal.GetMedalCategoryList() + if err != nil { + log.Error("GetCategoryList error.%v", err) + ctx.JSON(http.StatusOK, response.ServerError(err.Error())) + return + } + m := make(map[string]interface{}) + m["List"] = r + ctx.JSON(http.StatusOK, response.SuccessWithData(m)) +} + +func OperateMedalCategory(ctx *context.Context, category models.MedalCategory4Show) { + action := ctx.Params(":action") + + var err error + switch action { + case "edit": + err = medal.EditMedalCategory(category, ctx.User) + case "new": + err = medal.AddMedalCategory(category, ctx.User) + case "del": + err = medal.DelMedalCategory(category.ID, ctx.User) + default: + err = errors.New("action type error") + } + + if err != nil { + log.Error("OperateMedalCategory error ,%v", err) + ctx.JSON(http.StatusOK, response.ServerError(err.Error())) + return + } + ctx.JSON(http.StatusOK, response.Success()) +} diff --git a/routers/medal/medal.go b/routers/medal/medal.go new file mode 100644 index 000000000..d0625a2b4 --- /dev/null +++ b/routers/medal/medal.go @@ -0,0 +1,46 @@ +package medal + +import ( + "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/routers/response" + "code.gitea.io/gitea/services/medal" + "errors" + "net/http" +) + +func GetCustomizeMedalList(ctx *context.Context) { + r, err := medal.GetMedalList(models.GetMedalOpts{MedalType: models.CustomizeMedal}) + if err != nil { + log.Error("GetCategoryList error.%v", err) + ctx.JSON(http.StatusOK, response.ServerError(err.Error())) + return + } + m := make(map[string]interface{}) + m["List"] = r + ctx.JSON(http.StatusOK, response.SuccessWithData(m)) +} + +func OperateMedal(ctx *context.Context, category models.Medal4Show) { + action := ctx.Params(":action") + + var err error + switch action { + case "edit": + err = medal.EditMedal(category, ctx.User) + case "new": + err = medal.AddMedal(category, ctx.User) + case "del": + err = medal.DelMedal(category.ID, ctx.User) + default: + err = errors.New("action type error") + } + + if err != nil { + log.Error("OperateCustomizeMedal error ,%v", err) + ctx.JSON(http.StatusOK, response.ServerError(err.Error())) + return + } + ctx.JSON(http.StatusOK, response.Success()) +} diff --git a/routers/routes/routes.go b/routers/routes/routes.go index 66a357c79..5830edfdc 100755 --- a/routers/routes/routes.go +++ b/routers/routes/routes.go @@ -6,6 +6,7 @@ package routes import ( "bytes" + "code.gitea.io/gitea/routers/medal" "code.gitea.io/gitea/routers/reward/point" "code.gitea.io/gitea/routers/task" "code.gitea.io/gitea/services/reward" @@ -659,9 +660,20 @@ func RegisterRoutes(m *macaron.Macaron) { m.Group("/task/config", func() { m.Get("/list", task.GetTaskConfigList) - m.Post("/add/batch", bindIgnErr(models.BatchLimitConfigVO{}), task.BatchAddTaskConfig) m.Post("/^:action(new|edit|del)$", bindIgnErr(models.TaskConfigWithLimit{}), task.OperateTaskConfig) }) + + m.Group("/medal", func() { + m.Group("/category", func() { + m.Get("/list", medal.GetCategoryList) + m.Post("/^:action(new|edit|del)$", bindIgnErr(models.MedalCategory4Show{}), medal.OperateMedalCategory) + }) + m.Group("/customize", func() { + m.Get("/list", medal.GetCustomizeMedalList) + }) + m.Post("/^:action(new|edit|del)$", bindIgnErr(models.Medal4Show{}), medal.OperateMedal) + }) + }, operationReq) // ***** END: Operation ***** diff --git a/services/admin/operate_log/operate_log.go b/services/admin/operate_log/operate_log.go index 7b72ec2e2..7f966db0c 100644 --- a/services/admin/operate_log/operate_log.go +++ b/services/admin/operate_log/operate_log.go @@ -4,6 +4,13 @@ import ( "code.gitea.io/gitea/models" ) +type LogBizType string + +const ( + MedalCategoryOperate LogBizType = "MedalCategoryOperate" + MedalOperate LogBizType = "MedalOperate" +) + func Log(log models.AdminOperateLog) error { _, err := models.InsertAdminOperateLog(log) return err @@ -12,3 +19,34 @@ func Log(log models.AdminOperateLog) error { func NewLogValues() *models.LogValues { return &models.LogValues{Params: make([]models.LogValue, 0)} } + +func Log4Add(bizType LogBizType, newValue interface{}, doerId int64, comment string) { + Log(models.AdminOperateLog{ + BizType: string(bizType), + OperateType: "add", + NewValue: NewLogValues().Add("new", newValue).JsonString(), + CreatedBy: doerId, + Comment: comment, + }) +} + +func Log4Edit(bizType LogBizType, oldValue interface{}, newValue interface{}, doerId int64, comment string) { + Log(models.AdminOperateLog{ + BizType: string(bizType), + OperateType: "edit", + NewValue: NewLogValues().Add("new", newValue).JsonString(), + OldValue: NewLogValues().Add("old", oldValue).JsonString(), + CreatedBy: doerId, + Comment: comment, + }) +} + +func Log4Del(bizType LogBizType, oldValue interface{}, doerId int64, comment string) { + Log(models.AdminOperateLog{ + BizType: string(bizType), + OperateType: "del", + OldValue: NewLogValues().Add("old", oldValue).JsonString(), + CreatedBy: doerId, + Comment: comment, + }) +} diff --git a/services/medal/category.go b/services/medal/category.go new file mode 100644 index 000000000..50f1b804e --- /dev/null +++ b/services/medal/category.go @@ -0,0 +1,64 @@ +package medal + +import ( + "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/services/admin/operate_log" + "errors" +) + +func GetMedalCategoryList() ([]*models.MedalCategory4Show, error) { + list, err := models.GetMedalCategoryList() + if err != nil { + return nil, err + } + if len(list) == 0 { + return nil, nil + } + r := make([]*models.MedalCategory4Show, len(list)) + for i := 0; i < len(list); i++ { + r[i] = list[i].ToShow() + } + + return r, nil +} + +func AddMedalCategory(m models.MedalCategory4Show, doer *models.User) error { + _, err := models.AddMedalCategory(m.ToDTO()) + if err != nil { + return err + } + operate_log.Log4Add(operate_log.MedalCategoryOperate, m, doer.ID, "新增了勋章分类") + return nil +} + +func EditMedalCategory(m models.MedalCategory4Show, doer *models.User) error { + if m.ID == 0 { + log.Error(" EditMedalCategory param error") + return errors.New("param error") + } + old, err := models.GetMedalCategoryById(m.ID) + if err != nil { + return err + } + _, err = models.UpdateMedalCategoryById(m.ID, m.ToDTO()) + if err != nil { + return err + } + operate_log.Log4Edit(operate_log.MedalCategoryOperate, old, m.ToDTO(), doer.ID, "修改了勋章分类") + return err +} + +func DelMedalCategory(id int64, doer *models.User) error { + if id == 0 { + log.Error(" DelMedalCategory param error") + return errors.New("param error") + } + old, err := models.GetMedalCategoryById(id) + if err != nil { + return err + } + _, err = models.DelMedalCategory(id) + operate_log.Log4Del(operate_log.MedalCategoryOperate, old, doer.ID, "删除了勋章分类") + return err +} diff --git a/services/medal/medal.go b/services/medal/medal.go new file mode 100644 index 000000000..967d7011f --- /dev/null +++ b/services/medal/medal.go @@ -0,0 +1,64 @@ +package medal + +import ( + "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/services/admin/operate_log" + "errors" +) + +func GetMedalList(opts models.GetMedalOpts) ([]*models.Medal4Show, error) { + list, err := models.GetMedalList(opts) + if err != nil { + return nil, err + } + if len(list) == 0 { + return nil, nil + } + r := make([]*models.Medal4Show, len(list)) + for i := 0; i < len(list); i++ { + r[i] = list[i].ToShow() + } + + return r, nil +} + +func AddMedal(m models.Medal4Show, doer *models.User) error { + _, err := models.AddMedal(m.ToDTO()) + if err != nil { + return err + } + operate_log.Log4Add(operate_log.MedalOperate, m, doer.ID, "新增了勋章") + return nil +} + +func EditMedal(m models.Medal4Show, doer *models.User) error { + if m.ID == 0 { + log.Error(" EditMedal param error") + return errors.New("param error") + } + old, err := models.GetMedalById(m.ID) + if err != nil { + return err + } + _, err = models.UpdateMedalById(m.ID, m.ToDTO()) + if err != nil { + return err + } + operate_log.Log4Edit(operate_log.MedalOperate, old, m.ToDTO(), doer.ID, "修改了勋章") + return err +} + +func DelMedal(id int64, doer *models.User) error { + if id == 0 { + log.Error(" DelMedal param error") + return errors.New("param error") + } + old, err := models.GetMedalById(id) + if err != nil { + return err + } + _, err = models.DelMedal(id) + operate_log.Log4Del(operate_log.MedalOperate, old, doer.ID, "删除了勋章") + return err +} From def6c11dbfaac24301ba1c1b8aa268cf55550d22 Mon Sep 17 00:00:00 2001 From: chenyifan01 Date: Sun, 9 Oct 2022 18:07:57 +0800 Subject: [PATCH 02/29] #2908 1.medal-> badge 2.add badge user management 3.add badge in user profile --- models/badge.go | 137 +++++++++++++++++++++++ models/{medal_category.go => badge_category.go} | 38 +++---- models/badge_user.go | 140 ++++++++++++++++++++++++ models/medal.go | 103 ----------------- models/models.go | 6 +- models/user.go | 21 ++++ models/user_medal.go | 10 -- routers/badge/badge.go | 98 +++++++++++++++++ routers/{medal => badge}/category.go | 18 +-- routers/medal/medal.go | 46 -------- routers/routes/routes.go | 18 ++- routers/user/profile.go | 16 +++ services/admin/operate_log/operate_log.go | 4 +- services/badge/badge.go | 64 +++++++++++ services/badge/category.go | 64 +++++++++++ services/badge/user.go | 104 ++++++++++++++++++ services/medal/category.go | 64 ----------- services/medal/medal.go | 64 ----------- 18 files changed, 690 insertions(+), 325 deletions(-) create mode 100644 models/badge.go rename models/{medal_category.go => badge_category.go} (59%) create mode 100644 models/badge_user.go delete mode 100644 models/medal.go delete mode 100644 models/user_medal.go create mode 100644 routers/badge/badge.go rename routers/{medal => badge}/category.go (62%) delete mode 100644 routers/medal/medal.go create mode 100644 services/badge/badge.go create mode 100644 services/badge/category.go create mode 100644 services/badge/user.go delete mode 100644 services/medal/category.go delete mode 100644 services/medal/medal.go diff --git a/models/badge.go b/models/badge.go new file mode 100644 index 000000000..20e3ea66a --- /dev/null +++ b/models/badge.go @@ -0,0 +1,137 @@ +package models + +import ( + "code.gitea.io/gitea/modules/timeutil" + "xorm.io/builder" +) + +type Badge struct { + ID int64 `xorm:"pk autoincr"` + Name string + LightedIcon string `xorm:"varchar(2048)"` + GreyedIcon string `xorm:"varchar(2048)"` + Url string `xorm:"varchar(2048)"` + CategoryId int64 + CreatedUnix timeutil.TimeStamp `xorm:"created"` + UpdatedUnix timeutil.TimeStamp `xorm:"updated"` + DeletedAt timeutil.TimeStamp `xorm:"deleted"` +} + +func (m *Badge) ToUserShow() *Badge4UserShow { + return &Badge4UserShow{ + Name: m.Name, + LightedIcon: m.LightedIcon, + GreyedIcon: m.GreyedIcon, + Url: m.Url, + } +} + +type GetBadgeOpts struct { + BadgeType BadgeType +} + +type BadgeAndCategory struct { + Badge Badge `xorm:"extends"` + Category BadgeCategory `xorm:"extends"` +} + +func (*BadgeAndCategory) TableName() string { + return "badge" +} + +func (m *BadgeAndCategory) ToShow() *Badge4AdminShow { + return &Badge4AdminShow{ + ID: m.Badge.ID, + Name: m.Badge.Name, + LightedIcon: m.Badge.LightedIcon, + GreyedIcon: m.Badge.GreyedIcon, + Url: m.Badge.Url, + CategoryName: m.Category.Name, + CategoryId: m.Category.ID, + CreatedUnix: m.Badge.CreatedUnix, + UpdatedUnix: m.Badge.UpdatedUnix, + } +} + +type Badge4AdminShow struct { + ID int64 + Name string + LightedIcon string + GreyedIcon string + Url string + CategoryName string + CategoryId int64 + CreatedUnix timeutil.TimeStamp + UpdatedUnix timeutil.TimeStamp +} + +func (m Badge4AdminShow) ToDTO() Badge { + return Badge{ + Name: m.Name, + LightedIcon: m.LightedIcon, + GreyedIcon: m.GreyedIcon, + Url: m.Url, + CategoryId: m.CategoryId, + } +} + +type Badge4UserShow struct { + Name string + LightedIcon string + GreyedIcon string + Url string +} + +type BadgeShowWithStatus struct { + Badge *Badge4UserShow + IsLighted bool +} + +type UserAllBadgeInCategory struct { + CategoryName string + CategoryId int64 + LightedNum int + Badges []*BadgeShowWithStatus +} + +func GetBadgeList(opts GetBadgeOpts) ([]*BadgeAndCategory, error) { + var cond = builder.NewCond() + if opts.BadgeType > 0 { + cond = cond.And(builder.Eq{"badge_category.type": opts.BadgeType}) + } + + r := make([]*BadgeAndCategory, 0) + if err := x.Join("INNER", "badge_category", "badge_category.ID = badge.category_id").Where(cond).OrderBy("badge.created_unix desc").Find(&r); err != nil { + return nil, err + } + return r, nil +} + +func AddBadge(m Badge) (int64, error) { + return x.Insert(&m) +} + +func UpdateBadgeById(id int64, param Badge) (int64, error) { + return x.ID(id).Update(¶m) +} + +func DelBadge(id int64) (int64, error) { + return x.ID(id).Delete(&Badge{}) +} + +func GetBadgeById(id int64) (*Badge, error) { + m := &Badge{} + has, err := x.ID(id).Get(m) + if err != nil { + return nil, err + } else if !has { + return nil, &ErrRecordNotExist{} + } + return m, nil +} + +func GetBadgeByCategoryId(categoryId int64) ([]*Badge, error) { + r := make([]*Badge, 0) + err := x.Where("category_id = ?", categoryId).Find(&r) + return r, err +} diff --git a/models/medal_category.go b/models/badge_category.go similarity index 59% rename from models/medal_category.go rename to models/badge_category.go index 3c8769650..e8f90f6c1 100644 --- a/models/medal_category.go +++ b/models/badge_category.go @@ -2,25 +2,25 @@ package models import "code.gitea.io/gitea/modules/timeutil" -type MedalType int +type BadgeType int const ( - CustomizeMedal = iota + 1 - SystemMedal + CustomizeBadge = iota + 1 + SystemBadge ) -type MedalCategory struct { +type BadgeCategory struct { ID int64 `xorm:"pk autoincr"` Name string Position int64 - Type MedalType + Type BadgeType CreatedUnix timeutil.TimeStamp `xorm:"created"` UpdatedUnix timeutil.TimeStamp `xorm:"updated"` DeletedAt timeutil.TimeStamp `xorm:"deleted"` } -func (m *MedalCategory) ToShow() *MedalCategory4Show { - return &MedalCategory4Show{ +func (m *BadgeCategory) ToShow() *BadgeCategory4Show { + return &BadgeCategory4Show{ ID: m.ID, Name: m.Name, Position: m.Position, @@ -29,16 +29,16 @@ func (m *MedalCategory) ToShow() *MedalCategory4Show { } } -type MedalCategory4Show struct { +type BadgeCategory4Show struct { ID int64 `xorm:"pk autoincr"` Name string Position int64 - Type MedalType + Type BadgeType CreatedUnix timeutil.TimeStamp `xorm:"created"` } -func (m MedalCategory4Show) ToDTO() MedalCategory { - return MedalCategory{ +func (m BadgeCategory4Show) ToDTO() BadgeCategory { + return BadgeCategory{ ID: m.ID, Name: m.Name, Position: m.Position, @@ -47,28 +47,28 @@ func (m MedalCategory4Show) ToDTO() MedalCategory { } } -func GetMedalCategoryList() ([]*MedalCategory, error) { - r := make([]*MedalCategory, 0) +func GetBadgeCategoryList() ([]*BadgeCategory, error) { + r := make([]*BadgeCategory, 0) if err := x.OrderBy("position asc,created_unix desc").Find(&r); err != nil { return nil, err } return r, nil } -func AddMedalCategory(m MedalCategory) (int64, error) { +func AddBadgeCategory(m BadgeCategory) (int64, error) { return x.Insert(&m) } -func UpdateMedalCategoryById(id int64, param MedalCategory) (int64, error) { +func UpdateBadgeCategoryById(id int64, param BadgeCategory) (int64, error) { return x.ID(id).Update(¶m) } -func DelMedalCategory(id int64) (int64, error) { - return x.ID(id).Delete(&MedalCategory{}) +func DelBadgeCategory(id int64) (int64, error) { + return x.ID(id).Delete(&BadgeCategory{}) } -func GetMedalCategoryById(id int64) (*MedalCategory, error) { - m := &MedalCategory{} +func GetBadgeCategoryById(id int64) (*BadgeCategory, error) { + m := &BadgeCategory{} has, err := x.ID(id).Get(m) if err != nil { return nil, err diff --git a/models/badge_user.go b/models/badge_user.go new file mode 100644 index 000000000..b2428ab1a --- /dev/null +++ b/models/badge_user.go @@ -0,0 +1,140 @@ +package models + +import ( + "code.gitea.io/gitea/modules/timeutil" + "xorm.io/builder" +) + +const ( + ActionAddBadgeUser = 1 + ActionDelBadgeUser = 2 +) + +type BadgeUser struct { + ID int64 `xorm:"pk autoincr"` + UserId int64 `xorm:"unique(user_id,badge_id)"` + BadgeId int64 `xorm:"index"` + CreatedUnix timeutil.TimeStamp `xorm:"created index"` +} + +type BadgeUserLog struct { + ID int64 `xorm:"pk autoincr"` + UserId int64 `xorm:"index"` + BadgeId int64 `xorm:"index"` + Action int + CreatedUnix timeutil.TimeStamp `xorm:"created index"` +} + +type BadgeUserDetail struct { + BadgeUser BadgeUser `xorm:"extends"` + User User `xorm:"extends"` +} + +func (*BadgeUserDetail) TableName() string { + return "badge_user" +} + +func (m *BadgeUserDetail) ToShow() *BadgeUser4SHow { + return &BadgeUser4SHow{ + ID: m.BadgeUser.ID, + UserId: m.BadgeUser.UserId, + Name: m.User.Name, + Avatar: m.User.RelAvatarLink(), + Email: m.User.Email, + CreatedUnix: m.BadgeUser.CreatedUnix, + } +} + +type BadgeUser4SHow struct { + ID int64 + UserId int64 + Name string + Avatar string + Email string + CreatedUnix timeutil.TimeStamp +} + +type AddBadgeUsersReq struct { + BadgeId int64 + Users string +} +type DelBadgeUserReq struct { + ID int64 +} + +type GetUserBadgesOpts struct { + CategoryId int64 + ListOptions +} + +func AddBadgeUser(m BadgeUser) (int64, error) { + sess := x.NewSession() + defer sess.Close() + sess.Begin() + n, err := sess.Insert(&m) + if err != nil || n == 0 { + return 0, err + } + _, err = sess.Insert(&BadgeUserLog{ + UserId: m.UserId, + BadgeId: m.BadgeId, + Action: ActionAddBadgeUser, + }) + if err != nil { + sess.Rollback() + return 0, err + } + return n, sess.Commit() +} + +func DelBadgeUser(id int64) (int64, error) { + m := BadgeUser{} + has, err := x.ID(id).Get(&m) + if err != nil { + return 0, err + } + if !has { + return 0, ErrRecordNotExist{} + } + sess := x.NewSession() + defer sess.Close() + sess.Begin() + n, err := x.ID(m.ID).Delete(&BadgeUser{}) + if err != nil || n == 0 { + return 0, err + } + _, err = sess.Insert(&BadgeUserLog{ + UserId: m.UserId, + BadgeId: m.BadgeId, + Action: ActionDelBadgeUser, + }) + if err != nil { + sess.Rollback() + return 0, err + } + return n, sess.Commit() +} + +func GetBadgeUsers(badgeId int64, opts ListOptions) ([]BadgeUserDetail, error) { + if opts.Page <= 0 { + opts.Page = 1 + } + m := make([]BadgeUserDetail, 0) + err := x.Join("LEFT", "public.user", "public.user.ID = badge_user.user_id").Where("badge_user.badge_id = ?", badgeId).OrderBy("badge_user.created_unix desc").Limit(opts.PageSize, (opts.Page-1)*opts.PageSize).Find(&m) + if err != nil { + return nil, err + } + return m, nil +} + +func GetUserBadges(userId int64, opts GetUserBadgesOpts) ([]*Badge, error) { + cond := builder.NewCond() + cond = cond.And(builder.Eq{"badge_user.user_id": userId}) + if opts.CategoryId > 0 { + cond = cond.And(builder.Eq{"badge.category_id": opts.CategoryId}) + } + + r := make([]*Badge, 0) + err := x.Join("INNER", "badge_user", "badge_user.badge_id = badge.id").Where(cond).OrderBy("badge_user.created_unix desc").Limit(opts.PageSize, (opts.Page-1)*opts.PageSize).Find(&r) + return r, err +} diff --git a/models/medal.go b/models/medal.go deleted file mode 100644 index d2508b3b1..000000000 --- a/models/medal.go +++ /dev/null @@ -1,103 +0,0 @@ -package models - -import ( - "code.gitea.io/gitea/modules/timeutil" - "xorm.io/builder" -) - -type Medal struct { - ID int64 `xorm:"pk autoincr"` - Name string - LightedIcon string `xorm:"varchar(2048)"` - GreyedIcon string `xorm:"varchar(2048)"` - Url string `xorm:"varchar(2048)"` - CategoryId int64 - CreatedUnix timeutil.TimeStamp `xorm:"created"` - UpdatedUnix timeutil.TimeStamp `xorm:"updated"` - DeletedAt timeutil.TimeStamp `xorm:"deleted"` -} - -type GetMedalOpts struct { - MedalType MedalType -} - -type MedalAndCategory struct { - Medal Medal `xorm:"extends"` - Category MedalCategory `xorm:"extends"` -} - -func (*MedalAndCategory) TableName() string { - return "medal" -} - -func (m *MedalAndCategory) ToShow() *Medal4Show { - return &Medal4Show{ - ID: m.Medal.ID, - Name: m.Medal.Name, - LightedIcon: m.Medal.LightedIcon, - GreyedIcon: m.Medal.GreyedIcon, - Url: m.Medal.Url, - CategoryName: m.Category.Name, - CategoryId: m.Category.ID, - CreatedUnix: m.Medal.CreatedUnix, - UpdatedUnix: m.Medal.UpdatedUnix, - } -} - -type Medal4Show struct { - ID int64 - Name string - LightedIcon string - GreyedIcon string - Url string - CategoryName string - CategoryId int64 - CreatedUnix timeutil.TimeStamp - UpdatedUnix timeutil.TimeStamp -} - -func (m Medal4Show) ToDTO() Medal { - return Medal{ - Name: m.Name, - LightedIcon: m.LightedIcon, - GreyedIcon: m.GreyedIcon, - Url: m.Url, - CategoryId: m.CategoryId, - } -} - -func GetMedalList(opts GetMedalOpts) ([]*MedalAndCategory, error) { - var cond = builder.NewCond() - if opts.MedalType > 0 { - cond = cond.And(builder.Eq{"medal_category.type": opts.MedalType}) - } - - r := make([]*MedalAndCategory, 0) - if err := x.Join("INNER", "medal_category", "medal_category.ID = medal.category_id").Where(cond).OrderBy("medal.created_unix desc").Find(&r); err != nil { - return nil, err - } - return r, nil -} - -func AddMedal(m Medal) (int64, error) { - return x.Insert(&m) -} - -func UpdateMedalById(id int64, param Medal) (int64, error) { - return x.ID(id).Update(¶m) -} - -func DelMedal(id int64) (int64, error) { - return x.ID(id).Delete(&Medal{}) -} - -func GetMedalById(id int64) (*Medal, error) { - m := &Medal{} - has, err := x.ID(id).Get(m) - if err != nil { - return nil, err - } else if !has { - return nil, &ErrRecordNotExist{} - } - return m, nil -} diff --git a/models/models.go b/models/models.go index 910bfde65..ff64bfad2 100755 --- a/models/models.go +++ b/models/models.go @@ -161,8 +161,10 @@ func init() { new(CloudbrainSpec), new(CloudbrainTemp), new(DatasetReference), - new(MedalCategory), - new(Medal), + new(BadgeCategory), + new(Badge), + new(BadgeUser), + new(BadgeUserLog), ) tablesStatistic = append(tablesStatistic, diff --git a/models/user.go b/models/user.go index f40eb699f..b21858e37 100755 --- a/models/user.go +++ b/models/user.go @@ -2184,3 +2184,24 @@ func GetBlockChainUnSuccessUsers() ([]*User, error) { Find(&users) return users, err } + +//GetUserIdsByUserNames Get userIDs in batches through username paging, this method will ignore errors +func GetUserIdsByUserNames(names []string) []int64 { + pageSize := 200 + length := len(names) + r := make([]int64, 0, length) + for i := 0; i < length; i = i + pageSize { + if length-i < 200 { + pageSize = length - i + } + userNameTemp := names[i : i+pageSize] + t := make([]int64, 0, length) + err := x.Table("public.user").Cols("id").In("name", userNameTemp).Find(&t) + if err != nil { + continue + } + r = append(r, t...) + + } + return r +} diff --git a/models/user_medal.go b/models/user_medal.go deleted file mode 100644 index a4421df13..000000000 --- a/models/user_medal.go +++ /dev/null @@ -1,10 +0,0 @@ -package models - -import "code.gitea.io/gitea/modules/timeutil" - -type UserMedal struct { - ID int64 `xorm:"pk autoincr"` - UserId int64 `xorm:"index"` - MedalId int64 `xorm:"index"` - CreatedUnix timeutil.TimeStamp `xorm:"created"` -} diff --git a/routers/badge/badge.go b/routers/badge/badge.go new file mode 100644 index 000000000..c62c1ee74 --- /dev/null +++ b/routers/badge/badge.go @@ -0,0 +1,98 @@ +package badge + +import ( + "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/routers/response" + "code.gitea.io/gitea/services/badge" + "errors" + "net/http" + "strings" +) + +func GetCustomizeBadgeList(ctx *context.Context) { + r, err := badge.GetBadgeList(models.GetBadgeOpts{BadgeType: models.CustomizeBadge}) + if err != nil { + log.Error("GetCustomizeBadgeList error.%v", err) + ctx.JSON(http.StatusOK, response.ServerError(err.Error())) + return + } + m := make(map[string]interface{}) + m["List"] = r + ctx.JSON(http.StatusOK, response.SuccessWithData(m)) +} + +func OperateBadge(ctx *context.Context, category models.Badge4AdminShow) { + action := ctx.Params(":action") + + var err error + switch action { + case "edit": + err = badge.EditBadge(category, ctx.User) + case "new": + err = badge.AddBadge(category, ctx.User) + case "del": + err = badge.DelBadge(category.ID, ctx.User) + default: + err = errors.New("action type error") + } + + if err != nil { + log.Error("OperateBadge error ,%v", err) + ctx.JSON(http.StatusOK, response.ServerError(err.Error())) + return + } + ctx.JSON(http.StatusOK, response.Success()) +} + +func GetBadgeUsers(ctx *context.Context) { + page := ctx.QueryInt("page") + badgeId := ctx.QueryInt64("badge") + r, err := badge.GetBadgeUsers(badgeId, models.ListOptions{PageSize: 20, Page: page}) + if err != nil { + log.Error("GetBadgeUsers error.%v", err) + ctx.JSON(http.StatusOK, response.ServerError(err.Error())) + return + } + m := make(map[string]interface{}) + m["List"] = r + ctx.JSON(http.StatusOK, response.SuccessWithData(m)) +} + +func AddOperateBadgeUsers(ctx *context.Context, req models.AddBadgeUsersReq) { + userStr := req.Users + if userStr == "" { + ctx.JSON(http.StatusOK, response.Success()) + return + } + userStr = strings.ReplaceAll(userStr, " ", "") + userStr = strings.ReplaceAll(userStr, "\r", "") + userNames := strings.Split(userStr, "\n") + n, err := badge.AddBadgeUsers(req.BadgeId, userNames) + if err != nil { + log.Error("AddOperateBadgeUsers error.%v", err) + ctx.JSON(http.StatusOK, response.ServerError(err.Error())) + return + } + m := make(map[string]interface{}) + m["Total"] = len(userNames) + m["Success"] = n + ctx.JSON(http.StatusOK, response.SuccessWithData(m)) +} + +func DelBadgeUsers(ctx *context.Context, req models.DelBadgeUserReq) { + id := req.ID + if id <= 0 { + ctx.JSON(http.StatusOK, response.Success()) + return + } + + err := badge.DelBadgeUser(id) + if err != nil { + log.Error("DelBadgeUsers error.%v", err) + ctx.JSON(http.StatusOK, response.ServerError(err.Error())) + return + } + ctx.JSON(http.StatusOK, response.Success()) +} diff --git a/routers/medal/category.go b/routers/badge/category.go similarity index 62% rename from routers/medal/category.go rename to routers/badge/category.go index b010af586..a386f8fc5 100644 --- a/routers/medal/category.go +++ b/routers/badge/category.go @@ -1,17 +1,17 @@ -package medal +package badge import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/routers/response" - "code.gitea.io/gitea/services/medal" + "code.gitea.io/gitea/services/badge" "errors" "net/http" ) -func GetCategoryList(ctx *context.Context) { - r, err := medal.GetMedalCategoryList() +func GetBadgeCategoryList(ctx *context.Context) { + r, err := badge.GetBadgeCategoryList() if err != nil { log.Error("GetCategoryList error.%v", err) ctx.JSON(http.StatusOK, response.ServerError(err.Error())) @@ -22,23 +22,23 @@ func GetCategoryList(ctx *context.Context) { ctx.JSON(http.StatusOK, response.SuccessWithData(m)) } -func OperateMedalCategory(ctx *context.Context, category models.MedalCategory4Show) { +func OperateBadgeCategory(ctx *context.Context, category models.BadgeCategory4Show) { action := ctx.Params(":action") var err error switch action { case "edit": - err = medal.EditMedalCategory(category, ctx.User) + err = badge.EditBadgeCategory(category, ctx.User) case "new": - err = medal.AddMedalCategory(category, ctx.User) + err = badge.AddBadgeCategory(category, ctx.User) case "del": - err = medal.DelMedalCategory(category.ID, ctx.User) + err = badge.DelBadgeCategory(category.ID, ctx.User) default: err = errors.New("action type error") } if err != nil { - log.Error("OperateMedalCategory error ,%v", err) + log.Error("OperateBadgeCategory error ,%v", err) ctx.JSON(http.StatusOK, response.ServerError(err.Error())) return } diff --git a/routers/medal/medal.go b/routers/medal/medal.go deleted file mode 100644 index d0625a2b4..000000000 --- a/routers/medal/medal.go +++ /dev/null @@ -1,46 +0,0 @@ -package medal - -import ( - "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/context" - "code.gitea.io/gitea/modules/log" - "code.gitea.io/gitea/routers/response" - "code.gitea.io/gitea/services/medal" - "errors" - "net/http" -) - -func GetCustomizeMedalList(ctx *context.Context) { - r, err := medal.GetMedalList(models.GetMedalOpts{MedalType: models.CustomizeMedal}) - if err != nil { - log.Error("GetCategoryList error.%v", err) - ctx.JSON(http.StatusOK, response.ServerError(err.Error())) - return - } - m := make(map[string]interface{}) - m["List"] = r - ctx.JSON(http.StatusOK, response.SuccessWithData(m)) -} - -func OperateMedal(ctx *context.Context, category models.Medal4Show) { - action := ctx.Params(":action") - - var err error - switch action { - case "edit": - err = medal.EditMedal(category, ctx.User) - case "new": - err = medal.AddMedal(category, ctx.User) - case "del": - err = medal.DelMedal(category.ID, ctx.User) - default: - err = errors.New("action type error") - } - - if err != nil { - log.Error("OperateCustomizeMedal error ,%v", err) - ctx.JSON(http.StatusOK, response.ServerError(err.Error())) - return - } - ctx.JSON(http.StatusOK, response.Success()) -} diff --git a/routers/routes/routes.go b/routers/routes/routes.go index 5830edfdc..14f2d0f74 100755 --- a/routers/routes/routes.go +++ b/routers/routes/routes.go @@ -6,7 +6,7 @@ package routes import ( "bytes" - "code.gitea.io/gitea/routers/medal" + "code.gitea.io/gitea/routers/badge" "code.gitea.io/gitea/routers/reward/point" "code.gitea.io/gitea/routers/task" "code.gitea.io/gitea/services/reward" @@ -663,15 +663,21 @@ func RegisterRoutes(m *macaron.Macaron) { m.Post("/^:action(new|edit|del)$", bindIgnErr(models.TaskConfigWithLimit{}), task.OperateTaskConfig) }) - m.Group("/medal", func() { + m.Group("/badge", func() { m.Group("/category", func() { - m.Get("/list", medal.GetCategoryList) - m.Post("/^:action(new|edit|del)$", bindIgnErr(models.MedalCategory4Show{}), medal.OperateMedalCategory) + m.Get("/list", badge.GetBadgeCategoryList) + m.Post("/^:action(new|edit|del)$", bindIgnErr(models.BadgeCategory4Show{}), badge.OperateBadgeCategory) }) m.Group("/customize", func() { - m.Get("/list", medal.GetCustomizeMedalList) + m.Get("/list", badge.GetCustomizeBadgeList) + + }) + m.Group("/users", func() { + m.Get("", badge.GetBadgeUsers) + m.Post("/add", bindIgnErr(models.AddBadgeUsersReq{}), badge.AddOperateBadgeUsers) + m.Post("/del", bindIgnErr(models.DelBadgeUserReq{}), badge.DelBadgeUsers) }) - m.Post("/^:action(new|edit|del)$", bindIgnErr(models.Medal4Show{}), medal.OperateMedal) + m.Post("/^:action(new|edit|del)$", bindIgnErr(models.Badge4AdminShow{}), badge.OperateBadge) }) }, operationReq) diff --git a/routers/user/profile.go b/routers/user/profile.go index 42cdfd1a8..1d275c191 100755 --- a/routers/user/profile.go +++ b/routers/user/profile.go @@ -6,6 +6,7 @@ package user import ( + "code.gitea.io/gitea/services/badge" "errors" "fmt" "path" @@ -90,10 +91,18 @@ func Profile(ctx *context.Context) { return } + // Show user badges + badges, err := badge.GetUserBadges(ctxUser.ID, models.ListOptions{Page: 1, PageSize: 5}) + if err != nil { + ctx.ServerError("GetUserBadges", err) + return + } + ctx.Data["Title"] = ctxUser.DisplayName() ctx.Data["PageIsUserProfile"] = true ctx.Data["Owner"] = ctxUser ctx.Data["OpenIDs"] = openIDs + ctx.Data["RecentBadges"] = badges ctx.Data["EnableHeatmap"] = setting.Service.EnableUserHeatmap ctx.Data["HeatmapUser"] = ctxUser.Name showPrivate := ctx.IsSigned && (ctx.User.IsAdmin || ctx.User.ID == ctxUser.ID) @@ -297,6 +306,13 @@ func Profile(ctx *context.Context) { } total = int(count) + case "badge": + allBadges, err := badge.GetUserAllBadges(ctxUser.ID) + if err != nil { + ctx.ServerError("GetUserAllBadges", err) + return + } + ctx.Data["AllBadges"] = allBadges default: ctx.ServerError("tab error", errors.New("tab error")) return diff --git a/services/admin/operate_log/operate_log.go b/services/admin/operate_log/operate_log.go index 7f966db0c..f52950351 100644 --- a/services/admin/operate_log/operate_log.go +++ b/services/admin/operate_log/operate_log.go @@ -7,8 +7,8 @@ import ( type LogBizType string const ( - MedalCategoryOperate LogBizType = "MedalCategoryOperate" - MedalOperate LogBizType = "MedalOperate" + BadgeCategoryOperate LogBizType = "BadgeCategoryOperate" + BadgeOperate LogBizType = "BadgeOperate" ) func Log(log models.AdminOperateLog) error { diff --git a/services/badge/badge.go b/services/badge/badge.go new file mode 100644 index 000000000..83c3581b5 --- /dev/null +++ b/services/badge/badge.go @@ -0,0 +1,64 @@ +package badge + +import ( + "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/services/admin/operate_log" + "errors" +) + +func GetBadgeList(opts models.GetBadgeOpts) ([]*models.Badge4AdminShow, error) { + list, err := models.GetBadgeList(opts) + if err != nil { + return nil, err + } + if len(list) == 0 { + return nil, nil + } + r := make([]*models.Badge4AdminShow, len(list)) + for i := 0; i < len(list); i++ { + r[i] = list[i].ToShow() + } + + return r, nil +} + +func AddBadge(m models.Badge4AdminShow, doer *models.User) error { + _, err := models.AddBadge(m.ToDTO()) + if err != nil { + return err + } + operate_log.Log4Add(operate_log.BadgeOperate, m, doer.ID, "新增了勋章") + return nil +} + +func EditBadge(m models.Badge4AdminShow, doer *models.User) error { + if m.ID == 0 { + log.Error(" EditBadge param error") + return errors.New("param error") + } + old, err := models.GetBadgeById(m.ID) + if err != nil { + return err + } + _, err = models.UpdateBadgeById(m.ID, m.ToDTO()) + if err != nil { + return err + } + operate_log.Log4Edit(operate_log.BadgeOperate, old, m.ToDTO(), doer.ID, "修改了勋章") + return err +} + +func DelBadge(id int64, doer *models.User) error { + if id == 0 { + log.Error(" DelBadge param error") + return errors.New("param error") + } + old, err := models.GetBadgeById(id) + if err != nil { + return err + } + _, err = models.DelBadge(id) + operate_log.Log4Del(operate_log.BadgeOperate, old, doer.ID, "删除了勋章") + return err +} diff --git a/services/badge/category.go b/services/badge/category.go new file mode 100644 index 000000000..316e654a7 --- /dev/null +++ b/services/badge/category.go @@ -0,0 +1,64 @@ +package badge + +import ( + "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/services/admin/operate_log" + "errors" +) + +func GetBadgeCategoryList() ([]*models.BadgeCategory4Show, error) { + list, err := models.GetBadgeCategoryList() + if err != nil { + return nil, err + } + if len(list) == 0 { + return nil, nil + } + r := make([]*models.BadgeCategory4Show, len(list)) + for i := 0; i < len(list); i++ { + r[i] = list[i].ToShow() + } + + return r, nil +} + +func AddBadgeCategory(m models.BadgeCategory4Show, doer *models.User) error { + _, err := models.AddBadgeCategory(m.ToDTO()) + if err != nil { + return err + } + operate_log.Log4Add(operate_log.BadgeCategoryOperate, m, doer.ID, "新增了勋章分类") + return nil +} + +func EditBadgeCategory(m models.BadgeCategory4Show, doer *models.User) error { + if m.ID == 0 { + log.Error(" EditBadgeCategory param error") + return errors.New("param error") + } + old, err := models.GetBadgeCategoryById(m.ID) + if err != nil { + return err + } + _, err = models.UpdateBadgeCategoryById(m.ID, m.ToDTO()) + if err != nil { + return err + } + operate_log.Log4Edit(operate_log.BadgeCategoryOperate, old, m.ToDTO(), doer.ID, "修改了勋章分类") + return err +} + +func DelBadgeCategory(id int64, doer *models.User) error { + if id == 0 { + log.Error(" DelBadgeCategory param error") + return errors.New("param error") + } + old, err := models.GetBadgeCategoryById(id) + if err != nil { + return err + } + _, err = models.DelBadgeCategory(id) + operate_log.Log4Del(operate_log.BadgeCategoryOperate, old, doer.ID, "删除了勋章分类") + return err +} diff --git a/services/badge/user.go b/services/badge/user.go new file mode 100644 index 000000000..ccc112f01 --- /dev/null +++ b/services/badge/user.go @@ -0,0 +1,104 @@ +package badge + +import ( + "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/log" +) + +func GetBadgeUsers(badgeId int64, opts models.ListOptions) ([]*models.BadgeUser4SHow, error) { + list, err := models.GetBadgeUsers(badgeId, opts) + if err != nil { + return nil, err + } + if len(list) == 0 { + return nil, nil + } + r := make([]*models.BadgeUser4SHow, len(list)) + for i := 0; i < len(list); i++ { + r[i] = list[i].ToShow() + } + + return r, nil +} + +func AddBadgeUsers(badgeId int64, userNames []string) (int, error) { + userIds := models.GetUserIdsByUserNames(userNames) + if len(userIds) == 0 { + return 0, nil + } + successCount := 0 + for _, v := range userIds { + m := models.BadgeUser{ + UserId: v, + BadgeId: badgeId, + } + _, err := models.AddBadgeUser(m) + if err != nil { + log.Error("AddBadgeUser err in loop, m=%+v. e=%v", m, err) + continue + } + successCount++ + } + return successCount, nil +} + +func DelBadgeUser(id int64) error { + _, err := models.DelBadgeUser(id) + return err +} + +//GetUserBadges Only Returns badges the user has earned +func GetUserBadges(userId int64, opts models.ListOptions) ([]*models.Badge4UserShow, error) { + badges, err := models.GetUserBadges(userId, models.GetUserBadgesOpts{ListOptions: opts}) + if err != nil { + return nil, err + } + r := make([]*models.Badge4UserShow, len(badges)) + for i, v := range badges { + r[i] = v.ToUserShow() + } + return r, nil +} + +func GetUserAllBadges(userId int64) ([]models.UserAllBadgeInCategory, error) { + categoryList, err := models.GetBadgeCategoryList() + if err != nil { + return nil, err + } + r := make([]models.UserAllBadgeInCategory, len(categoryList)) + for i, v := range categoryList { + badges, err := models.GetBadgeByCategoryId(v.ID) + userBadgeMap, err := getUserBadgesMap(userId, v.ID, 100, 1) + if err != nil { + return nil, err + } + t := models.UserAllBadgeInCategory{ + CategoryName: v.Name, + CategoryId: v.ID, + LightedNum: len(userBadgeMap), + } + bArray := make([]*models.BadgeShowWithStatus, len(badges)) + for j, v := range badges { + b := &models.BadgeShowWithStatus{Badge: v.ToUserShow()} + if _, has := userBadgeMap[v.ID]; has { + b.IsLighted = true + } + bArray[j] = b + } + t.Badges = bArray + r[i] = t + } + return r, nil +} + +func getUserBadgesMap(userId, categoryId int64, pageSize, page int) (map[int64]*models.Badge, error) { + userBadges, err := models.GetUserBadges(userId, models.GetUserBadgesOpts{ListOptions: models.ListOptions{PageSize: pageSize, Page: page}, CategoryId: categoryId}) + if err != nil { + return nil, err + } + m := make(map[int64]*models.Badge, 0) + for _, v := range userBadges { + m[v.ID] = v + } + return m, nil +} diff --git a/services/medal/category.go b/services/medal/category.go deleted file mode 100644 index 50f1b804e..000000000 --- a/services/medal/category.go +++ /dev/null @@ -1,64 +0,0 @@ -package medal - -import ( - "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/log" - "code.gitea.io/gitea/services/admin/operate_log" - "errors" -) - -func GetMedalCategoryList() ([]*models.MedalCategory4Show, error) { - list, err := models.GetMedalCategoryList() - if err != nil { - return nil, err - } - if len(list) == 0 { - return nil, nil - } - r := make([]*models.MedalCategory4Show, len(list)) - for i := 0; i < len(list); i++ { - r[i] = list[i].ToShow() - } - - return r, nil -} - -func AddMedalCategory(m models.MedalCategory4Show, doer *models.User) error { - _, err := models.AddMedalCategory(m.ToDTO()) - if err != nil { - return err - } - operate_log.Log4Add(operate_log.MedalCategoryOperate, m, doer.ID, "新增了勋章分类") - return nil -} - -func EditMedalCategory(m models.MedalCategory4Show, doer *models.User) error { - if m.ID == 0 { - log.Error(" EditMedalCategory param error") - return errors.New("param error") - } - old, err := models.GetMedalCategoryById(m.ID) - if err != nil { - return err - } - _, err = models.UpdateMedalCategoryById(m.ID, m.ToDTO()) - if err != nil { - return err - } - operate_log.Log4Edit(operate_log.MedalCategoryOperate, old, m.ToDTO(), doer.ID, "修改了勋章分类") - return err -} - -func DelMedalCategory(id int64, doer *models.User) error { - if id == 0 { - log.Error(" DelMedalCategory param error") - return errors.New("param error") - } - old, err := models.GetMedalCategoryById(id) - if err != nil { - return err - } - _, err = models.DelMedalCategory(id) - operate_log.Log4Del(operate_log.MedalCategoryOperate, old, doer.ID, "删除了勋章分类") - return err -} diff --git a/services/medal/medal.go b/services/medal/medal.go deleted file mode 100644 index 967d7011f..000000000 --- a/services/medal/medal.go +++ /dev/null @@ -1,64 +0,0 @@ -package medal - -import ( - "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/log" - "code.gitea.io/gitea/services/admin/operate_log" - "errors" -) - -func GetMedalList(opts models.GetMedalOpts) ([]*models.Medal4Show, error) { - list, err := models.GetMedalList(opts) - if err != nil { - return nil, err - } - if len(list) == 0 { - return nil, nil - } - r := make([]*models.Medal4Show, len(list)) - for i := 0; i < len(list); i++ { - r[i] = list[i].ToShow() - } - - return r, nil -} - -func AddMedal(m models.Medal4Show, doer *models.User) error { - _, err := models.AddMedal(m.ToDTO()) - if err != nil { - return err - } - operate_log.Log4Add(operate_log.MedalOperate, m, doer.ID, "新增了勋章") - return nil -} - -func EditMedal(m models.Medal4Show, doer *models.User) error { - if m.ID == 0 { - log.Error(" EditMedal param error") - return errors.New("param error") - } - old, err := models.GetMedalById(m.ID) - if err != nil { - return err - } - _, err = models.UpdateMedalById(m.ID, m.ToDTO()) - if err != nil { - return err - } - operate_log.Log4Edit(operate_log.MedalOperate, old, m.ToDTO(), doer.ID, "修改了勋章") - return err -} - -func DelMedal(id int64, doer *models.User) error { - if id == 0 { - log.Error(" DelMedal param error") - return errors.New("param error") - } - old, err := models.GetMedalById(id) - if err != nil { - return err - } - _, err = models.DelMedal(id) - operate_log.Log4Del(operate_log.MedalOperate, old, doer.ID, "删除了勋章") - return err -} From 9300604644d4b8f90ac9433959d1d3c3c961e985 Mon Sep 17 00:00:00 2001 From: chenyifan01 Date: Mon, 10 Oct 2022 17:00:21 +0800 Subject: [PATCH 03/29] #2908 1.add icon upload api 2.fix bug --- models/badge.go | 58 ++++++++++++++++++++---- models/badge_category.go | 17 ++++++- models/badge_user.go | 32 +++++++++---- modules/setting/setting.go | 15 +++++++ routers/badge/badge.go | 48 +++++++++++++++++--- routers/badge/category.go | 6 ++- routers/routes/routes.go | 16 +++++-- routers/user/profile.go | 6 +++ services/badge/badge.go | 24 ++++++---- services/badge/category.go | 10 ++--- services/badge/icon.go | 109 +++++++++++++++++++++++++++++++++++++++++++++ services/badge/user.go | 21 +++++---- 12 files changed, 312 insertions(+), 50 deletions(-) create mode 100644 services/badge/icon.go diff --git a/models/badge.go b/models/badge.go index 20e3ea66a..7e20ab2d4 100644 --- a/models/badge.go +++ b/models/badge.go @@ -1,7 +1,10 @@ package models import ( + "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/timeutil" + "path/filepath" + "strings" "xorm.io/builder" ) @@ -20,14 +23,15 @@ type Badge struct { func (m *Badge) ToUserShow() *Badge4UserShow { return &Badge4UserShow{ Name: m.Name, - LightedIcon: m.LightedIcon, - GreyedIcon: m.GreyedIcon, + LightedIcon: GetIconOuterLink(m.LightedIcon), + GreyedIcon: GetIconOuterLink(m.GreyedIcon), Url: m.Url, } } type GetBadgeOpts struct { BadgeType BadgeType + LO ListOptions } type BadgeAndCategory struct { @@ -43,8 +47,8 @@ func (m *BadgeAndCategory) ToShow() *Badge4AdminShow { return &Badge4AdminShow{ ID: m.Badge.ID, Name: m.Badge.Name, - LightedIcon: m.Badge.LightedIcon, - GreyedIcon: m.Badge.GreyedIcon, + LightedIcon: GetIconOuterLink(m.Badge.LightedIcon), + GreyedIcon: GetIconOuterLink(m.Badge.GreyedIcon), Url: m.Badge.Url, CategoryName: m.Category.Name, CategoryId: m.Category.ID, @@ -75,6 +79,25 @@ func (m Badge4AdminShow) ToDTO() Badge { } } +type BadgeOperateReq struct { + ID int64 + Name string + LightedIcon string + GreyedIcon string + Url string + CategoryId int64 +} + +func (m BadgeOperateReq) ToDTO() Badge { + return Badge{ + Name: m.Name, + LightedIcon: m.LightedIcon, + GreyedIcon: m.GreyedIcon, + Url: m.Url, + CategoryId: m.CategoryId, + } +} + type Badge4UserShow struct { Name string LightedIcon string @@ -94,17 +117,23 @@ type UserAllBadgeInCategory struct { Badges []*BadgeShowWithStatus } -func GetBadgeList(opts GetBadgeOpts) ([]*BadgeAndCategory, error) { +func GetBadgeList(opts GetBadgeOpts) (int64, []*BadgeAndCategory, error) { + if opts.LO.Page <= 0 { + opts.LO.Page = 1 + } var cond = builder.NewCond() if opts.BadgeType > 0 { cond = cond.And(builder.Eq{"badge_category.type": opts.BadgeType}) } - + n, err := x.Join("INNER", "badge_category", "badge_category.ID = badge.category_id").Where(cond).Count(&BadgeAndCategory{}) + if err != nil { + return 0, nil, err + } r := make([]*BadgeAndCategory, 0) - if err := x.Join("INNER", "badge_category", "badge_category.ID = badge.category_id").Where(cond).OrderBy("badge.created_unix desc").Find(&r); err != nil { - return nil, err + if err = x.Join("INNER", "badge_category", "badge_category.ID = badge.category_id").Where(cond).OrderBy("badge.created_unix desc").Limit(opts.LO.PageSize, (opts.LO.Page-1)*opts.LO.PageSize).Find(&r); err != nil { + return 0, nil, err } - return r, nil + return n, r, nil } func AddBadge(m Badge) (int64, error) { @@ -135,3 +164,14 @@ func GetBadgeByCategoryId(categoryId int64) ([]*Badge, error) { err := x.Where("category_id = ?", categoryId).Find(&r) return r, err } + +func GetCustomIconByHash(hash string) string { + if len(hash) == 0 { + return "" + } + return filepath.Join(setting.IconUploadPath, hash) +} + +func GetIconOuterLink(hash string) string { + return strings.TrimRight(setting.AppSubURL, "/") + "/show/icon/" + hash +} diff --git a/models/badge_category.go b/models/badge_category.go index e8f90f6c1..069fb6b10 100644 --- a/models/badge_category.go +++ b/models/badge_category.go @@ -47,6 +47,21 @@ func (m BadgeCategory4Show) ToDTO() BadgeCategory { } } +func GetBadgeCategoryListPaging(opts ListOptions) (int64, []*BadgeCategory, error) { + n, err := x.Count(&BadgeCategory{}) + if err != nil { + return 0, nil, err + } + if opts.Page <= 0 { + opts.Page = 1 + } + r := make([]*BadgeCategory, 0) + if err := x.OrderBy("position asc,created_unix desc").Limit(opts.PageSize, (opts.Page-1)*opts.PageSize).Find(&r); err != nil { + return 0, nil, err + } + return n, r, nil +} + func GetBadgeCategoryList() ([]*BadgeCategory, error) { r := make([]*BadgeCategory, 0) if err := x.OrderBy("position asc,created_unix desc").Find(&r); err != nil { @@ -73,7 +88,7 @@ func GetBadgeCategoryById(id int64) (*BadgeCategory, error) { if err != nil { return nil, err } else if !has { - return nil, &ErrRecordNotExist{} + return nil, ErrRecordNotExist{} } return m, nil } diff --git a/models/badge_user.go b/models/badge_user.go index b2428ab1a..32861248e 100644 --- a/models/badge_user.go +++ b/models/badge_user.go @@ -12,8 +12,8 @@ const ( type BadgeUser struct { ID int64 `xorm:"pk autoincr"` - UserId int64 `xorm:"unique(user_id,badge_id)"` - BadgeId int64 `xorm:"index"` + UserId int64 `xorm:"unique(user_badge)"` + BadgeId int64 `xorm:"unique(user_badge) index"` CreatedUnix timeutil.TimeStamp `xorm:"created index"` } @@ -115,19 +115,23 @@ func DelBadgeUser(id int64) (int64, error) { return n, sess.Commit() } -func GetBadgeUsers(badgeId int64, opts ListOptions) ([]BadgeUserDetail, error) { +func GetBadgeUsers(badgeId int64, opts ListOptions) (int64, []BadgeUserDetail, error) { + n, err := x.Join("LEFT", "public.user", "public.user.ID = badge_user.user_id").Where("badge_user.badge_id = ?", badgeId).Count(&BadgeUserDetail{}) + if err != nil { + return 0, nil, err + } if opts.Page <= 0 { opts.Page = 1 } m := make([]BadgeUserDetail, 0) - err := x.Join("LEFT", "public.user", "public.user.ID = badge_user.user_id").Where("badge_user.badge_id = ?", badgeId).OrderBy("badge_user.created_unix desc").Limit(opts.PageSize, (opts.Page-1)*opts.PageSize).Find(&m) + err = x.Join("LEFT", "public.user", "public.user.ID = badge_user.user_id").Where("badge_user.badge_id = ?", badgeId).OrderBy("badge_user.id desc").Limit(opts.PageSize, (opts.Page-1)*opts.PageSize).Find(&m) if err != nil { - return nil, err + return 0, nil, err } - return m, nil + return n, m, nil } -func GetUserBadges(userId int64, opts GetUserBadgesOpts) ([]*Badge, error) { +func GetUserBadgesPaging(userId int64, opts GetUserBadgesOpts) ([]*Badge, error) { cond := builder.NewCond() cond = cond.And(builder.Eq{"badge_user.user_id": userId}) if opts.CategoryId > 0 { @@ -135,6 +139,18 @@ func GetUserBadges(userId int64, opts GetUserBadgesOpts) ([]*Badge, error) { } r := make([]*Badge, 0) - err := x.Join("INNER", "badge_user", "badge_user.badge_id = badge.id").Where(cond).OrderBy("badge_user.created_unix desc").Limit(opts.PageSize, (opts.Page-1)*opts.PageSize).Find(&r) + err := x.Join("INNER", "badge_user", "badge_user.badge_id = badge.id").Where(cond).OrderBy("badge_user.id desc").Limit(opts.PageSize, (opts.Page-1)*opts.PageSize).Find(&r) + return r, err +} + +func GetUserBadges(userId, categoryId int64) ([]*Badge, error) { + cond := builder.NewCond() + cond = cond.And(builder.Eq{"badge_user.user_id": userId}) + if categoryId > 0 { + cond = cond.And(builder.Eq{"badge.category_id": categoryId}) + } + + r := make([]*Badge, 0) + err := x.Join("INNER", "badge_user", "badge_user.badge_id = badge.id").Where(cond).OrderBy("badge_user.created_unix desc").Find(&r) return r, err } diff --git a/modules/setting/setting.go b/modules/setting/setting.go index d6e4824ef..00b0245f6 100755 --- a/modules/setting/setting.go +++ b/modules/setting/setting.go @@ -622,6 +622,13 @@ var ( DeductTaskRange time.Duration DeductTaskRangeForFirst time.Duration + //badge config + BadgeIconMaxFileSize int64 + BadgeIconMaxWidth int + BadgeIconMaxHeight int + BadgeIconDefaultSize uint + IconUploadPath string + //wechat auto reply config UserNameOfWechatReply string RepoNameOfWechatReply string @@ -1515,6 +1522,14 @@ func NewContext() { CloudBrainPayInterval = sec.Key("CLOUDBRAIN_PAY_INTERVAL").MustDuration(60 * time.Minute) DeductTaskRange = sec.Key("DEDUCT_TASK_RANGE").MustDuration(30 * time.Minute) DeductTaskRangeForFirst = sec.Key("DEDUCT_TASK_RANGE_FOR_FIRST").MustDuration(3 * time.Hour) + + sec = Cfg.Section("icons") + BadgeIconMaxFileSize = sec.Key("BADGE_ICON_MAX_FILE_SIZE").MustInt64(1048576) + BadgeIconMaxWidth = sec.Key("BADGE_ICON_MAX_WIDTH").MustInt(4096) + BadgeIconMaxHeight = sec.Key("BADGE_ICON_MAX_HEIGHT").MustInt(3072) + BadgeIconDefaultSize = sec.Key("BADGE_ICON_DEFAULT_SIZE").MustUint(200) + IconUploadPath = sec.Key("ICON_UPLOAD_PATH").MustString(path.Join(AppDataPath, "icons")) + SetRadarMapConfig() sec = Cfg.Section("warn_mail") diff --git a/routers/badge/badge.go b/routers/badge/badge.go index c62c1ee74..5344b4e39 100644 --- a/routers/badge/badge.go +++ b/routers/badge/badge.go @@ -4,15 +4,19 @@ import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/routers/response" "code.gitea.io/gitea/services/badge" "errors" + "github.com/unknwon/com" "net/http" "strings" ) func GetCustomizeBadgeList(ctx *context.Context) { - r, err := badge.GetBadgeList(models.GetBadgeOpts{BadgeType: models.CustomizeBadge}) + page := ctx.QueryInt("page") + pageSize := 50 + n, r, err := badge.GetBadgeList(models.GetBadgeOpts{BadgeType: models.CustomizeBadge, LO: models.ListOptions{PageSize: pageSize, Page: page}}) if err != nil { log.Error("GetCustomizeBadgeList error.%v", err) ctx.JSON(http.StatusOK, response.ServerError(err.Error())) @@ -20,20 +24,22 @@ func GetCustomizeBadgeList(ctx *context.Context) { } m := make(map[string]interface{}) m["List"] = r + m["Total"] = n + m["PageSize"] = pageSize ctx.JSON(http.StatusOK, response.SuccessWithData(m)) } -func OperateBadge(ctx *context.Context, category models.Badge4AdminShow) { +func OperateBadge(ctx *context.Context, req models.BadgeOperateReq) { action := ctx.Params(":action") var err error switch action { case "edit": - err = badge.EditBadge(category, ctx.User) + err = badge.EditBadge(req, ctx.User) case "new": - err = badge.AddBadge(category, ctx.User) + err = badge.AddBadge(req, ctx.User) case "del": - err = badge.DelBadge(category.ID, ctx.User) + err = badge.DelBadge(req.ID, ctx.User) default: err = errors.New("action type error") } @@ -49,7 +55,8 @@ func OperateBadge(ctx *context.Context, category models.Badge4AdminShow) { func GetBadgeUsers(ctx *context.Context) { page := ctx.QueryInt("page") badgeId := ctx.QueryInt64("badge") - r, err := badge.GetBadgeUsers(badgeId, models.ListOptions{PageSize: 20, Page: page}) + pageSize := 50 + n, r, err := badge.GetBadgeUsers(badgeId, models.ListOptions{PageSize: pageSize, Page: page}) if err != nil { log.Error("GetBadgeUsers error.%v", err) ctx.JSON(http.StatusOK, response.ServerError(err.Error())) @@ -57,6 +64,8 @@ func GetBadgeUsers(ctx *context.Context) { } m := make(map[string]interface{}) m["List"] = r + m["Total"] = n + m["PageSize"] = pageSize ctx.JSON(http.StatusOK, response.SuccessWithData(m)) } @@ -96,3 +105,30 @@ func DelBadgeUsers(ctx *context.Context, req models.DelBadgeUserReq) { } ctx.JSON(http.StatusOK, response.Success()) } + +func UploadIcon(ctx *context.Context, form badge.IconUploadForm) { + + uploader := badge.NewIconUploader(badge.IconUploadConfig{ + FileMaxSize: setting.BadgeIconMaxFileSize, + FileMaxWidth: setting.BadgeIconMaxWidth, + FileMaxHeight: setting.BadgeIconMaxHeight, + }) + iconName, err := uploader.Upload(form, ctx.User) + if err != nil { + log.Error("UploadIcon error.%v", err) + ctx.JSON(http.StatusOK, response.ServerError(err.Error())) + return + } + m := make(map[string]string, 0) + m["IconName"] = iconName + ctx.JSON(http.StatusOK, response.SuccessWithData(m)) +} + +func GetIcon(ctx *context.Context) { + hash := ctx.Params(":hash") + if !com.IsFile(models.GetCustomIconByHash(hash)) { + ctx.NotFound(ctx.Req.URL.RequestURI(), nil) + return + } + ctx.Redirect(setting.AppSubURL + "/icons/" + hash) +} diff --git a/routers/badge/category.go b/routers/badge/category.go index a386f8fc5..4ac85df4a 100644 --- a/routers/badge/category.go +++ b/routers/badge/category.go @@ -11,7 +11,9 @@ import ( ) func GetBadgeCategoryList(ctx *context.Context) { - r, err := badge.GetBadgeCategoryList() + page := ctx.QueryInt("page") + pageSize := 50 + n, r, err := badge.GetBadgeCategoryList(models.ListOptions{Page: page, PageSize: pageSize}) if err != nil { log.Error("GetCategoryList error.%v", err) ctx.JSON(http.StatusOK, response.ServerError(err.Error())) @@ -19,6 +21,8 @@ func GetBadgeCategoryList(ctx *context.Context) { } m := make(map[string]interface{}) m["List"] = r + m["Total"] = n + m["PageSize"] = pageSize ctx.JSON(http.StatusOK, response.SuccessWithData(m)) } diff --git a/routers/routes/routes.go b/routers/routes/routes.go index 14f2d0f74..91b5690ad 100755 --- a/routers/routes/routes.go +++ b/routers/routes/routes.go @@ -9,6 +9,7 @@ import ( "code.gitea.io/gitea/routers/badge" "code.gitea.io/gitea/routers/reward/point" "code.gitea.io/gitea/routers/task" + badge_service "code.gitea.io/gitea/services/badge" "code.gitea.io/gitea/services/reward" "encoding/gob" "net/http" @@ -195,6 +196,14 @@ func NewMacaron() *macaron.Macaron { }, )) m.Use(public.StaticHandler( + setting.IconUploadPath, + &public.Options{ + Prefix: "icons", + SkipLogging: setting.DisableRouterLog, + ExpiresAfter: setting.StaticCacheTime, + }, + )) + m.Use(public.StaticHandler( setting.RepositoryAvatarUploadPath, &public.Options{ Prefix: "repo-avatars", @@ -518,6 +527,8 @@ func RegisterRoutes(m *macaron.Macaron) { m.Get("/avatar/:hash", user.AvatarByEmailHash) + m.Get("/show/icon/:hash", badge.GetIcon) + adminReq := context.Toggle(&context.ToggleOptions{SignInRequired: true, AdminRequired: true}) // ***** START: Admin ***** @@ -670,16 +681,15 @@ func RegisterRoutes(m *macaron.Macaron) { }) m.Group("/customize", func() { m.Get("/list", badge.GetCustomizeBadgeList) - }) m.Group("/users", func() { m.Get("", badge.GetBadgeUsers) m.Post("/add", bindIgnErr(models.AddBadgeUsersReq{}), badge.AddOperateBadgeUsers) m.Post("/del", bindIgnErr(models.DelBadgeUserReq{}), badge.DelBadgeUsers) }) - m.Post("/^:action(new|edit|del)$", bindIgnErr(models.Badge4AdminShow{}), badge.OperateBadge) + m.Post("/^:action(new|edit|del)$", bindIgnErr(models.BadgeOperateReq{}), badge.OperateBadge) }) - + m.Post("/icon/upload", bindIgnErr(badge_service.IconUploadForm{}), badge.UploadIcon) }, operationReq) // ***** END: Operation ***** diff --git a/routers/user/profile.go b/routers/user/profile.go index 1d275c191..8685cd734 100755 --- a/routers/user/profile.go +++ b/routers/user/profile.go @@ -6,7 +6,9 @@ package user import ( + "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/services/badge" + "encoding/json" "errors" "fmt" "path" @@ -103,6 +105,8 @@ func Profile(ctx *context.Context) { ctx.Data["Owner"] = ctxUser ctx.Data["OpenIDs"] = openIDs ctx.Data["RecentBadges"] = badges + b, _ := json.Marshal(badges) + log.Info(string(b)) ctx.Data["EnableHeatmap"] = setting.Service.EnableUserHeatmap ctx.Data["HeatmapUser"] = ctxUser.Name showPrivate := ctx.IsSigned && (ctx.User.IsAdmin || ctx.User.ID == ctxUser.ID) @@ -312,6 +316,8 @@ func Profile(ctx *context.Context) { ctx.ServerError("GetUserAllBadges", err) return } + ab, _ := json.Marshal(allBadges) + log.Info(string(ab)) ctx.Data["AllBadges"] = allBadges default: ctx.ServerError("tab error", errors.New("tab error")) diff --git a/services/badge/badge.go b/services/badge/badge.go index 83c3581b5..0aefeca6e 100644 --- a/services/badge/badge.go +++ b/services/badge/badge.go @@ -7,24 +7,32 @@ import ( "errors" ) -func GetBadgeList(opts models.GetBadgeOpts) ([]*models.Badge4AdminShow, error) { - list, err := models.GetBadgeList(opts) +func GetBadgeList(opts models.GetBadgeOpts) (int64, []*models.Badge4AdminShow, error) { + total, list, err := models.GetBadgeList(opts) if err != nil { - return nil, err + return 0, nil, err } if len(list) == 0 { - return nil, nil + return 0, nil, nil } r := make([]*models.Badge4AdminShow, len(list)) for i := 0; i < len(list); i++ { r[i] = list[i].ToShow() } - return r, nil + return total, r, nil } -func AddBadge(m models.Badge4AdminShow, doer *models.User) error { - _, err := models.AddBadge(m.ToDTO()) +func AddBadge(m models.BadgeOperateReq, doer *models.User) error { + _, err := models.GetBadgeCategoryById(m.CategoryId) + + if err != nil { + if models.IsErrRecordNotExist(err) { + return errors.New("badge category is not available") + } + return err + } + _, err = models.AddBadge(m.ToDTO()) if err != nil { return err } @@ -32,7 +40,7 @@ func AddBadge(m models.Badge4AdminShow, doer *models.User) error { return nil } -func EditBadge(m models.Badge4AdminShow, doer *models.User) error { +func EditBadge(m models.BadgeOperateReq, doer *models.User) error { if m.ID == 0 { log.Error(" EditBadge param error") return errors.New("param error") diff --git a/services/badge/category.go b/services/badge/category.go index 316e654a7..14d06620a 100644 --- a/services/badge/category.go +++ b/services/badge/category.go @@ -7,20 +7,20 @@ import ( "errors" ) -func GetBadgeCategoryList() ([]*models.BadgeCategory4Show, error) { - list, err := models.GetBadgeCategoryList() +func GetBadgeCategoryList(opts models.ListOptions) (int64, []*models.BadgeCategory4Show, error) { + total, list, err := models.GetBadgeCategoryListPaging(opts) if err != nil { - return nil, err + return 0, nil, err } if len(list) == 0 { - return nil, nil + return 0, nil, nil } r := make([]*models.BadgeCategory4Show, len(list)) for i := 0; i < len(list); i++ { r[i] = list[i].ToShow() } - return r, nil + return total, r, nil } func AddBadgeCategory(m models.BadgeCategory4Show, doer *models.User) error { diff --git a/services/badge/icon.go b/services/badge/icon.go new file mode 100644 index 000000000..ae7c25241 --- /dev/null +++ b/services/badge/icon.go @@ -0,0 +1,109 @@ +package badge + +import ( + "bytes" + "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/base" + "code.gitea.io/gitea/modules/setting" + "crypto/md5" + "errors" + "fmt" + "image" + "image/png" + "io/ioutil" + "mime/multipart" + "os" +) + +type IconUploader struct { + Config IconUploadConfig +} + +type IconUploadForm struct { + Icon *multipart.FileHeader +} + +type IconUploadConfig struct { + FileMaxSize int64 + FileMaxWidth int + FileMaxHeight int +} + +func NewIconUploader(config IconUploadConfig) IconUploader { + return IconUploader{Config: config} +} + +func (u IconUploader) Upload(form IconUploadForm, user *models.User) (string, error) { + if form.Icon == nil || form.Icon.Filename == "" { + return "", errors.New("File or fileName is empty") + } + + fr, err := form.Icon.Open() + if err != nil { + return "", fmt.Errorf("Icon.Open: %v", err) + } + defer fr.Close() + + if form.Icon.Size > u.Config.FileMaxSize { + return "", errors.New("File is too large") + } + + data, err := ioutil.ReadAll(fr) + if err != nil { + return "", fmt.Errorf("ioutil.ReadAll: %v", err) + } + if !base.IsImageFile(data) { + return "", errors.New("File is not a image") + } + iconName, err := u.uploadIcon(data, user.ID) + if err != nil { + return "", fmt.Errorf("uploadIcon: %v", err) + } + return iconName, nil + +} + +func (u IconUploader) uploadIcon(data []byte, userId int64) (string, error) { + m, err := u.prepare(data) + if err != nil { + return "", err + } + + iconName := fmt.Sprintf("%x", md5.Sum([]byte(fmt.Sprintf("%d-%x", userId, md5.Sum(data))))) + + if err := os.MkdirAll(setting.IconUploadPath, os.ModePerm); err != nil { + return "", fmt.Errorf("uploadIcon. Failed to create dir %s: %v", setting.AvatarUploadPath, err) + } + + fw, err := os.Create(models.GetCustomIconByHash(iconName)) + if err != nil { + return "", fmt.Errorf("Create: %v", err) + } + defer fw.Close() + + if err = png.Encode(fw, *m); err != nil { + return "", fmt.Errorf("Encode: %v", err) + } + + return iconName, nil +} + +func (u IconUploader) prepare(data []byte) (*image.Image, error) { + imgCfg, _, err := image.DecodeConfig(bytes.NewReader(data)) + if err != nil { + return nil, fmt.Errorf("DecodeConfig: %v", err) + } + if imgCfg.Width > u.Config.FileMaxWidth { + return nil, fmt.Errorf("Image width is too large: %d > %d", imgCfg.Width, setting.AvatarMaxWidth) + } + if imgCfg.Height > u.Config.FileMaxHeight { + return nil, fmt.Errorf("Image height is too large: %d > %d", imgCfg.Height, setting.AvatarMaxHeight) + } + + img, _, err := image.Decode(bytes.NewReader(data)) + if err != nil { + return nil, fmt.Errorf("Decode: %v", err) + } + + return &img, nil +} diff --git a/services/badge/user.go b/services/badge/user.go index ccc112f01..70fc7bba7 100644 --- a/services/badge/user.go +++ b/services/badge/user.go @@ -5,20 +5,20 @@ import ( "code.gitea.io/gitea/modules/log" ) -func GetBadgeUsers(badgeId int64, opts models.ListOptions) ([]*models.BadgeUser4SHow, error) { - list, err := models.GetBadgeUsers(badgeId, opts) +func GetBadgeUsers(badgeId int64, opts models.ListOptions) (int64, []*models.BadgeUser4SHow, error) { + total, list, err := models.GetBadgeUsers(badgeId, opts) if err != nil { - return nil, err + return 0, nil, err } if len(list) == 0 { - return nil, nil + return 0, nil, nil } r := make([]*models.BadgeUser4SHow, len(list)) for i := 0; i < len(list); i++ { r[i] = list[i].ToShow() } - return r, nil + return total, r, nil } func AddBadgeUsers(badgeId int64, userNames []string) (int, error) { @@ -49,7 +49,7 @@ func DelBadgeUser(id int64) error { //GetUserBadges Only Returns badges the user has earned func GetUserBadges(userId int64, opts models.ListOptions) ([]*models.Badge4UserShow, error) { - badges, err := models.GetUserBadges(userId, models.GetUserBadgesOpts{ListOptions: opts}) + badges, err := models.GetUserBadgesPaging(userId, models.GetUserBadgesOpts{ListOptions: opts}) if err != nil { return nil, err } @@ -68,7 +68,10 @@ func GetUserAllBadges(userId int64) ([]models.UserAllBadgeInCategory, error) { r := make([]models.UserAllBadgeInCategory, len(categoryList)) for i, v := range categoryList { badges, err := models.GetBadgeByCategoryId(v.ID) - userBadgeMap, err := getUserBadgesMap(userId, v.ID, 100, 1) + if badges == nil || len(badges) == 0 { + continue + } + userBadgeMap, err := getUserBadgesMap(userId, v.ID) if err != nil { return nil, err } @@ -91,8 +94,8 @@ func GetUserAllBadges(userId int64) ([]models.UserAllBadgeInCategory, error) { return r, nil } -func getUserBadgesMap(userId, categoryId int64, pageSize, page int) (map[int64]*models.Badge, error) { - userBadges, err := models.GetUserBadges(userId, models.GetUserBadgesOpts{ListOptions: models.ListOptions{PageSize: pageSize, Page: page}, CategoryId: categoryId}) +func getUserBadgesMap(userId, categoryId int64) (map[int64]*models.Badge, error) { + userBadges, err := models.GetUserBadges(userId, categoryId) if err != nil { return nil, err } From 3940775144dbdb19edb220de74d65e8d5d0c01b0 Mon Sep 17 00:00:00 2001 From: chenyifan01 Date: Tue, 11 Oct 2022 10:13:47 +0800 Subject: [PATCH 04/29] #2908 update --- routers/badge/badge.go | 1 + services/badge/icon.go | 31 +++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/routers/badge/badge.go b/routers/badge/badge.go index 5344b4e39..5e4efcdbf 100644 --- a/routers/badge/badge.go +++ b/routers/badge/badge.go @@ -112,6 +112,7 @@ func UploadIcon(ctx *context.Context, form badge.IconUploadForm) { FileMaxSize: setting.BadgeIconMaxFileSize, FileMaxWidth: setting.BadgeIconMaxWidth, FileMaxHeight: setting.BadgeIconMaxHeight, + NeedSquare: true, }) iconName, err := uploader.Upload(form, ctx.User) if err != nil { diff --git a/services/badge/icon.go b/services/badge/icon.go index ae7c25241..fd731b586 100644 --- a/services/badge/icon.go +++ b/services/badge/icon.go @@ -8,6 +8,8 @@ import ( "crypto/md5" "errors" "fmt" + "github.com/nfnt/resize" + "github.com/oliamb/cutter" "image" "image/png" "io/ioutil" @@ -27,6 +29,9 @@ type IconUploadConfig struct { FileMaxSize int64 FileMaxWidth int FileMaxHeight int + DefaultSize uint + NeedResize bool + NeedSquare bool } func NewIconUploader(config IconUploadConfig) IconUploader { @@ -105,5 +110,31 @@ func (u IconUploader) prepare(data []byte) (*image.Image, error) { return nil, fmt.Errorf("Decode: %v", err) } + if u.Config.NeedSquare { + if imgCfg.Width != imgCfg.Height { + var newSize, ax, ay int + if imgCfg.Width > imgCfg.Height { + newSize = imgCfg.Height + ax = (imgCfg.Width - imgCfg.Height) / 2 + } else { + newSize = imgCfg.Width + ay = (imgCfg.Height - imgCfg.Width) / 2 + } + + img, err = cutter.Crop(img, cutter.Config{ + Width: newSize, + Height: newSize, + Anchor: image.Point{ax, ay}, + }) + if err != nil { + return nil, err + } + } + } + + if u.Config.NeedResize && u.Config.DefaultSize > 0 { + img = resize.Resize(u.Config.DefaultSize, u.Config.DefaultSize, img, resize.NearestNeighbor) + } + return &img, nil } From a3819e4fe03340fedd23caf2c9e081875ec858b4 Mon Sep 17 00:00:00 2001 From: chenyifan01 Date: Tue, 11 Oct 2022 10:27:20 +0800 Subject: [PATCH 05/29] #2908 remove useless code --- routers/user/profile.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/routers/user/profile.go b/routers/user/profile.go index 8685cd734..1d275c191 100755 --- a/routers/user/profile.go +++ b/routers/user/profile.go @@ -6,9 +6,7 @@ package user import ( - "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/services/badge" - "encoding/json" "errors" "fmt" "path" @@ -105,8 +103,6 @@ func Profile(ctx *context.Context) { ctx.Data["Owner"] = ctxUser ctx.Data["OpenIDs"] = openIDs ctx.Data["RecentBadges"] = badges - b, _ := json.Marshal(badges) - log.Info(string(b)) ctx.Data["EnableHeatmap"] = setting.Service.EnableUserHeatmap ctx.Data["HeatmapUser"] = ctxUser.Name showPrivate := ctx.IsSigned && (ctx.User.IsAdmin || ctx.User.ID == ctxUser.ID) @@ -316,8 +312,6 @@ func Profile(ctx *context.Context) { ctx.ServerError("GetUserAllBadges", err) return } - ab, _ := json.Marshal(allBadges) - log.Info(string(ab)) ctx.Data["AllBadges"] = allBadges default: ctx.ServerError("tab error", errors.New("tab error")) From e4db58a70afe725652e2e6175b1abed588c8868f Mon Sep 17 00:00:00 2001 From: chenyifan01 Date: Tue, 11 Oct 2022 14:14:49 +0800 Subject: [PATCH 06/29] #2910 update --- routers/badge/badge.go | 9 +++++++++ routers/badge/category.go | 9 +++++++++ routers/routes/routes.go | 2 ++ 3 files changed, 20 insertions(+) diff --git a/routers/badge/badge.go b/routers/badge/badge.go index 5e4efcdbf..4367f1841 100644 --- a/routers/badge/badge.go +++ b/routers/badge/badge.go @@ -2,6 +2,7 @@ package badge import ( "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" @@ -13,6 +14,14 @@ import ( "strings" ) +const ( + tplBadgeCustomize base.TplName = "admin/badges/customize" +) + +func GetBadgeCustomizePage(ctx *context.Context) { + ctx.HTML(200, tplBadgeCustomize) +} + func GetCustomizeBadgeList(ctx *context.Context) { page := ctx.QueryInt("page") pageSize := 50 diff --git a/routers/badge/category.go b/routers/badge/category.go index 4ac85df4a..b5457c857 100644 --- a/routers/badge/category.go +++ b/routers/badge/category.go @@ -2,6 +2,7 @@ package badge import ( "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/routers/response" @@ -10,6 +11,14 @@ import ( "net/http" ) +const ( + tplBadgeCategory base.TplName = "admin/badges/category" +) + +func GetBadgeCategoryPage(ctx *context.Context) { + ctx.HTML(200, tplBadgeCategory) +} + func GetBadgeCategoryList(ctx *context.Context) { page := ctx.QueryInt("page") pageSize := 50 diff --git a/routers/routes/routes.go b/routers/routes/routes.go index 91b5690ad..648164fbe 100755 --- a/routers/routes/routes.go +++ b/routers/routes/routes.go @@ -676,10 +676,12 @@ func RegisterRoutes(m *macaron.Macaron) { m.Group("/badge", func() { m.Group("/category", func() { + m.Get("", badge.GetBadgeCategoryPage) m.Get("/list", badge.GetBadgeCategoryList) m.Post("/^:action(new|edit|del)$", bindIgnErr(models.BadgeCategory4Show{}), badge.OperateBadgeCategory) }) m.Group("/customize", func() { + m.Get("", badge.GetBadgeCustomizePage) m.Get("/list", badge.GetCustomizeBadgeList) }) m.Group("/users", func() { From 326946e36625e07ef561264e1d1374bb5097da41 Mon Sep 17 00:00:00 2001 From: chenyifan01 Date: Tue, 11 Oct 2022 14:52:54 +0800 Subject: [PATCH 07/29] #2910 update --- routers/badge/badge.go | 9 --------- routers/badge/category.go | 9 --------- routers/routes/routes.go | 2 -- 3 files changed, 20 deletions(-) diff --git a/routers/badge/badge.go b/routers/badge/badge.go index 4367f1841..5e4efcdbf 100644 --- a/routers/badge/badge.go +++ b/routers/badge/badge.go @@ -2,7 +2,6 @@ package badge import ( "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" @@ -14,14 +13,6 @@ import ( "strings" ) -const ( - tplBadgeCustomize base.TplName = "admin/badges/customize" -) - -func GetBadgeCustomizePage(ctx *context.Context) { - ctx.HTML(200, tplBadgeCustomize) -} - func GetCustomizeBadgeList(ctx *context.Context) { page := ctx.QueryInt("page") pageSize := 50 diff --git a/routers/badge/category.go b/routers/badge/category.go index b5457c857..4ac85df4a 100644 --- a/routers/badge/category.go +++ b/routers/badge/category.go @@ -2,7 +2,6 @@ package badge import ( "code.gitea.io/gitea/models" - "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/routers/response" @@ -11,14 +10,6 @@ import ( "net/http" ) -const ( - tplBadgeCategory base.TplName = "admin/badges/category" -) - -func GetBadgeCategoryPage(ctx *context.Context) { - ctx.HTML(200, tplBadgeCategory) -} - func GetBadgeCategoryList(ctx *context.Context) { page := ctx.QueryInt("page") pageSize := 50 diff --git a/routers/routes/routes.go b/routers/routes/routes.go index 648164fbe..91b5690ad 100755 --- a/routers/routes/routes.go +++ b/routers/routes/routes.go @@ -676,12 +676,10 @@ func RegisterRoutes(m *macaron.Macaron) { m.Group("/badge", func() { m.Group("/category", func() { - m.Get("", badge.GetBadgeCategoryPage) m.Get("/list", badge.GetBadgeCategoryList) m.Post("/^:action(new|edit|del)$", bindIgnErr(models.BadgeCategory4Show{}), badge.OperateBadgeCategory) }) m.Group("/customize", func() { - m.Get("", badge.GetBadgeCustomizePage) m.Get("/list", badge.GetCustomizeBadgeList) }) m.Group("/users", func() { From 4217e44a7e037aeeeaf13255c31464cbd2205631 Mon Sep 17 00:00:00 2001 From: chenyifan01 Date: Tue, 11 Oct 2022 17:32:09 +0800 Subject: [PATCH 08/29] #2188 fix bug --- routers/repo/editor.go | 6 +++--- routers/repo/setting_protected_branch.go | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/routers/repo/editor.go b/routers/repo/editor.go index 40edc4767..b350343db 100644 --- a/routers/repo/editor.go +++ b/routers/repo/editor.go @@ -303,7 +303,7 @@ func editFilePost(ctx *context.Context, form auth.EditRepoFileForm, isNewFile bo } if form.CommitChoice == frmCommitChoiceNewBranch && ctx.Repo.Repository.UnitEnabled(models.UnitTypePullRequests) { - ctx.Redirect(ctx.Repo.RepoLink + "/compare/" + ctx.Repo.BranchName + "..." + form.NewBranchName) + ctx.Redirect(ctx.Repo.RepoLink + "/compare/" + util.PathEscapeSegments(ctx.Repo.BranchName) + "..." + util.PathEscapeSegments(form.NewBranchName)) } else { ctx.Redirect(ctx.Repo.RepoLink + "/src/branch/" + util.PathEscapeSegments(branchName) + "/" + util.PathEscapeSegments(form.TreePath)) } @@ -475,7 +475,7 @@ func DeleteFilePost(ctx *context.Context, form auth.DeleteRepoFileForm) { ctx.Flash.Success(ctx.Tr("repo.editor.file_delete_success", ctx.Repo.TreePath)) if form.CommitChoice == frmCommitChoiceNewBranch && ctx.Repo.Repository.UnitEnabled(models.UnitTypePullRequests) { - ctx.Redirect(ctx.Repo.RepoLink + "/compare/" + ctx.Repo.BranchName + "..." + form.NewBranchName) + ctx.Redirect(ctx.Repo.RepoLink + "/compare/" + util.PathEscapeSegments(ctx.Repo.BranchName) + "..." + util.PathEscapeSegments(form.NewBranchName)) } else { treePath := filepath.Dir(ctx.Repo.TreePath) if treePath == "." { @@ -686,7 +686,7 @@ func UploadFilePost(ctx *context.Context, form auth.UploadRepoFileForm) { } if form.CommitChoice == frmCommitChoiceNewBranch && ctx.Repo.Repository.UnitEnabled(models.UnitTypePullRequests) { - ctx.Redirect(ctx.Repo.RepoLink + "/compare/" + ctx.Repo.BranchName + "..." + form.NewBranchName) + ctx.Redirect(ctx.Repo.RepoLink + "/compare/" + util.PathEscapeSegments(ctx.Repo.BranchName) + "..." + util.PathEscapeSegments(form.NewBranchName)) } else { ctx.Redirect(ctx.Repo.RepoLink + "/src/branch/" + util.PathEscapeSegments(branchName) + "/" + util.PathEscapeSegments(form.TreePath)) } diff --git a/routers/repo/setting_protected_branch.go b/routers/repo/setting_protected_branch.go index ab0fd77ee..f1ea17528 100644 --- a/routers/repo/setting_protected_branch.go +++ b/routers/repo/setting_protected_branch.go @@ -5,6 +5,7 @@ package repo import ( + "code.gitea.io/gitea/modules/util" "fmt" "strings" "time" @@ -192,7 +193,7 @@ func SettingsProtectedBranchPost(ctx *context.Context, f auth.ProtectBranchForm) } if f.RequiredApprovals < 0 { ctx.Flash.Error(ctx.Tr("repo.settings.protected_branch_required_approvals_min")) - ctx.Redirect(fmt.Sprintf("%s/settings/branches/%s", ctx.Repo.RepoLink, branch)) + ctx.Redirect(fmt.Sprintf("%s/settings/branches/%s", ctx.Repo.RepoLink, util.PathEscapeSegments(branch))) } var whitelistUsers, whitelistTeams, mergeWhitelistUsers, mergeWhitelistTeams, approvalsWhitelistUsers, approvalsWhitelistTeams []int64 @@ -263,7 +264,7 @@ func SettingsProtectedBranchPost(ctx *context.Context, f auth.ProtectBranchForm) return } ctx.Flash.Success(ctx.Tr("repo.settings.update_protect_branch_success", branch)) - ctx.Redirect(fmt.Sprintf("%s/settings/branches/%s", ctx.Repo.RepoLink, branch)) + ctx.Redirect(fmt.Sprintf("%s/settings/branches/%s", ctx.Repo.RepoLink, util.PathEscapeSegments(branch))) } else { if protectBranch != nil { if err := ctx.Repo.Repository.DeleteProtectedBranch(protectBranch.ID); err != nil { From a83afede2f9ce44af13a37234c0f9fa433c9dfa6 Mon Sep 17 00:00:00 2001 From: chenyifan01 Date: Fri, 14 Oct 2022 10:47:04 +0800 Subject: [PATCH 09/29] #2908 update --- models/badge.go | 14 +++++++++----- routers/badge/badge.go | 9 +++++---- routers/badge/category.go | 6 +++--- routers/response/response_list.go | 3 +++ services/badge/badge.go | 34 +++++++++++++++++++++------------- services/badge/category.go | 30 +++++++++++++++++++----------- 6 files changed, 60 insertions(+), 36 deletions(-) diff --git a/models/badge.go b/models/badge.go index 7e20ab2d4..fcfbdc27f 100644 --- a/models/badge.go +++ b/models/badge.go @@ -30,8 +30,9 @@ func (m *Badge) ToUserShow() *Badge4UserShow { } type GetBadgeOpts struct { - BadgeType BadgeType - LO ListOptions + BadgeType BadgeType + CategoryId int64 + ListOpts ListOptions } type BadgeAndCategory struct { @@ -118,19 +119,22 @@ type UserAllBadgeInCategory struct { } func GetBadgeList(opts GetBadgeOpts) (int64, []*BadgeAndCategory, error) { - if opts.LO.Page <= 0 { - opts.LO.Page = 1 + if opts.ListOpts.Page <= 0 { + opts.ListOpts.Page = 1 } var cond = builder.NewCond() if opts.BadgeType > 0 { cond = cond.And(builder.Eq{"badge_category.type": opts.BadgeType}) } + if opts.CategoryId > 0 { + cond = cond.And(builder.Eq{"badge_category.id": opts.CategoryId}) + } n, err := x.Join("INNER", "badge_category", "badge_category.ID = badge.category_id").Where(cond).Count(&BadgeAndCategory{}) if err != nil { return 0, nil, err } r := make([]*BadgeAndCategory, 0) - if err = x.Join("INNER", "badge_category", "badge_category.ID = badge.category_id").Where(cond).OrderBy("badge.created_unix desc").Limit(opts.LO.PageSize, (opts.LO.Page-1)*opts.LO.PageSize).Find(&r); err != nil { + if err = x.Join("INNER", "badge_category", "badge_category.ID = badge.category_id").Where(cond).OrderBy("badge.created_unix desc").Limit(opts.ListOpts.PageSize, (opts.ListOpts.Page-1)*opts.ListOpts.PageSize).Find(&r); err != nil { return 0, nil, err } return n, r, nil diff --git a/routers/badge/badge.go b/routers/badge/badge.go index 5e4efcdbf..6d8725b12 100644 --- a/routers/badge/badge.go +++ b/routers/badge/badge.go @@ -15,8 +15,9 @@ import ( func GetCustomizeBadgeList(ctx *context.Context) { page := ctx.QueryInt("page") + category := ctx.QueryInt64("category") pageSize := 50 - n, r, err := badge.GetBadgeList(models.GetBadgeOpts{BadgeType: models.CustomizeBadge, LO: models.ListOptions{PageSize: pageSize, Page: page}}) + n, r, err := badge.GetBadgeList(models.GetBadgeOpts{CategoryId: category, BadgeType: models.CustomizeBadge, ListOpts: models.ListOptions{PageSize: pageSize, Page: page}}) if err != nil { log.Error("GetCustomizeBadgeList error.%v", err) ctx.JSON(http.StatusOK, response.ServerError(err.Error())) @@ -32,7 +33,7 @@ func GetCustomizeBadgeList(ctx *context.Context) { func OperateBadge(ctx *context.Context, req models.BadgeOperateReq) { action := ctx.Params(":action") - var err error + var err *response.BizError switch action { case "edit": err = badge.EditBadge(req, ctx.User) @@ -41,12 +42,12 @@ func OperateBadge(ctx *context.Context, req models.BadgeOperateReq) { case "del": err = badge.DelBadge(req.ID, ctx.User) default: - err = errors.New("action type error") + err = response.NewBizError(errors.New("action type error")) } if err != nil { log.Error("OperateBadge error ,%v", err) - ctx.JSON(http.StatusOK, response.ServerError(err.Error())) + ctx.JSON(http.StatusOK, response.ResponseError(err)) return } ctx.JSON(http.StatusOK, response.Success()) diff --git a/routers/badge/category.go b/routers/badge/category.go index 4ac85df4a..71c34e1ba 100644 --- a/routers/badge/category.go +++ b/routers/badge/category.go @@ -29,7 +29,7 @@ func GetBadgeCategoryList(ctx *context.Context) { func OperateBadgeCategory(ctx *context.Context, category models.BadgeCategory4Show) { action := ctx.Params(":action") - var err error + var err *response.BizError switch action { case "edit": err = badge.EditBadgeCategory(category, ctx.User) @@ -38,12 +38,12 @@ func OperateBadgeCategory(ctx *context.Context, category models.BadgeCategory4Sh case "del": err = badge.DelBadgeCategory(category.ID, ctx.User) default: - err = errors.New("action type error") + err = response.NewBizError(errors.New("action type error")) } if err != nil { log.Error("OperateBadgeCategory error ,%v", err) - ctx.JSON(http.StatusOK, response.ServerError(err.Error())) + ctx.JSON(http.StatusOK, response.ResponseError(err)) return } ctx.JSON(http.StatusOK, response.Success()) diff --git a/routers/response/response_list.go b/routers/response/response_list.go index 6514f3edd..8bdbf375c 100644 --- a/routers/response/response_list.go +++ b/routers/response/response_list.go @@ -3,3 +3,6 @@ package response var RESOURCE_QUEUE_NOT_AVAILABLE = &BizError{Code: 1001, Err: "resource queue not available"} var SPECIFICATION_NOT_EXIST = &BizError{Code: 1002, Err: "specification not exist"} var SPECIFICATION_NOT_AVAILABLE = &BizError{Code: 1003, Err: "specification not available"} + +var CATEGORY_STILL_HAS_BADGES = &BizError{Code: 1004, Err: "Please delete badges in the category first"} +var BADGES_STILL_HAS_USERS = &BizError{Code: 1005, Err: "Please delete users of badge first"} diff --git a/services/badge/badge.go b/services/badge/badge.go index 0aefeca6e..c6f833f65 100644 --- a/services/badge/badge.go +++ b/services/badge/badge.go @@ -3,6 +3,7 @@ package badge import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/routers/response" "code.gitea.io/gitea/services/admin/operate_log" "errors" ) @@ -23,50 +24,57 @@ func GetBadgeList(opts models.GetBadgeOpts) (int64, []*models.Badge4AdminShow, e return total, r, nil } -func AddBadge(m models.BadgeOperateReq, doer *models.User) error { +func AddBadge(m models.BadgeOperateReq, doer *models.User) *response.BizError { _, err := models.GetBadgeCategoryById(m.CategoryId) if err != nil { if models.IsErrRecordNotExist(err) { - return errors.New("badge category is not available") + return response.NewBizError(errors.New("badge category is not available")) } - return err + return response.NewBizError(err) } _, err = models.AddBadge(m.ToDTO()) if err != nil { - return err + return response.NewBizError(err) } operate_log.Log4Add(operate_log.BadgeOperate, m, doer.ID, "新增了勋章") return nil } -func EditBadge(m models.BadgeOperateReq, doer *models.User) error { +func EditBadge(m models.BadgeOperateReq, doer *models.User) *response.BizError { if m.ID == 0 { log.Error(" EditBadge param error") - return errors.New("param error") + return response.NewBizError(errors.New("param error")) } old, err := models.GetBadgeById(m.ID) if err != nil { - return err + return response.NewBizError(err) } _, err = models.UpdateBadgeById(m.ID, m.ToDTO()) if err != nil { - return err + return response.NewBizError(err) } operate_log.Log4Edit(operate_log.BadgeOperate, old, m.ToDTO(), doer.ID, "修改了勋章") - return err + return nil } -func DelBadge(id int64, doer *models.User) error { +func DelBadge(id int64, doer *models.User) *response.BizError { if id == 0 { log.Error(" DelBadge param error") - return errors.New("param error") + return response.NewBizError(errors.New("param error")) } old, err := models.GetBadgeById(id) if err != nil { - return err + return response.NewBizError(err) + } + n, _, err := models.GetBadgeUsers(id, models.ListOptions{PageSize: 1, Page: 1}) + if err != nil { + return response.NewBizError(err) + } + if n > 0 { + return response.BADGES_STILL_HAS_USERS } _, err = models.DelBadge(id) operate_log.Log4Del(operate_log.BadgeOperate, old, doer.ID, "删除了勋章") - return err + return nil } diff --git a/services/badge/category.go b/services/badge/category.go index 14d06620a..445dedcad 100644 --- a/services/badge/category.go +++ b/services/badge/category.go @@ -3,6 +3,7 @@ package badge import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/routers/response" "code.gitea.io/gitea/services/admin/operate_log" "errors" ) @@ -23,42 +24,49 @@ func GetBadgeCategoryList(opts models.ListOptions) (int64, []*models.BadgeCatego return total, r, nil } -func AddBadgeCategory(m models.BadgeCategory4Show, doer *models.User) error { +func AddBadgeCategory(m models.BadgeCategory4Show, doer *models.User) *response.BizError { _, err := models.AddBadgeCategory(m.ToDTO()) if err != nil { - return err + return response.NewBizError(err) } operate_log.Log4Add(operate_log.BadgeCategoryOperate, m, doer.ID, "新增了勋章分类") return nil } -func EditBadgeCategory(m models.BadgeCategory4Show, doer *models.User) error { +func EditBadgeCategory(m models.BadgeCategory4Show, doer *models.User) *response.BizError { if m.ID == 0 { log.Error(" EditBadgeCategory param error") - return errors.New("param error") + return response.NewBizError(errors.New("param error")) } old, err := models.GetBadgeCategoryById(m.ID) if err != nil { - return err + return response.NewBizError(err) } _, err = models.UpdateBadgeCategoryById(m.ID, m.ToDTO()) if err != nil { - return err + return response.NewBizError(err) } operate_log.Log4Edit(operate_log.BadgeCategoryOperate, old, m.ToDTO(), doer.ID, "修改了勋章分类") - return err + return nil } -func DelBadgeCategory(id int64, doer *models.User) error { +func DelBadgeCategory(id int64, doer *models.User) *response.BizError { if id == 0 { log.Error(" DelBadgeCategory param error") - return errors.New("param error") + return response.NewBizError(errors.New("param error")) } old, err := models.GetBadgeCategoryById(id) if err != nil { - return err + return response.NewBizError(err) + } + badges, err := models.GetBadgeByCategoryId(id) + if err != nil { + return response.NewBizError(err) + } + if len(badges) > 0 { + return response.CATEGORY_STILL_HAS_BADGES } _, err = models.DelBadgeCategory(id) operate_log.Log4Del(operate_log.BadgeCategoryOperate, old, doer.ID, "删除了勋章分类") - return err + return nil } From d38a58b57b3c92f0b8ca333ce8a5cf110561930e Mon Sep 17 00:00:00 2001 From: chenyifan01 Date: Mon, 17 Oct 2022 14:38:42 +0800 Subject: [PATCH 10/29] bug fix --- services/badge/user.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/services/badge/user.go b/services/badge/user.go index 70fc7bba7..b4273d8d2 100644 --- a/services/badge/user.go +++ b/services/badge/user.go @@ -65,8 +65,8 @@ func GetUserAllBadges(userId int64) ([]models.UserAllBadgeInCategory, error) { if err != nil { return nil, err } - r := make([]models.UserAllBadgeInCategory, len(categoryList)) - for i, v := range categoryList { + r := make([]models.UserAllBadgeInCategory, 0) + for _, v := range categoryList { badges, err := models.GetBadgeByCategoryId(v.ID) if badges == nil || len(badges) == 0 { continue @@ -89,7 +89,7 @@ func GetUserAllBadges(userId int64) ([]models.UserAllBadgeInCategory, error) { bArray[j] = b } t.Badges = bArray - r[i] = t + r = append(r, t) } return r, nil } From 4e2ec5ac738610556857ce00b8d706c79f9f62f4 Mon Sep 17 00:00:00 2001 From: chenyifan01 Date: Mon, 17 Oct 2022 14:55:11 +0800 Subject: [PATCH 11/29] add total badges --- models/badge_user.go | 3 +++ routers/user/profile.go | 7 +++++++ services/badge/user.go | 4 ++++ 3 files changed, 14 insertions(+) diff --git a/models/badge_user.go b/models/badge_user.go index 32861248e..9b556bc0e 100644 --- a/models/badge_user.go +++ b/models/badge_user.go @@ -142,6 +142,9 @@ func GetUserBadgesPaging(userId int64, opts GetUserBadgesOpts) ([]*Badge, error) err := x.Join("INNER", "badge_user", "badge_user.badge_id = badge.id").Where(cond).OrderBy("badge_user.id desc").Limit(opts.PageSize, (opts.Page-1)*opts.PageSize).Find(&r) return r, err } +func CountUserBadges(userId int64) (int64, error) { + return x.Where("user_id = ?", userId).Count(&BadgeUser{}) +} func GetUserBadges(userId, categoryId int64) ([]*Badge, error) { cond := builder.NewCond() diff --git a/routers/user/profile.go b/routers/user/profile.go index 1d275c191..66a480b7f 100755 --- a/routers/user/profile.go +++ b/routers/user/profile.go @@ -97,12 +97,19 @@ func Profile(ctx *context.Context) { ctx.ServerError("GetUserBadges", err) return } + // Count user badges + cnt, err := badge.CountUserBadges(ctxUser.ID) + if err != nil { + ctx.ServerError("CountUserBadges", err) + return + } ctx.Data["Title"] = ctxUser.DisplayName() ctx.Data["PageIsUserProfile"] = true ctx.Data["Owner"] = ctxUser ctx.Data["OpenIDs"] = openIDs ctx.Data["RecentBadges"] = badges + ctx.Data["TotalBadges"] = cnt ctx.Data["EnableHeatmap"] = setting.Service.EnableUserHeatmap ctx.Data["HeatmapUser"] = ctxUser.Name showPrivate := ctx.IsSigned && (ctx.User.IsAdmin || ctx.User.ID == ctxUser.ID) diff --git a/services/badge/user.go b/services/badge/user.go index b4273d8d2..025b10f77 100644 --- a/services/badge/user.go +++ b/services/badge/user.go @@ -60,6 +60,10 @@ func GetUserBadges(userId int64, opts models.ListOptions) ([]*models.Badge4UserS return r, nil } +func CountUserBadges(userId int64) (int64, error) { + return models.CountUserBadges(userId) +} + func GetUserAllBadges(userId int64) ([]models.UserAllBadgeInCategory, error) { categoryList, err := models.GetBadgeCategoryList() if err != nil { From 46a28cbd6ce5063f1c7ab9ccf2f9eaa64a7e2e5a Mon Sep 17 00:00:00 2001 From: zhoupzh Date: Mon, 17 Oct 2022 14:58:04 +0800 Subject: [PATCH 12/29] =?UTF-8?q?=E5=89=8D=E7=AB=AF=E5=BE=BD=E7=AB=A0?= =?UTF-8?q?=E7=B3=BB=E7=BB=9F=E6=98=BE=E7=A4=BA=E9=A1=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- options/locale/locale_en-US.ini | 1 + options/locale/locale_zh-CN.ini | 1 + templates/repo/badge.tmpl | 25 ++++++++++++ templates/user/profile.tmpl | 18 +++++++++ web_src/less/_user.less | 85 ++++++++++++++++++++++++++++++++++++++++- 5 files changed, 128 insertions(+), 2 deletions(-) create mode 100644 templates/repo/badge.tmpl diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index dbd3f81f8..c3e2426fb 100755 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -525,6 +525,7 @@ datasets = Datasets activity = Public Activity followers = Followers starred = Starred Repositories +badge = Achievement Badge following = Following follow = Follow unfollow = Unfollow diff --git a/options/locale/locale_zh-CN.ini b/options/locale/locale_zh-CN.ini index 21c4f45bd..bf7549918 100755 --- a/options/locale/locale_zh-CN.ini +++ b/options/locale/locale_zh-CN.ini @@ -530,6 +530,7 @@ datasets=数据集 activity=公开活动 followers=关注者 starred=已点赞 +badge=成就徽章 following=关注中 follow=关注 unfollow=取消关注 diff --git a/templates/repo/badge.tmpl b/templates/repo/badge.tmpl new file mode 100644 index 000000000..61b542be8 --- /dev/null +++ b/templates/repo/badge.tmpl @@ -0,0 +1,25 @@ +
+ {{range .AllBadges }} +
+
{{.CategoryName}}   (已点亮{{.LightedNum}}个)
+ +
+ {{ end }} + {{ template "base/paginate" . }} +
+ diff --git a/templates/user/profile.tmpl b/templates/user/profile.tmpl index be6ecbaa0..f1328b626 100755 --- a/templates/user/profile.tmpl +++ b/templates/user/profile.tmpl @@ -17,6 +17,17 @@ {{if .Owner.FullName}}{{.Owner.FullName}}{{end}} {{.Owner.Name}} + +
+ {{range $k,$v :=.RecentBadges}} + {{if le $k 3}} +
+ {{else}} + + {{end}} + {{end}} + +
{{if eq .TabName "activity"}} @@ -201,6 +217,8 @@ {{template "explore/dataset_search" .}} {{template "explore/dataset_list" .}} {{template "base/paginate" .}} + {{else if eq .TabName "badge"}} + {{template "repo/badge" .}} {{else}} {{template "explore/repo_search" .}} {{template "explore/repo_list" .}} diff --git a/web_src/less/_user.less b/web_src/less/_user.less index 6acbb35ee..c2381820c 100644 --- a/web_src/less/_user.less +++ b/web_src/less/_user.less @@ -9,11 +9,30 @@ .username { display: block; } - + .badge-wrap { + display: flex; + justify-content: center; + align-items: center; + .badge-img-avatar { + width: 32px; + height: 32px; + margin-right: 5px; + } + .badge-more-icon { + width: 32px; + height: 32px; + display: flex; + justify-content: center; + align-items: center; + border-radius: 50%; + border: 1px #f8f9fa solid; + background: #f8f9fa; + } + } .header { font-weight: 700; font-size: 1.3rem; - margin-top: -.2rem; + margin-top: -0.2rem; line-height: 1.3rem; } @@ -158,3 +177,65 @@ max-width: 60px; } } +.badge-achive { + .bagde-section { + color: #000; + margin-top: 28px; + border-bottom: 1px solid #dededf; + } + .bagde-section:last-child { + color: #000; + margin-top: 28px; + border-bottom: none; + } + .badge-section-title { + position: relative; + font-size: 16px; + line-height: 24px; + padding-left: 8px; + margin-bottom: 20px; + display: flex; + justify-content: space-between; + } + .badge-section-children { + width: 100%; + } + .badge-honor-badge { + margin-bottom: 25px; + } + .badge-honor-badge-basic { + display: flex; + align-items: flex-start; + flex-wrap: wrap; + } + .badge-honor-badge-basic-item { + text-align: center; + font-size: 12px; + margin-right: 30px; + color: #101010; + } + .is-not-pointer { + cursor: pointer; + pointer-events: none; + } + .badge-honor-badge-basic-img { + width: 56px; + height: 56px; + margin-bottom: 5px; + } + .badge-honor-badge-basic-txt { + line-height: 20px; + width: 65px; + word-break: break-all; + } + .badge-section-title:before { + content: ""; + position: absolute; + top: 50%; + left: 0; + transform: translateY(-50%); + width: 3px; + height: 1em; + background-color: #000; + } +} From c5feced4f1c877e5885f23b97d69f66debc8b4a6 Mon Sep 17 00:00:00 2001 From: zhoupzh Date: Mon, 17 Oct 2022 15:48:08 +0800 Subject: [PATCH 13/29] fix issue --- templates/user/profile.tmpl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/templates/user/profile.tmpl b/templates/user/profile.tmpl index f1328b626..d4e97a961 100755 --- a/templates/user/profile.tmpl +++ b/templates/user/profile.tmpl @@ -184,6 +184,7 @@ {{.i18n.Tr "user.badge"}} +
{{.TotalBadges}}
@@ -246,5 +247,8 @@ .user.profile .ui.card .extra.content ul { padding: 5px 0; } + .ui.secondary.pointing.menu .item{ + padding: 0.78571429em 0.92857143em; + } \ No newline at end of file From f80265742ca9e0b357c859576d5883cd8cc6bc32 Mon Sep 17 00:00:00 2001 From: zhoupzh Date: Tue, 18 Oct 2022 11:38:33 +0800 Subject: [PATCH 14/29] =?UTF-8?q?=E4=B8=AA=E4=BA=BA=E9=A1=B5=E5=BE=BD?= =?UTF-8?q?=E7=AB=A0=E5=A4=A7=E5=B0=8F=E6=A0=B7=E5=BC=8F=E6=9B=B4=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web_src/less/_user.less | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/web_src/less/_user.less b/web_src/less/_user.less index c2381820c..e07831c25 100644 --- a/web_src/less/_user.less +++ b/web_src/less/_user.less @@ -219,13 +219,13 @@ pointer-events: none; } .badge-honor-badge-basic-img { - width: 56px; - height: 56px; - margin-bottom: 5px; + width: 100px; + height: 100px; + margin-bottom: 10px; } .badge-honor-badge-basic-txt { line-height: 20px; - width: 65px; + width: 100px; word-break: break-all; } .badge-section-title:before { From 7d8a70d99a39f6dd237579d78d50dada4cd9512e Mon Sep 17 00:00:00 2001 From: chenshihai Date: Wed, 19 Oct 2022 11:25:48 +0800 Subject: [PATCH 15/29] =?UTF-8?q?#2988=20npu=E8=B0=83=E8=AF=95=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1=E8=AF=A6=E6=83=85=E9=A1=B5=E9=95=9C=E5=83=8F=E5=AD=97?= =?UTF-8?q?=E6=AE=B5=E6=82=AC=E6=B5=AE=E6=8F=90=E7=A4=BA=E6=96=87=E5=AD=97?= =?UTF-8?q?=E4=B8=8D=E5=AF=B9=20=09#2987=20=E6=99=BA=E7=AE=97gpu=E8=AE=AD?= =?UTF-8?q?=E7=BB=83=E4=BB=BB=E5=8A=A1=E8=AF=A6=E6=83=85=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?AI=E5=BC=95=E6=93=8E=E5=AD=97=E6=AE=B5=E5=BA=94=E5=8F=AB?= =?UTF-8?q?=E9=95=9C=E5=83=8F=20=09#2989=20=E4=B8=AA=E4=BA=BA=E4=B8=AD?= =?UTF-8?q?=E5=BF=83-=E4=BA=91=E8=84=91=E4=BB=BB=E5=8A=A1=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2=E7=82=B9=E5=87=BB=E4=BF=AE=E6=94=B9=E5=86=8D=E7=82=B9?= =?UTF-8?q?=E5=87=BB=E5=8F=96=E6=B6=88=E5=BA=94=E8=BF=94=E5=9B=9E=E4=B8=AA?= =?UTF-8?q?=E4=BA=BA=E4=B8=AD=E5=BF=83-=E4=BA=91=E8=84=91=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- templates/admin/cloudbrain/list.tmpl | 14 +++++++++++++- templates/repo/cloudbrain/trainjob/new.tmpl | 6 +++++- templates/repo/grampus/trainjob/gpu/new.tmpl | 6 +++++- templates/repo/grampus/trainjob/npu/new.tmpl | 6 +++++- templates/repo/grampus/trainjob/show.tmpl | 21 +++++++++++++++++++++ templates/repo/modelarts/notebook/show.tmpl | 6 +++--- templates/repo/modelarts/trainjob/index.tmpl | 12 +++++++++++- templates/repo/modelarts/trainjob/version_new.tmpl | 20 ++++++++++++-------- templates/user/dashboard/cloudbrains.tmpl | 15 ++++++++++++++- 9 files changed, 89 insertions(+), 17 deletions(-) diff --git a/templates/admin/cloudbrain/list.tmpl b/templates/admin/cloudbrain/list.tmpl index 4c500b5e6..eb418d70b 100755 --- a/templates/admin/cloudbrain/list.tmpl +++ b/templates/admin/cloudbrain/list.tmpl @@ -290,7 +290,7 @@ {{if eq .JobType "TRAIN"}} - + {{template "base/footer" .}} \ No newline at end of file diff --git a/templates/repo/cloudbrain/trainjob/new.tmpl b/templates/repo/cloudbrain/trainjob/new.tmpl index 607af5f07..0ca76ad0d 100755 --- a/templates/repo/cloudbrain/trainjob/new.tmpl +++ b/templates/repo/cloudbrain/trainjob/new.tmpl @@ -232,7 +232,7 @@ - {{.i18n.Tr "repo.cloudbrain.cancel"}} @@ -256,5 +256,9 @@ memory: {{$.i18n.Tr "cloudbrain.memory"}}, shared_memory: {{$.i18n.Tr "cloudbrain.shared_memory"}}, }); + var backUrl = new URLSearchParams(window.location.search).get("backurl"); + if (backUrl) { + $('.__btn-cancel-back__').attr('href', backUrl); + } })(); diff --git a/templates/repo/grampus/trainjob/gpu/new.tmpl b/templates/repo/grampus/trainjob/gpu/new.tmpl index e97ccfe59..cd4970632 100755 --- a/templates/repo/grampus/trainjob/gpu/new.tmpl +++ b/templates/repo/grampus/trainjob/gpu/new.tmpl @@ -205,7 +205,7 @@ - {{.i18n.Tr "repo.cloudbrain.cancel"}} + {{.i18n.Tr "repo.cloudbrain.cancel"}} @@ -228,5 +228,9 @@ memory: {{$.i18n.Tr "cloudbrain.memory"}}, shared_memory: {{$.i18n.Tr "cloudbrain.shared_memory"}}, }); + var backUrl = new URLSearchParams(window.location.search).get("backurl"); + if (backUrl) { + $('.__btn-cancel-back__').attr('href', backUrl); + } })(); diff --git a/templates/repo/grampus/trainjob/npu/new.tmpl b/templates/repo/grampus/trainjob/npu/new.tmpl index 51a561d3d..925ae3915 100755 --- a/templates/repo/grampus/trainjob/npu/new.tmpl +++ b/templates/repo/grampus/trainjob/npu/new.tmpl @@ -229,7 +229,7 @@ - {{.i18n.Tr "repo.cloudbrain.cancel"}} + {{.i18n.Tr "repo.cloudbrain.cancel"}} @@ -252,5 +252,9 @@ memory: {{$.i18n.Tr "cloudbrain.memory"}}, shared_memory: {{$.i18n.Tr "cloudbrain.shared_memory"}}, }); + var backUrl = new URLSearchParams(window.location.search).get("backurl"); + if (backUrl) { + $('.__btn-cancel-back__').attr('href', backUrl); + } })(); diff --git a/templates/repo/grampus/trainjob/show.tmpl b/templates/repo/grampus/trainjob/show.tmpl index 67548696f..67c415488 100755 --- a/templates/repo/grampus/trainjob/show.tmpl +++ b/templates/repo/grampus/trainjob/show.tmpl @@ -385,6 +385,26 @@
+ {{ if eq $.Spec.ComputeResource "GPU"}} + + + + + {{else}} + {{end}}
+ {{$.i18n.Tr "cloudbrain.mirror"}} + +
+ + {{.EngineName}} + +
+
{{$.i18n.Tr "repo.modelarts.train_job.AI_driver"}} @@ -395,6 +415,7 @@
{{$.i18n.Tr "repo.modelarts.code_version"}} diff --git a/templates/repo/modelarts/notebook/show.tmpl b/templates/repo/modelarts/notebook/show.tmpl index 0f632eab2..cc65ad0b8 100755 --- a/templates/repo/modelarts/notebook/show.tmpl +++ b/templates/repo/modelarts/notebook/show.tmpl @@ -364,9 +364,9 @@
{{.Image}} diff --git a/templates/repo/modelarts/trainjob/index.tmpl b/templates/repo/modelarts/trainjob/index.tmpl index 19594d349..f131a0e38 100755 --- a/templates/repo/modelarts/trainjob/index.tmpl +++ b/templates/repo/modelarts/trainjob/index.tmpl @@ -173,7 +173,7 @@
{{$.CsrfTokenHtml}} {{if .CanModify}} - + {{$.i18n.Tr "repo.modelarts.modify"}} {{else}} @@ -273,4 +273,14 @@ $('.ui.selection.dropdown').dropdown({ } }) }) +document.addEventListener('DOMContentLoaded', function() { + var editbtns = $('.__btn_edit__'); + var curHref = window.location.href; + for (var i = 0, iLen = editbtns.length; i < iLen; i++) { + var buttonEl = editbtns.eq(i); + var oHref = buttonEl.attr('href'); + var hasSearch = oHref.split('?').length > 1; + buttonEl.attr('href', oHref + (hasSearch ? '&' : '?') + 'backurl=' + encodeURIComponent(curHref)); + } +}); diff --git a/templates/repo/modelarts/trainjob/version_new.tmpl b/templates/repo/modelarts/trainjob/version_new.tmpl index 89bf6fc08..ea01d9739 100644 --- a/templates/repo/modelarts/trainjob/version_new.tmpl +++ b/templates/repo/modelarts/trainjob/version_new.tmpl @@ -273,15 +273,19 @@ {{template "base/footer" .}} - {{template "base/footer" .}} From 2e25fc2d079ea36663cc182496a4cdd5c5964eb9 Mon Sep 17 00:00:00 2001 From: zhoupzh Date: Fri, 21 Oct 2022 15:53:46 +0800 Subject: [PATCH 16/29] fix style css --- web_src/less/_user.less | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/web_src/less/_user.less b/web_src/less/_user.less index e07831c25..29ca96255 100644 --- a/web_src/less/_user.less +++ b/web_src/less/_user.less @@ -227,6 +227,11 @@ line-height: 20px; width: 100px; word-break: break-all; + overflow: hidden; + text-overflow: ellipsis; + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; } .badge-section-title:before { content: ""; From 482b4bffea0cf233ddca1823c68933918c336bce Mon Sep 17 00:00:00 2001 From: ychao_1983 Date: Fri, 21 Oct 2022 16:01:32 +0800 Subject: [PATCH 17/29] =?UTF-8?q?=E6=8F=90=E4=BA=A4=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- models/cloudbrain.go | 137 +--------------------------- routers/repo/aisafety.go | 6 ++ routers/repo/cloudbrain.go | 136 +++++++++++++-------------- routers/repo/grampus.go | 11 ++- routers/repo/modelarts.go | 70 ++++---------- services/cloudbrain/cloudbrainTask/count.go | 86 +++++++++++++++++ 6 files changed, 196 insertions(+), 250 deletions(-) create mode 100644 services/cloudbrain/cloudbrainTask/count.go diff --git a/models/cloudbrain.go b/models/cloudbrain.go index 6135dac40..f0e27995e 100755 --- a/models/cloudbrain.go +++ b/models/cloudbrain.go @@ -2015,11 +2015,6 @@ func GetModelSafetyTestTask() ([]*Cloudbrain, error) { return cloudbrains, err } -func GetCloudbrainCountByUserID(userID int64, jobType string) (int, error) { - count, err := x.In("status", JobWaiting, JobRunning).And("job_type = ? and user_id = ? and type = ?", jobType, userID, TypeCloudBrainOne).Count(new(Cloudbrain)) - return int(count), err -} - func GetCloudbrainRunCountByRepoID(repoID int64) (int, error) { count, err := x.In("status", JobWaiting, JobRunning, ModelArtsCreateQueue, ModelArtsCreating, ModelArtsStarting, ModelArtsReadyToStart, ModelArtsResizing, ModelArtsStartQueuing, ModelArtsRunning, ModelArtsDeleting, ModelArtsRestarting, ModelArtsTrainJobInit, @@ -2028,11 +2023,6 @@ func GetCloudbrainRunCountByRepoID(repoID int64) (int, error) { return int(count), err } -func GetBenchmarkCountByUserID(userID int64) (int, error) { - count, err := x.In("status", JobWaiting, JobRunning).And("(job_type = ? or job_type = ? or job_type = ?) and user_id = ? and type = ?", string(JobTypeBenchmark), string(JobTypeModelSafety), string(JobTypeBrainScore), string(JobTypeSnn4imagenet), userID, TypeCloudBrainOne).Count(new(Cloudbrain)) - return int(count), err -} - func GetModelSafetyCountByUserID(userID int64) (int, error) { count, err := x.In("status", JobWaiting, JobRunning).And("job_type = ? and user_id = ?", string(JobTypeModelSafety), userID).Count(new(Cloudbrain)) return int(count), err @@ -2048,40 +2038,14 @@ func GetWaitingCloudbrainCount(cloudbrainType int, computeResource string, jobTy } return sess.Count(new(Cloudbrain)) } - -func GetCloudbrainNotebookCountByUserID(userID int64) (int, error) { - count, err := x.In("status", ModelArtsCreateQueue, ModelArtsCreating, ModelArtsStarting, ModelArtsReadyToStart, ModelArtsResizing, ModelArtsStartQueuing, ModelArtsRunning, ModelArtsRestarting). - And("job_type = ? and user_id = ? and type in (?,?)", JobTypeDebug, userID, TypeCloudBrainTwo, TypeCDCenter).Count(new(Cloudbrain)) - return int(count), err -} - -func GetCloudbrainTrainJobCountByUserID(userID int64) (int, error) { - count, err := x.In("status", ModelArtsTrainJobInit, ModelArtsTrainJobImageCreating, ModelArtsTrainJobSubmitTrying, ModelArtsTrainJobWaiting, ModelArtsTrainJobRunning, ModelArtsTrainJobScaling, ModelArtsTrainJobCheckInit, ModelArtsTrainJobCheckRunning, ModelArtsTrainJobCheckRunningCompleted). - And("job_type = ? and user_id = ? and type = ?", JobTypeTrain, userID, TypeCloudBrainTwo).Count(new(Cloudbrain)) - return int(count), err -} - -func GetCloudbrainInferenceJobCountByUserID(userID int64) (int, error) { - count, err := x.In("status", ModelArtsTrainJobInit, ModelArtsTrainJobImageCreating, ModelArtsTrainJobSubmitTrying, ModelArtsTrainJobWaiting, ModelArtsTrainJobRunning, ModelArtsTrainJobScaling, ModelArtsTrainJobCheckInit, ModelArtsTrainJobCheckRunning, ModelArtsTrainJobCheckRunningCompleted). - And("job_type = ? and user_id = ? and type = ?", JobTypeInference, userID, TypeCloudBrainTwo).Count(new(Cloudbrain)) - return int(count), err -} - -func GetGrampusCountByUserID(userID int64, jobType, computeResource string) (int, error) { - count, err := x.In("status", GrampusStatusWaiting, GrampusStatusRunning).And("job_type = ? and user_id = ? and type = ?", jobType, userID, TypeC2Net).And("compute_resource = ?", computeResource).Count(new(Cloudbrain)) +func GetNotFinalStatusTaskCount(userID int64, notFinalStatus []string, jobTypes []JobType, cloudbrainTypes []int, computeResource string) (int, error) { + count, err := x.In("status", notFinalStatus). + In("job_type", jobTypes). + In("type", cloudbrainTypes). + And("user_id = ? and compute_resource = ?", userID, computeResource).Count(new(Cloudbrain)) return int(count), err } -func UpdateInferenceJob(job *Cloudbrain) error { - return updateInferenceJob(x, job) -} - -func updateInferenceJob(e Engine, job *Cloudbrain) error { - var sess *xorm.Session - sess = e.Where("job_id = ?", job.JobID) - _, err := sess.Cols("status", "train_job_duration", "duration", "start_time", "end_time", "created_unix").Update(job) - return err -} func RestartCloudbrain(old *Cloudbrain, new *Cloudbrain) (err error) { sess := x.NewSession() defer sess.Close() @@ -2411,97 +2375,6 @@ var ( CloudbrainSpecialGpuInfosMap map[string]*GpuInfo ) -func InitCloudbrainOneResourceSpecMap() { - if CloudbrainDebugResourceSpecsMap == nil || len(CloudbrainDebugResourceSpecsMap) == 0 { - t := ResourceSpecs{} - json.Unmarshal([]byte(setting.ResourceSpecs), &t) - CloudbrainDebugResourceSpecsMap = make(map[int]*ResourceSpec, len(t.ResourceSpec)) - for _, spec := range t.ResourceSpec { - CloudbrainDebugResourceSpecsMap[spec.Id] = spec - } - } - if CloudbrainTrainResourceSpecsMap == nil || len(CloudbrainTrainResourceSpecsMap) == 0 { - t := ResourceSpecs{} - json.Unmarshal([]byte(setting.TrainResourceSpecs), &t) - CloudbrainTrainResourceSpecsMap = make(map[int]*ResourceSpec, len(t.ResourceSpec)) - for _, spec := range t.ResourceSpec { - CloudbrainTrainResourceSpecsMap[spec.Id] = spec - } - } - if CloudbrainInferenceResourceSpecsMap == nil || len(CloudbrainInferenceResourceSpecsMap) == 0 { - t := ResourceSpecs{} - json.Unmarshal([]byte(setting.InferenceResourceSpecs), &t) - CloudbrainInferenceResourceSpecsMap = make(map[int]*ResourceSpec, len(t.ResourceSpec)) - for _, spec := range t.ResourceSpec { - CloudbrainInferenceResourceSpecsMap[spec.Id] = spec - } - } - if CloudbrainBenchmarkResourceSpecsMap == nil || len(CloudbrainBenchmarkResourceSpecsMap) == 0 { - t := ResourceSpecs{} - json.Unmarshal([]byte(setting.BenchmarkResourceSpecs), &t) - CloudbrainBenchmarkResourceSpecsMap = make(map[int]*ResourceSpec, len(t.ResourceSpec)) - for _, spec := range t.ResourceSpec { - CloudbrainBenchmarkResourceSpecsMap[spec.Id] = spec - } - } - if CloudbrainSpecialResourceSpecsMap == nil || len(CloudbrainSpecialResourceSpecsMap) == 0 { - t := SpecialPools{} - json.Unmarshal([]byte(setting.SpecialPools), &t) - for _, pool := range t.Pools { - CloudbrainSpecialResourceSpecsMap = make(map[int]*ResourceSpec, len(pool.ResourceSpec)) - for _, spec := range pool.ResourceSpec { - CloudbrainSpecialResourceSpecsMap[spec.Id] = spec - } - } - } - SpecsMapInitFlag = true -} - -func InitCloudbrainOneGpuInfoMap() { - if CloudbrainDebugGpuInfosMap == nil || len(CloudbrainDebugGpuInfosMap) == 0 { - t := GpuInfos{} - json.Unmarshal([]byte(setting.GpuTypes), &t) - CloudbrainDebugGpuInfosMap = make(map[string]*GpuInfo, len(t.GpuInfo)) - for _, GpuInfo := range t.GpuInfo { - CloudbrainDebugGpuInfosMap[GpuInfo.Queue] = GpuInfo - } - } - if CloudbrainTrainGpuInfosMap == nil || len(CloudbrainTrainGpuInfosMap) == 0 { - t := GpuInfos{} - json.Unmarshal([]byte(setting.TrainGpuTypes), &t) - CloudbrainTrainGpuInfosMap = make(map[string]*GpuInfo, len(t.GpuInfo)) - for _, GpuInfo := range t.GpuInfo { - CloudbrainTrainGpuInfosMap[GpuInfo.Queue] = GpuInfo - } - } - if CloudbrainInferenceGpuInfosMap == nil || len(CloudbrainInferenceGpuInfosMap) == 0 { - t := GpuInfos{} - json.Unmarshal([]byte(setting.InferenceGpuTypes), &t) - CloudbrainInferenceGpuInfosMap = make(map[string]*GpuInfo, len(t.GpuInfo)) - for _, GpuInfo := range t.GpuInfo { - CloudbrainInferenceGpuInfosMap[GpuInfo.Queue] = GpuInfo - } - } - if CloudbrainBenchmarkGpuInfosMap == nil || len(CloudbrainBenchmarkGpuInfosMap) == 0 { - t := GpuInfos{} - json.Unmarshal([]byte(setting.BenchmarkGpuTypes), &t) - CloudbrainBenchmarkGpuInfosMap = make(map[string]*GpuInfo, len(t.GpuInfo)) - for _, GpuInfo := range t.GpuInfo { - CloudbrainBenchmarkGpuInfosMap[GpuInfo.Queue] = GpuInfo - } - } - if CloudbrainSpecialGpuInfosMap == nil || len(CloudbrainSpecialGpuInfosMap) == 0 { - t := SpecialPools{} - json.Unmarshal([]byte(setting.SpecialPools), &t) - for _, pool := range t.Pools { - CloudbrainSpecialGpuInfosMap = make(map[string]*GpuInfo, len(pool.Pool)) - for _, GpuInfo := range pool.Pool { - CloudbrainSpecialGpuInfosMap[GpuInfo.Queue] = GpuInfo - } - } - } - GpuInfosMapInitFlag = true -} func GetNewestJobsByAiCenter() ([]int64, error) { ids := make([]int64, 0) return ids, x. diff --git a/routers/repo/aisafety.go b/routers/repo/aisafety.go index 5102a6722..63f50592b 100644 --- a/routers/repo/aisafety.go +++ b/routers/repo/aisafety.go @@ -535,6 +535,8 @@ func AiSafetyCreateForGetGPU(ctx *context.Context) { } else { log.Info("The GPU WaitCount not get") } + NotStopTaskCount, _ := models.GetModelSafetyCountByUserID(ctx.User.ID) + ctx.Data["NotStopTaskCount"] = NotStopTaskCount ctx.HTML(200, tplModelSafetyTestCreateGpu) } @@ -578,6 +580,8 @@ func AiSafetyCreateForGetNPU(ctx *context.Context) { waitCount := cloudbrain.GetWaitingCloudbrainCount(models.TypeCloudBrainTwo, "") ctx.Data["WaitCount"] = waitCount log.Info("The NPU WaitCount is " + fmt.Sprint(waitCount)) + NotStopTaskCount, _ := models.GetModelSafetyCountByUserID(ctx.User.ID) + ctx.Data["NotStopTaskCount"] = NotStopTaskCount ctx.HTML(200, tplModelSafetyTestCreateNpu) } @@ -980,6 +984,8 @@ func modelSafetyNewDataPrepare(ctx *context.Context) error { ctx.Data["ckpt_name"] = ctx.Query("ckpt_name") ctx.Data["model_name"] = ctx.Query("model_name") ctx.Data["model_version"] = ctx.Query("model_version") + NotStopTaskCount, _ := models.GetModelSafetyCountByUserID(ctx.User.ID) + ctx.Data["NotStopTaskCount"] = NotStopTaskCount if ctx.QueryInt("type") == models.TypeCloudBrainOne { ctx.Data["type"] = models.TypeCloudBrainOne diff --git a/routers/repo/cloudbrain.go b/routers/repo/cloudbrain.go index a2ea7d51b..f5a43e697 100755 --- a/routers/repo/cloudbrain.go +++ b/routers/repo/cloudbrain.go @@ -17,6 +17,7 @@ import ( "code.gitea.io/gitea/modules/dataset" + "code.gitea.io/gitea/services/cloudbrain/cloudbrainTask" "code.gitea.io/gitea/services/cloudbrain/resource" "code.gitea.io/gitea/services/reward/point/account" @@ -107,7 +108,7 @@ func jobNamePrefixValid(s string) string { } -func cloudBrainNewDataPrepare(ctx *context.Context) error { +func cloudBrainNewDataPrepare(ctx *context.Context, jobType string) error { ctx.Data["PageIsCloudBrain"] = true t := time.Now() var displayJobName = jobNamePrefixValid(cutString(ctx.User.Name, 5)) + t.Format("2006010215") + strconv.Itoa(int(t.Unix()))[5:] @@ -148,6 +149,8 @@ func cloudBrainNewDataPrepare(ctx *context.Context) error { defaultMode = "alogrithm" } ctx.Data["benchmarkMode"] = defaultMode + NotStopTaskCount, _ := cloudbrainTask.GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeCloudBrainOne, jobType, models.GPUResource) + ctx.Data["NotStopTaskCount"] = NotStopTaskCount if ctx.Cloudbrain != nil { ctx.Data["branch_name"] = ctx.Cloudbrain.BranchName @@ -210,7 +213,7 @@ func prepareCloudbrainOneSpecs(ctx *context.Context) { } func CloudBrainNew(ctx *context.Context) { - err := cloudBrainNewDataPrepare(ctx) + err := cloudBrainNewDataPrepare(ctx, string(models.JobTypeDebug)) if err != nil { ctx.ServerError("get new cloudbrain info failed", err) return @@ -244,7 +247,7 @@ func cloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { isOk, err := lock.Lock(models.CloudbrainKeyDuration) if !isOk { log.Error("lock processed failed:%v", err, ctx.Data["MsgID"]) - cloudBrainNewDataPrepare(ctx) + cloudBrainNewDataPrepare(ctx, jobType) ctx.RenderWithErr(ctx.Tr("repo.cloudbrain_samejob_err"), tpl, &form) return } @@ -254,42 +257,42 @@ func cloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { if err == nil { if len(tasks) != 0 { log.Error("the job name did already exist", ctx.Data["MsgID"]) - cloudBrainNewDataPrepare(ctx) + cloudBrainNewDataPrepare(ctx, jobType) ctx.RenderWithErr("the job name did already exist", tpl, &form) return } } else { if !models.IsErrJobNotExist(err) { log.Error("system error, %v", err, ctx.Data["MsgID"]) - cloudBrainNewDataPrepare(ctx) + cloudBrainNewDataPrepare(ctx, jobType) ctx.RenderWithErr("system error", tpl, &form) return } } if !jobNamePattern.MatchString(displayJobName) { - cloudBrainNewDataPrepare(ctx) + cloudBrainNewDataPrepare(ctx, jobType) ctx.RenderWithErr(ctx.Tr("repo.cloudbrain_jobname_err"), tpl, &form) return } if jobType != string(models.JobTypeBenchmark) && jobType != string(models.JobTypeDebug) && jobType != string(models.JobTypeTrain) { log.Error("jobtype error:", jobType, ctx.Data["MsgID"]) - cloudBrainNewDataPrepare(ctx) + cloudBrainNewDataPrepare(ctx, jobType) ctx.RenderWithErr("jobtype error", tpl, &form) return } - count, err := models.GetCloudbrainCountByUserID(ctx.User.ID, jobType) + count, err := cloudbrainTask.GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeCloudBrainOne, jobType, models.GPUResource) if err != nil { log.Error("GetCloudbrainCountByUserID failed:%v", err, ctx.Data["MsgID"]) - cloudBrainNewDataPrepare(ctx) + cloudBrainNewDataPrepare(ctx, jobType) ctx.RenderWithErr("system error", tpl, &form) return } else { if count >= 1 { log.Error("the user already has running or waiting task", ctx.Data["MsgID"]) - cloudBrainNewDataPrepare(ctx) + cloudBrainNewDataPrepare(ctx, jobType) ctx.RenderWithErr(ctx.Tr("repo.cloudbrain.morethanonejob"), tpl, &form) return } @@ -301,7 +304,7 @@ func cloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { datasetInfos, datasetNames, err = models.GetDatasetInfo(uuids) if err != nil { log.Error("GetDatasetInfo failed: %v", err, ctx.Data["MsgID"]) - cloudBrainNewDataPrepare(ctx) + cloudBrainNewDataPrepare(ctx, jobType) ctx.RenderWithErr(ctx.Tr("cloudbrain.error.dataset_select"), tpl, &form) return } @@ -312,7 +315,7 @@ func cloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { bootFileExist, err := ctx.Repo.FileExists(bootFile, branchName) if err != nil || !bootFileExist { log.Error("Get bootfile error:", err, ctx.Data["MsgID"]) - cloudBrainNewDataPrepare(ctx) + cloudBrainNewDataPrepare(ctx, jobType) ctx.RenderWithErr(ctx.Tr("repo.cloudbrain_bootfile_err"), tpl, &form) return } @@ -320,7 +323,7 @@ func cloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { commandTrain, err := getTrainJobCommand(form) if err != nil { log.Error("getTrainJobCommand failed: %v", err) - cloudBrainNewDataPrepare(ctx) + cloudBrainNewDataPrepare(ctx, jobType) ctx.RenderWithErr(err.Error(), tpl, &form) return } @@ -333,7 +336,7 @@ func cloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { } errStr := loadCodeAndMakeModelPath(repo, codePath, branchName, jobName, cloudbrain.ModelMountPath) if errStr != "" { - cloudBrainNewDataPrepare(ctx) + cloudBrainNewDataPrepare(ctx, jobType) ctx.RenderWithErr(ctx.Tr(errStr), tpl, &form) return } @@ -346,14 +349,14 @@ func cloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { Cluster: models.OpenICluster, AiCenterCode: models.AICenterOfCloudBrainOne}) if err != nil || spec == nil { - cloudBrainNewDataPrepare(ctx) + cloudBrainNewDataPrepare(ctx, jobType) ctx.RenderWithErr("Resource specification not available", tpl, &form) return } if !account.IsPointBalanceEnough(ctx.User.ID, spec.UnitPrice) { log.Error("point balance is not enough,userId=%d specId=%d", ctx.User.ID, spec.ID) - cloudBrainNewDataPrepare(ctx) + cloudBrainNewDataPrepare(ctx, jobType) ctx.RenderWithErr(ctx.Tr("points.insufficient_points_balance"), tpl, &form) return } @@ -396,7 +399,7 @@ func cloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { err = cloudbrain.GenerateTask(req) if err != nil { - cloudBrainNewDataPrepare(ctx) + cloudBrainNewDataPrepare(ctx, jobType) ctx.RenderWithErr(err.Error(), tpl, &form) return } @@ -454,7 +457,7 @@ func CloudBrainInferenceJobCreate(ctx *context.Context, form auth.CreateCloudBra isOk, err := lock.Lock(models.CloudbrainKeyDuration) if !isOk { log.Error("lock processed failed:%v", err, ctx.Data["MsgID"]) - cloudBrainNewDataPrepare(ctx) + cloudBrainNewDataPrepare(ctx, jobType) ctx.RenderWithErr(ctx.Tr("repo.cloudbrain_samejob_err"), tpl, &form) return } @@ -465,7 +468,7 @@ func CloudBrainInferenceJobCreate(ctx *context.Context, form auth.CreateCloudBra command, err := getInferenceJobCommand(form) if err != nil { log.Error("getTrainJobCommand failed: %v", err) - cloudBrainNewDataPrepare(ctx) + cloudBrainNewDataPrepare(ctx, jobType) ctx.RenderWithErr(err.Error(), tpl, &form) return } @@ -474,21 +477,21 @@ func CloudBrainInferenceJobCreate(ctx *context.Context, form auth.CreateCloudBra if err == nil { if len(tasks) != 0 { log.Error("the job name did already exist", ctx.Data["MsgID"]) - cloudBrainNewDataPrepare(ctx) + cloudBrainNewDataPrepare(ctx, jobType) ctx.RenderWithErr("the job name did already exist", tpl, &form) return } } else { if !models.IsErrJobNotExist(err) { log.Error("system error, %v", err, ctx.Data["MsgID"]) - cloudBrainNewDataPrepare(ctx) + cloudBrainNewDataPrepare(ctx, jobType) ctx.RenderWithErr("system error", tpl, &form) return } } if !jobNamePattern.MatchString(displayJobName) { - cloudBrainNewDataPrepare(ctx) + cloudBrainNewDataPrepare(ctx, jobType) ctx.RenderWithErr(ctx.Tr("repo.cloudbrain_jobname_err"), tpl, &form) return } @@ -496,21 +499,21 @@ func CloudBrainInferenceJobCreate(ctx *context.Context, form auth.CreateCloudBra bootFileExist, err := ctx.Repo.FileExists(bootFile, branchName) if err != nil || !bootFileExist { log.Error("Get bootfile error:", err, ctx.Data["MsgID"]) - cloudBrainNewDataPrepare(ctx) + cloudBrainNewDataPrepare(ctx, jobType) ctx.RenderWithErr(ctx.Tr("repo.cloudbrain_bootfile_err"), tpl, &form) return } - count, err := models.GetCloudbrainCountByUserID(ctx.User.ID, jobType) + count, err := cloudbrainTask.GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeCloudBrainOne, jobType, models.GPUResource) if err != nil { log.Error("GetCloudbrainCountByUserID failed:%v", err, ctx.Data["MsgID"]) - cloudBrainNewDataPrepare(ctx) + cloudBrainNewDataPrepare(ctx, jobType) ctx.RenderWithErr("system error", tpl, &form) return } else { if count >= 1 { log.Error("the user already has running or waiting task", ctx.Data["MsgID"]) - cloudBrainNewDataPrepare(ctx) + cloudBrainNewDataPrepare(ctx, jobType) ctx.RenderWithErr(ctx.Tr("repo.cloudbrain.morethanonejob"), tpl, &form) return } @@ -521,7 +524,7 @@ func CloudBrainInferenceJobCreate(ctx *context.Context, form auth.CreateCloudBra } errStr := loadCodeAndMakeModelPath(repo, codePath, branchName, jobName, cloudbrain.ResultPath) if errStr != "" { - cloudBrainNewDataPrepare(ctx) + cloudBrainNewDataPrepare(ctx, jobType) ctx.RenderWithErr(ctx.Tr(errStr), tpl, &form) return } @@ -531,7 +534,7 @@ func CloudBrainInferenceJobCreate(ctx *context.Context, form auth.CreateCloudBra datasetInfos, datasetNames, err := models.GetDatasetInfo(uuid) if err != nil { log.Error("GetDatasetInfo failed: %v", err, ctx.Data["MsgID"]) - cloudBrainNewDataPrepare(ctx) + cloudBrainNewDataPrepare(ctx, jobType) ctx.RenderWithErr(ctx.Tr("cloudbrain.error.dataset_select"), tpl, &form) return } @@ -541,13 +544,13 @@ func CloudBrainInferenceJobCreate(ctx *context.Context, form auth.CreateCloudBra Cluster: models.OpenICluster, AiCenterCode: models.AICenterOfCloudBrainOne}) if err != nil || spec == nil { - cloudBrainNewDataPrepare(ctx) + cloudBrainNewDataPrepare(ctx, jobType) ctx.RenderWithErr("Resource specification not available", tpl, &form) return } if !account.IsPointBalanceEnough(ctx.User.ID, spec.UnitPrice) { log.Error("point balance is not enough,userId=%d specId=%d", ctx.User.ID, spec.ID) - cloudBrainNewDataPrepare(ctx) + cloudBrainNewDataPrepare(ctx, jobType) ctx.RenderWithErr(ctx.Tr("points.insufficient_points_balance"), tpl, &form) return } @@ -582,7 +585,7 @@ func CloudBrainInferenceJobCreate(ctx *context.Context, form auth.CreateCloudBra err = cloudbrain.GenerateTask(req) if err != nil { - cloudBrainNewDataPrepare(ctx) + cloudBrainNewDataPrepare(ctx, jobType) ctx.RenderWithErr(err.Error(), tpl, &form) return } @@ -682,7 +685,7 @@ func CloudBrainRestart(ctx *context.Context) { break } - count, err := models.GetCloudbrainCountByUserID(ctx.User.ID, string(models.JobTypeDebug)) + count, err := cloudbrainTask.GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeCloudBrainOne, string(models.JobTypeDebug), models.GPUResource) if err != nil { log.Error("GetCloudbrainCountByUserID failed:%v", err, ctx.Data["MsgID"]) resultCode = "-1" @@ -2222,7 +2225,7 @@ func CloudBrainBenchmarkNew(ctx *context.Context) { ctx.Data["description"] = "" ctx.Data["benchmarkTypeID"] = -1 ctx.Data["benchmark_child_types_id_hidden"] = -1 - err := cloudBrainNewDataPrepare(ctx) + err := cloudBrainNewDataPrepare(ctx, string(models.JobTypeBenchmark)) if err != nil { ctx.ServerError("get new cloudbrain info failed", err) return @@ -2327,6 +2330,7 @@ func BenchMarkAlgorithmCreate(ctx *context.Context, form auth.CreateCloudBrainFo benchmarkTypeID := form.BenchmarkTypeID benchmarkChildTypeID := form.BenchmarkChildTypeID repo := ctx.Repo.Repository + jobType := form.JobType ctx.Data["description"] = form.Description ctx.Data["benchmarkTypeID"] = benchmarkTypeID @@ -2336,31 +2340,31 @@ func BenchMarkAlgorithmCreate(ctx *context.Context, form auth.CreateCloudBrainFo isOk, err := lock.Lock(models.CloudbrainKeyDuration) if !isOk { log.Error("lock processed failed:%v", err, ctx.Data["MsgID"]) - cloudBrainNewDataPrepare(ctx) + cloudBrainNewDataPrepare(ctx, jobType) ctx.RenderWithErr(ctx.Tr("repo.cloudbrain_samejob_err"), tplCloudBrainBenchmarkNew, &form) return } defer lock.UnLock() - tasks, err := models.GetCloudbrainsByDisplayJobName(repo.ID, string(models.JobTypeBenchmark), displayJobName) + tasks, err := models.GetCloudbrainsByDisplayJobName(repo.ID, jobType, displayJobName) if err == nil { if len(tasks) != 0 { log.Error("the job name did already exist", ctx.Data["MsgID"]) - cloudBrainNewDataPrepare(ctx) + cloudBrainNewDataPrepare(ctx, jobType) ctx.RenderWithErr("the job name did already exist", tplCloudBrainBenchmarkNew, &form) return } } else { if !models.IsErrJobNotExist(err) { log.Error("system error, %v", err, ctx.Data["MsgID"]) - cloudBrainNewDataPrepare(ctx) + cloudBrainNewDataPrepare(ctx, jobType) ctx.RenderWithErr("system error", tplCloudBrainBenchmarkNew, &form) return } } if !jobNamePattern.MatchString(jobName) { - cloudBrainNewDataPrepare(ctx) + cloudBrainNewDataPrepare(ctx, jobType) ctx.RenderWithErr(ctx.Tr("repo.cloudbrain_jobname_err"), tplCloudBrainBenchmarkNew, &form) return } @@ -2368,7 +2372,7 @@ func BenchMarkAlgorithmCreate(ctx *context.Context, form auth.CreateCloudBrainFo childInfo, err := getBenchmarkAttachment(benchmarkTypeID, benchmarkChildTypeID, ctx) if err != nil { log.Error("getBenchmarkAttachment failed:%v", err, ctx.Data["MsgID"]) - cloudBrainNewDataPrepare(ctx) + cloudBrainNewDataPrepare(ctx, jobType) ctx.RenderWithErr("benchmark type error", tplCloudBrainBenchmarkNew, &form) return } @@ -2379,27 +2383,27 @@ func BenchMarkAlgorithmCreate(ctx *context.Context, form auth.CreateCloudBrainFo Cluster: models.OpenICluster, AiCenterCode: models.AICenterOfCloudBrainOne}) if err != nil || spec == nil { - cloudBrainNewDataPrepare(ctx) + cloudBrainNewDataPrepare(ctx, jobType) ctx.RenderWithErr("Resource specification not available", tplCloudBrainBenchmarkNew, &form) return } if !account.IsPointBalanceEnough(ctx.User.ID, spec.UnitPrice) { log.Error("point balance is not enough,userId=%d specId=%d", ctx.User.ID, spec.ID) - cloudBrainNewDataPrepare(ctx) + cloudBrainNewDataPrepare(ctx, jobType) ctx.RenderWithErr(ctx.Tr("points.insufficient_points_balance"), tplCloudBrainBenchmarkNew, &form) return } - count, err := models.GetBenchmarkCountByUserID(ctx.User.ID) + count, err := cloudbrainTask.GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeCloudBrainOne, jobType, models.GPUResource) if err != nil { log.Error("GetCloudbrainCountByUserID failed:%v", err, ctx.Data["MsgID"]) - cloudBrainNewDataPrepare(ctx) + cloudBrainNewDataPrepare(ctx, jobType) ctx.RenderWithErr("system error", tplCloudBrainBenchmarkNew, &form) return } else { if count >= 1 { log.Error("the user already has running or waiting task", ctx.Data["MsgID"]) - cloudBrainNewDataPrepare(ctx) + cloudBrainNewDataPrepare(ctx, jobType) ctx.RenderWithErr(ctx.Tr("repo.cloudbrain.morethanonejob"), tplCloudBrainBenchmarkNew, &form) return } @@ -2408,7 +2412,7 @@ func BenchMarkAlgorithmCreate(ctx *context.Context, form auth.CreateCloudBrainFo os.RemoveAll(codePath) if err := downloadCode(repo, codePath, cloudbrain.DefaultBranchName); err != nil { log.Error("downloadCode failed, %v", err, ctx.Data["MsgID"]) - cloudBrainNewDataPrepare(ctx) + cloudBrainNewDataPrepare(ctx, jobType) ctx.RenderWithErr("system error", tplCloudBrainBenchmarkNew, &form) return } @@ -2417,11 +2421,11 @@ func BenchMarkAlgorithmCreate(ctx *context.Context, form auth.CreateCloudBrainFo if os.IsNotExist(err) { // file does not exist log.Error("train.py does not exist, %v", err, ctx.Data["MsgID"]) - cloudBrainNewDataPrepare(ctx) + cloudBrainNewDataPrepare(ctx, jobType) ctx.RenderWithErr("train.py does not exist", tplCloudBrainBenchmarkNew, &form) } else { log.Error("Stat failed, %v", err, ctx.Data["MsgID"]) - cloudBrainNewDataPrepare(ctx) + cloudBrainNewDataPrepare(ctx, jobType) ctx.RenderWithErr("system error", tplCloudBrainBenchmarkNew, &form) } return @@ -2429,11 +2433,11 @@ func BenchMarkAlgorithmCreate(ctx *context.Context, form auth.CreateCloudBrainFo if os.IsNotExist(err) { // file does not exist log.Error("test.py does not exist, %v", err, ctx.Data["MsgID"]) - cloudBrainNewDataPrepare(ctx) + cloudBrainNewDataPrepare(ctx, jobType) ctx.RenderWithErr("test.py does not exist", tplCloudBrainBenchmarkNew, &form) } else { log.Error("Stat failed, %v", err, ctx.Data["MsgID"]) - cloudBrainNewDataPrepare(ctx) + cloudBrainNewDataPrepare(ctx, jobType) ctx.RenderWithErr("system error", tplCloudBrainBenchmarkNew, &form) } return @@ -2441,7 +2445,7 @@ func BenchMarkAlgorithmCreate(ctx *context.Context, form auth.CreateCloudBrainFo if err := uploadCodeToMinio(codePath+"/", jobName, cloudbrain.CodeMountPath+"/"); err != nil { log.Error("uploadCodeToMinio failed, %v", err, ctx.Data["MsgID"]) - cloudBrainNewDataPrepare(ctx) + cloudBrainNewDataPrepare(ctx, jobType) ctx.RenderWithErr("system error", tplCloudBrainBenchmarkNew, &form) return } @@ -2466,7 +2470,7 @@ func BenchMarkAlgorithmCreate(ctx *context.Context, form auth.CreateCloudBrainFo datasetInfos, datasetNames, err := models.GetDatasetInfo(uuid) if err != nil { log.Error("GetDatasetInfo failed: %v", err, ctx.Data["MsgID"]) - cloudBrainNewDataPrepare(ctx) + cloudBrainNewDataPrepare(ctx, jobType) ctx.RenderWithErr(ctx.Tr("cloudbrain.error.dataset_select"), tplCloudBrainBenchmarkNew, &form) return } @@ -2500,7 +2504,7 @@ func BenchMarkAlgorithmCreate(ctx *context.Context, form auth.CreateCloudBrainFo err = cloudbrain.GenerateTask(req) if err != nil { - cloudBrainNewDataPrepare(ctx) + cloudBrainNewDataPrepare(ctx, jobType) ctx.RenderWithErr(err.Error(), tplCloudBrainBenchmarkNew, &form) return } @@ -2526,7 +2530,7 @@ func ModelBenchmarkCreate(ctx *context.Context, form auth.CreateCloudBrainForm) isOk, err := lock.Lock(models.CloudbrainKeyDuration) if !isOk { log.Error("lock processed failed:%v", err, ctx.Data["MsgID"]) - cloudBrainNewDataPrepare(ctx) + cloudBrainNewDataPrepare(ctx, jobType) ctx.RenderWithErr(ctx.Tr("repo.cloudbrain_samejob_err"), tpl, &form) return } @@ -2536,42 +2540,42 @@ func ModelBenchmarkCreate(ctx *context.Context, form auth.CreateCloudBrainForm) if err == nil { if len(tasks) != 0 { log.Error("the job name did already exist", ctx.Data["MsgID"]) - cloudBrainNewDataPrepare(ctx) + cloudBrainNewDataPrepare(ctx, jobType) ctx.RenderWithErr("the job name did already exist", tpl, &form) return } } else { if !models.IsErrJobNotExist(err) { log.Error("system error, %v", err, ctx.Data["MsgID"]) - cloudBrainNewDataPrepare(ctx) + cloudBrainNewDataPrepare(ctx, jobType) ctx.RenderWithErr("system error", tpl, &form) return } } if !jobNamePattern.MatchString(displayJobName) { - cloudBrainNewDataPrepare(ctx) + cloudBrainNewDataPrepare(ctx, jobType) ctx.RenderWithErr(ctx.Tr("repo.cloudbrain_jobname_err"), tpl, &form) return } if jobType != string(models.JobTypeSnn4imagenet) && jobType != string(models.JobTypeBrainScore) { log.Error("jobtype error:", jobType, ctx.Data["MsgID"]) - cloudBrainNewDataPrepare(ctx) + cloudBrainNewDataPrepare(ctx, jobType) ctx.RenderWithErr("jobtype error", tpl, &form) return } - count, err := models.GetBenchmarkCountByUserID(ctx.User.ID) + count, err := cloudbrainTask.GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeCloudBrainOne, jobType, models.GPUResource) if err != nil { log.Error("GetCloudbrainCountByUserID failed:%v", err, ctx.Data["MsgID"]) - cloudBrainNewDataPrepare(ctx) + cloudBrainNewDataPrepare(ctx, jobType) ctx.RenderWithErr("system error", tpl, &form) return } else { if count >= 1 { log.Error("the user already has running or waiting task", ctx.Data["MsgID"]) - cloudBrainNewDataPrepare(ctx) + cloudBrainNewDataPrepare(ctx, jobType) ctx.RenderWithErr(ctx.Tr("repo.cloudbrain.morethanonejob"), tpl, &form) return } @@ -2603,7 +2607,7 @@ func ModelBenchmarkCreate(ctx *context.Context, form auth.CreateCloudBrainForm) datasetInfos, datasetNames, err := models.GetDatasetInfo(uuid) if err != nil { log.Error("GetDatasetInfo failed: %v", err, ctx.Data["MsgID"]) - cloudBrainNewDataPrepare(ctx) + cloudBrainNewDataPrepare(ctx, jobType) ctx.RenderWithErr(ctx.Tr("cloudbrain.error.dataset_select"), tpl, &form) return } @@ -2613,14 +2617,14 @@ func ModelBenchmarkCreate(ctx *context.Context, form auth.CreateCloudBrainForm) Cluster: models.OpenICluster, AiCenterCode: models.AICenterOfCloudBrainOne}) if err != nil || spec == nil { - cloudBrainNewDataPrepare(ctx) + cloudBrainNewDataPrepare(ctx, jobType) ctx.RenderWithErr("Resource specification not available", tpl, &form) return } if !account.IsPointBalanceEnough(ctx.User.ID, spec.UnitPrice) { log.Error("point balance is not enough,userId=%d specId=%d", ctx.User.ID, spec.ID) - cloudBrainNewDataPrepare(ctx) + cloudBrainNewDataPrepare(ctx, jobType) ctx.RenderWithErr(ctx.Tr("points.insufficient_points_balance"), tpl, &form) return } @@ -2654,7 +2658,7 @@ func ModelBenchmarkCreate(ctx *context.Context, form auth.CreateCloudBrainForm) err = cloudbrain.GenerateTask(req) if err != nil { - cloudBrainNewDataPrepare(ctx) + cloudBrainNewDataPrepare(ctx, jobType) ctx.RenderWithErr(err.Error(), tpl, &form) return } @@ -2701,7 +2705,7 @@ func CloudBrainTrainJobVersionNew(ctx *context.Context) { } func cloudBrainTrainJobCreate(ctx *context.Context) { - err := cloudBrainNewDataPrepare(ctx) + err := cloudBrainNewDataPrepare(ctx, string(models.JobTypeTrain)) if err != nil { ctx.ServerError("get new train-job info failed", err) return @@ -2710,7 +2714,7 @@ func cloudBrainTrainJobCreate(ctx *context.Context) { } func InferenceCloudBrainJobNew(ctx *context.Context) { - err := cloudBrainNewDataPrepare(ctx) + err := cloudBrainNewDataPrepare(ctx, string(models.JobTypeInference)) if err != nil { ctx.ServerError("get new train-job info failed", err) return diff --git a/routers/repo/grampus.go b/routers/repo/grampus.go index b78bdebd3..d901298b7 100755 --- a/routers/repo/grampus.go +++ b/routers/repo/grampus.go @@ -12,6 +12,8 @@ import ( "strings" "time" + "code.gitea.io/gitea/services/cloudbrain/cloudbrainTask" + "code.gitea.io/gitea/modules/dataset" "code.gitea.io/gitea/services/cloudbrain/resource" @@ -135,10 +137,15 @@ func grampusTrainJobNewDataPrepare(ctx *context.Context, processType string) err ctx.Data["datasetType"] = models.TypeCloudBrainOne waitCount := cloudbrain.GetWaitingCloudbrainCount(models.TypeC2Net, models.GPUResource, models.JobTypeTrain) ctx.Data["WaitCount"] = waitCount + NotStopTaskCount, _ := cloudbrainTask.GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeC2Net, string(models.JobTypeTrain), models.GPUResource) + ctx.Data["NotStopTaskCount"] = NotStopTaskCount + } else if processType == grampus.ProcessorTypeNPU { ctx.Data["datasetType"] = models.TypeCloudBrainTwo waitCount := cloudbrain.GetWaitingCloudbrainCount(models.TypeC2Net, models.NPUResource, models.JobTypeTrain) ctx.Data["WaitCount"] = waitCount + NotStopTaskCount, _ := cloudbrainTask.GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeC2Net, string(models.JobTypeTrain), models.NPUResource) + ctx.Data["NotStopTaskCount"] = NotStopTaskCount } if ctx.Cloudbrain != nil { @@ -300,7 +307,7 @@ func grampusTrainJobGpuCreate(ctx *context.Context, form auth.CreateGrampusTrain } //check count limit - count, err := models.GetGrampusCountByUserID(ctx.User.ID, string(models.JobTypeTrain), models.GPUResource) + count, err := cloudbrainTask.GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeC2Net, string(models.JobTypeTrain), models.GPUResource) if err != nil { log.Error("GetGrampusCountByUserID failed:%v", err, ctx.Data["MsgID"]) grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeGPU) @@ -570,7 +577,7 @@ func grampusTrainJobNpuCreate(ctx *context.Context, form auth.CreateGrampusTrain } //check count limit - count, err := models.GetGrampusCountByUserID(ctx.User.ID, string(models.JobTypeTrain), models.NPUResource) + count, err := cloudbrainTask.GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeC2Net, string(models.JobTypeTrain), models.NPUResource) if err != nil { log.Error("GetGrampusCountByUserID failed:%v", err, ctx.Data["MsgID"]) grampusTrainJobNewDataPrepare(ctx, grampus.ProcessorTypeNPU) diff --git a/routers/repo/modelarts.go b/routers/repo/modelarts.go index 6e44b3cd2..2a10da264 100755 --- a/routers/repo/modelarts.go +++ b/routers/repo/modelarts.go @@ -15,6 +15,8 @@ import ( "time" "unicode/utf8" + "code.gitea.io/gitea/services/cloudbrain/cloudbrainTask" + "code.gitea.io/gitea/modules/dataset" "code.gitea.io/gitea/modules/modelarts_cd" @@ -144,6 +146,8 @@ func notebookNewDataPrepare(ctx *context.Context) error { waitCount := cloudbrain.GetWaitingCloudbrainCount(models.TypeCloudBrainTwo, "") ctx.Data["WaitCount"] = waitCount + NotStopTaskCount, _ := cloudbrainTask.GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeCloudBrainTwo, string(models.JobTypeDebug), models.NPUResource) + ctx.Data["NotStopTaskCount"] = NotStopTaskCount return nil } @@ -162,50 +166,6 @@ func prepareCloudbrainTwoDebugSpecs(ctx *context.Context) { ctx.Data["Specs"] = noteBookSpecs } -func NotebookCreate(ctx *context.Context, form auth.CreateModelArtsNotebookForm) { - ctx.Data["PageIsNotebook"] = true - jobName := form.JobName - uuid := form.Attachment - description := form.Description - flavor := form.Flavor - - count, err := models.GetCloudbrainNotebookCountByUserID(ctx.User.ID) - if err != nil { - log.Error("GetCloudbrainNotebookCountByUserID failed:%v", err, ctx.Data["MsgID"]) - cloudBrainNewDataPrepare(ctx) - ctx.RenderWithErr("system error", tplModelArtsNotebookNew, &form) - return - } else { - if count >= 1 { - log.Error("the user already has running or waiting task", ctx.Data["MsgID"]) - cloudBrainNewDataPrepare(ctx) - ctx.RenderWithErr("you have already a running or waiting task, can not create more", tplModelArtsNotebookNew, &form) - return - } - } - _, err = models.GetCloudbrainByName(jobName) - if err == nil { - log.Error("the job name did already exist", ctx.Data["MsgID"]) - cloudBrainNewDataPrepare(ctx) - ctx.RenderWithErr("the job name did already exist", tplModelArtsNotebookNew, &form) - return - } else { - if !models.IsErrJobNotExist(err) { - log.Error("system error, %v", err, ctx.Data["MsgID"]) - cloudBrainNewDataPrepare(ctx) - ctx.RenderWithErr("system error", tplModelArtsNotebookNew, &form) - return - } - } - - err = modelarts.GenerateTask(ctx, jobName, uuid, description, flavor) - if err != nil { - ctx.RenderWithErr(err.Error(), tplModelArtsNotebookNew, &form) - return - } - ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/debugjob?debugListType=all") -} - func Notebook2Create(ctx *context.Context, form auth.CreateModelArtsNotebookForm) { ctx.Data["PageIsNotebook"] = true displayJobName := form.DisplayJobName @@ -225,7 +185,8 @@ func Notebook2Create(ctx *context.Context, form auth.CreateModelArtsNotebookForm } defer lock.UnLock() - count, err := models.GetCloudbrainNotebookCountByUserID(ctx.User.ID) + count, err := cloudbrainTask.GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeCloudBrainTwo, string(models.JobTypeDebug), models.NPUResource) + if err != nil { log.Error("GetCloudbrainNotebookCountByUserID failed:%v", err, ctx.Data["MsgID"]) notebookNewDataPrepare(ctx) @@ -272,7 +233,7 @@ func Notebook2Create(ctx *context.Context, form auth.CreateModelArtsNotebookForm } if !account.IsPointBalanceEnough(ctx.User.ID, spec.UnitPrice) { log.Error("point balance is not enough,userId=%d specId=%d ", ctx.User.ID, spec.ID) - cloudBrainNewDataPrepare(ctx) + notebookNewDataPrepare(ctx) ctx.RenderWithErr(ctx.Tr("points.insufficient_points_balance"), tplModelArtsNotebookNew, &form) return } @@ -450,7 +411,8 @@ func NotebookRestart(ctx *context.Context) { break } - count, err := models.GetCloudbrainNotebookCountByUserID(ctx.User.ID) + count, err := cloudbrainTask.GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeCloudBrainTwo, string(models.JobTypeDebug), models.NPUResource) + if err != nil { log.Error("GetCloudbrainNotebookCountByUserID failed:%v", err, ctx.Data["MsgID"]) errorMsg = "system error" @@ -798,6 +760,8 @@ func trainJobNewDataPrepare(ctx *context.Context) error { ctx.Data["datasetType"] = models.TypeCloudBrainTwo waitCount := cloudbrain.GetWaitingCloudbrainCount(models.TypeCloudBrainTwo, "") ctx.Data["WaitCount"] = waitCount + NotStopTaskCount, _ := cloudbrainTask.GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeCloudBrainTwo, string(models.JobTypeTrain), models.NPUResource) + ctx.Data["NotStopTaskCount"] = NotStopTaskCount setMultiNodeIfConfigureMatch(ctx) @@ -966,6 +930,8 @@ func trainJobNewVersionDataPrepare(ctx *context.Context) error { ctx.Data["config_list"] = configList.ParaConfigs waitCount := cloudbrain.GetWaitingCloudbrainCount(models.TypeCloudBrainTwo, "") ctx.Data["WaitCount"] = waitCount + NotStopTaskCount, _ := cloudbrainTask.GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeCloudBrainTwo, string(models.JobTypeTrain), models.NPUResource) + ctx.Data["NotStopTaskCount"] = NotStopTaskCount return nil } @@ -1012,7 +978,8 @@ func TrainJobCreate(ctx *context.Context, form auth.CreateModelArtsTrainJobForm) } defer lock.UnLock() - count, err := models.GetCloudbrainTrainJobCountByUserID(ctx.User.ID) + count, err := cloudbrainTask.GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeCloudBrainTwo, string(models.JobTypeTrain), models.NPUResource) + if err != nil { log.Error("GetCloudbrainTrainJobCountByUserID failed:%v", err, ctx.Data["MsgID"]) trainJobNewDataPrepare(ctx) @@ -1356,7 +1323,7 @@ func TrainJobCreateVersion(ctx *context.Context, form auth.CreateModelArtsTrainJ return } - count, err := models.GetCloudbrainTrainJobCountByUserID(ctx.User.ID) + count, err := cloudbrainTask.GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeCloudBrainTwo, string(models.JobTypeTrain), models.NPUResource) if err != nil { log.Error("GetCloudbrainTrainJobCountByUserID failed:%v", err, ctx.Data["MsgID"]) trainJobNewVersionDataPrepare(ctx) @@ -2007,7 +1974,8 @@ func InferenceJobCreate(ctx *context.Context, form auth.CreateModelArtsInference } defer lock.UnLock() - count, err := models.GetCloudbrainInferenceJobCountByUserID(ctx.User.ID) + count, err := cloudbrainTask.GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeCloudBrainTwo, string(models.JobTypeInference), models.NPUResource) + if err != nil { log.Error("GetCloudbrainInferenceJobCountByUserID failed:%v", err, ctx.Data["MsgID"]) inferenceJobErrorNewDataPrepare(ctx, form) @@ -2409,6 +2377,8 @@ func inferenceJobNewDataPrepare(ctx *context.Context) error { ctx.Data["datasetType"] = models.TypeCloudBrainTwo waitCount := cloudbrain.GetWaitingCloudbrainCount(models.TypeCloudBrainTwo, "") ctx.Data["WaitCount"] = waitCount + NotStopTaskCount, _ := cloudbrainTask.GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeCloudBrainTwo, string(models.JobTypeInference), models.NPUResource) + ctx.Data["NotStopTaskCount"] = NotStopTaskCount return nil } diff --git a/services/cloudbrain/cloudbrainTask/count.go b/services/cloudbrain/cloudbrainTask/count.go new file mode 100644 index 000000000..25d56b0b6 --- /dev/null +++ b/services/cloudbrain/cloudbrainTask/count.go @@ -0,0 +1,86 @@ +package cloudbrainTask + +import ( + "fmt" + "strconv" + + "code.gitea.io/gitea/models" +) + +type StatusInfo struct { + CloudBrainTypes []int + JobType []models.JobType + NotFinalStatuses []string + ComputeResource string +} + +var cloudbrainOneNotFinalStatuses = []string{string(models.JobWaiting), string(models.JobRunning)} +var cloudbrainTwoNotFinalStatuses = []string{string(models.ModelArtsTrainJobInit), string(models.ModelArtsTrainJobImageCreating), string(models.ModelArtsTrainJobSubmitTrying), string(models.ModelArtsTrainJobWaiting), string(models.ModelArtsTrainJobRunning), string(models.ModelArtsTrainJobScaling), string(models.ModelArtsTrainJobCheckInit), string(models.ModelArtsTrainJobCheckRunning), string(models.ModelArtsTrainJobCheckRunningCompleted)} +var grampusTwoNotFinalStatuses = []string{models.GrampusStatusWaiting, models.GrampusStatusRunning} +var StatusInfoDict = map[string]StatusInfo{string(models.JobTypeDebug) + "-" + strconv.Itoa(models.TypeCloudBrainOne): { + CloudBrainTypes: []int{models.TypeCloudBrainOne}, + JobType: []models.JobType{models.JobTypeDebug}, + NotFinalStatuses: cloudbrainOneNotFinalStatuses, + ComputeResource: models.GPUResource, +}, string(models.JobTypeTrain) + "-" + strconv.Itoa(models.TypeCloudBrainOne): { + CloudBrainTypes: []int{models.TypeCloudBrainOne}, + JobType: []models.JobType{models.JobTypeTrain}, + NotFinalStatuses: cloudbrainOneNotFinalStatuses, + ComputeResource: models.GPUResource, +}, string(models.JobTypeInference) + "-" + strconv.Itoa(models.TypeCloudBrainOne): { + CloudBrainTypes: []int{models.TypeCloudBrainOne}, + JobType: []models.JobType{models.JobTypeInference}, + NotFinalStatuses: cloudbrainOneNotFinalStatuses, + ComputeResource: models.GPUResource, +}, string(models.JobTypeBenchmark) + "-" + strconv.Itoa(models.TypeCloudBrainOne): { + CloudBrainTypes: []int{models.TypeCloudBrainOne}, + JobType: []models.JobType{models.JobTypeBenchmark, models.JobTypeModelSafety, models.JobTypeBrainScore, models.JobTypeSnn4imagenet}, + NotFinalStatuses: cloudbrainOneNotFinalStatuses, + ComputeResource: models.GPUResource, +}, string(models.JobTypeDebug) + "-" + strconv.Itoa(models.TypeCloudBrainTwo): { + CloudBrainTypes: []int{models.TypeCloudBrainTwo, models.TypeCDCenter}, + JobType: []models.JobType{models.JobTypeDebug}, + NotFinalStatuses: []string{string(models.ModelArtsCreateQueue), string(models.ModelArtsCreating), string(models.ModelArtsStarting), string(models.ModelArtsReadyToStart), string(models.ModelArtsResizing), string(models.ModelArtsStartQueuing), string(models.ModelArtsRunning), string(models.ModelArtsRestarting)}, + ComputeResource: models.NPUResource, +}, string(models.JobTypeTrain) + "-" + strconv.Itoa(models.TypeCloudBrainTwo): { + CloudBrainTypes: []int{models.TypeCloudBrainTwo}, + JobType: []models.JobType{models.JobTypeTrain}, + NotFinalStatuses: cloudbrainTwoNotFinalStatuses, + ComputeResource: models.NPUResource, +}, string(models.JobTypeInference) + "-" + strconv.Itoa(models.TypeCloudBrainTwo): { + CloudBrainTypes: []int{models.TypeCloudBrainTwo}, + JobType: []models.JobType{models.JobTypeTrain}, + NotFinalStatuses: cloudbrainTwoNotFinalStatuses, + ComputeResource: models.NPUResource, +}, string(models.JobTypeTrain) + "-" + strconv.Itoa(models.TypeC2Net) + "-" + models.GPUResource: { + CloudBrainTypes: []int{models.TypeC2Net}, + JobType: []models.JobType{models.JobTypeTrain}, + NotFinalStatuses: grampusTwoNotFinalStatuses, + ComputeResource: models.GPUResource, +}, string(models.JobTypeTrain) + "-" + strconv.Itoa(models.TypeC2Net) + "-" + models.NPUResource: { + CloudBrainTypes: []int{models.TypeC2Net}, + JobType: []models.JobType{models.JobTypeTrain}, + NotFinalStatuses: grampusTwoNotFinalStatuses, + ComputeResource: models.NPUResource, +}} + +func GetNotFinalStatusTaskCount(uid int64, cloudbrainType int, jobType string, computeResource ...string) (int, error) { + jobNewType := jobType + if jobType == string(models.JobTypeSnn4imagenet) || jobType == string(models.JobTypeBrainScore) { + jobNewType = string(models.JobTypeBenchmark) + } + + key := jobNewType + "-" + strconv.Itoa(cloudbrainType) + if len(computeResource) > 0 { + key = key + "-" + computeResource[0] + } + + if statusInfo, ok := StatusInfoDict[key]; ok { + + return models.GetNotFinalStatusTaskCount(uid, statusInfo.NotFinalStatuses, statusInfo.JobType, statusInfo.CloudBrainTypes, statusInfo.ComputeResource) + + } else { + return 0, fmt.Errorf("Can not find the status info.") + } + +} From c634b0e80359e1f01fdd5199da19c32aaa2e842a Mon Sep 17 00:00:00 2001 From: ychao_1983 Date: Fri, 21 Oct 2022 16:18:17 +0800 Subject: [PATCH 18/29] =?UTF-8?q?=E6=8F=90=E4=BA=A4=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- routers/repo/cloudbrain.go | 12 ++++++------ routers/repo/modelarts.go | 18 +++++++++--------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/routers/repo/cloudbrain.go b/routers/repo/cloudbrain.go index f5a43e697..92c95de4e 100755 --- a/routers/repo/cloudbrain.go +++ b/routers/repo/cloudbrain.go @@ -149,7 +149,7 @@ func cloudBrainNewDataPrepare(ctx *context.Context, jobType string) error { defaultMode = "alogrithm" } ctx.Data["benchmarkMode"] = defaultMode - NotStopTaskCount, _ := cloudbrainTask.GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeCloudBrainOne, jobType, models.GPUResource) + NotStopTaskCount, _ := cloudbrainTask.GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeCloudBrainOne, jobType) ctx.Data["NotStopTaskCount"] = NotStopTaskCount if ctx.Cloudbrain != nil { @@ -283,7 +283,7 @@ func cloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { return } - count, err := cloudbrainTask.GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeCloudBrainOne, jobType, models.GPUResource) + count, err := cloudbrainTask.GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeCloudBrainOne, jobType) if err != nil { log.Error("GetCloudbrainCountByUserID failed:%v", err, ctx.Data["MsgID"]) cloudBrainNewDataPrepare(ctx, jobType) @@ -504,7 +504,7 @@ func CloudBrainInferenceJobCreate(ctx *context.Context, form auth.CreateCloudBra return } - count, err := cloudbrainTask.GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeCloudBrainOne, jobType, models.GPUResource) + count, err := cloudbrainTask.GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeCloudBrainOne, jobType) if err != nil { log.Error("GetCloudbrainCountByUserID failed:%v", err, ctx.Data["MsgID"]) cloudBrainNewDataPrepare(ctx, jobType) @@ -685,7 +685,7 @@ func CloudBrainRestart(ctx *context.Context) { break } - count, err := cloudbrainTask.GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeCloudBrainOne, string(models.JobTypeDebug), models.GPUResource) + count, err := cloudbrainTask.GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeCloudBrainOne, string(models.JobTypeDebug)) if err != nil { log.Error("GetCloudbrainCountByUserID failed:%v", err, ctx.Data["MsgID"]) resultCode = "-1" @@ -2394,7 +2394,7 @@ func BenchMarkAlgorithmCreate(ctx *context.Context, form auth.CreateCloudBrainFo return } - count, err := cloudbrainTask.GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeCloudBrainOne, jobType, models.GPUResource) + count, err := cloudbrainTask.GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeCloudBrainOne, jobType) if err != nil { log.Error("GetCloudbrainCountByUserID failed:%v", err, ctx.Data["MsgID"]) cloudBrainNewDataPrepare(ctx, jobType) @@ -2566,7 +2566,7 @@ func ModelBenchmarkCreate(ctx *context.Context, form auth.CreateCloudBrainForm) return } - count, err := cloudbrainTask.GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeCloudBrainOne, jobType, models.GPUResource) + count, err := cloudbrainTask.GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeCloudBrainOne, jobType) if err != nil { log.Error("GetCloudbrainCountByUserID failed:%v", err, ctx.Data["MsgID"]) cloudBrainNewDataPrepare(ctx, jobType) diff --git a/routers/repo/modelarts.go b/routers/repo/modelarts.go index 2a10da264..07c1fcd3e 100755 --- a/routers/repo/modelarts.go +++ b/routers/repo/modelarts.go @@ -146,7 +146,7 @@ func notebookNewDataPrepare(ctx *context.Context) error { waitCount := cloudbrain.GetWaitingCloudbrainCount(models.TypeCloudBrainTwo, "") ctx.Data["WaitCount"] = waitCount - NotStopTaskCount, _ := cloudbrainTask.GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeCloudBrainTwo, string(models.JobTypeDebug), models.NPUResource) + NotStopTaskCount, _ := cloudbrainTask.GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeCloudBrainTwo, string(models.JobTypeDebug)) ctx.Data["NotStopTaskCount"] = NotStopTaskCount return nil @@ -185,7 +185,7 @@ func Notebook2Create(ctx *context.Context, form auth.CreateModelArtsNotebookForm } defer lock.UnLock() - count, err := cloudbrainTask.GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeCloudBrainTwo, string(models.JobTypeDebug), models.NPUResource) + count, err := cloudbrainTask.GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeCloudBrainTwo, string(models.JobTypeDebug)) if err != nil { log.Error("GetCloudbrainNotebookCountByUserID failed:%v", err, ctx.Data["MsgID"]) @@ -411,7 +411,7 @@ func NotebookRestart(ctx *context.Context) { break } - count, err := cloudbrainTask.GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeCloudBrainTwo, string(models.JobTypeDebug), models.NPUResource) + count, err := cloudbrainTask.GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeCloudBrainTwo, string(models.JobTypeDebug)) if err != nil { log.Error("GetCloudbrainNotebookCountByUserID failed:%v", err, ctx.Data["MsgID"]) @@ -760,7 +760,7 @@ func trainJobNewDataPrepare(ctx *context.Context) error { ctx.Data["datasetType"] = models.TypeCloudBrainTwo waitCount := cloudbrain.GetWaitingCloudbrainCount(models.TypeCloudBrainTwo, "") ctx.Data["WaitCount"] = waitCount - NotStopTaskCount, _ := cloudbrainTask.GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeCloudBrainTwo, string(models.JobTypeTrain), models.NPUResource) + NotStopTaskCount, _ := cloudbrainTask.GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeCloudBrainTwo, string(models.JobTypeTrain)) ctx.Data["NotStopTaskCount"] = NotStopTaskCount setMultiNodeIfConfigureMatch(ctx) @@ -930,7 +930,7 @@ func trainJobNewVersionDataPrepare(ctx *context.Context) error { ctx.Data["config_list"] = configList.ParaConfigs waitCount := cloudbrain.GetWaitingCloudbrainCount(models.TypeCloudBrainTwo, "") ctx.Data["WaitCount"] = waitCount - NotStopTaskCount, _ := cloudbrainTask.GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeCloudBrainTwo, string(models.JobTypeTrain), models.NPUResource) + NotStopTaskCount, _ := cloudbrainTask.GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeCloudBrainTwo, string(models.JobTypeTrain)) ctx.Data["NotStopTaskCount"] = NotStopTaskCount return nil @@ -978,7 +978,7 @@ func TrainJobCreate(ctx *context.Context, form auth.CreateModelArtsTrainJobForm) } defer lock.UnLock() - count, err := cloudbrainTask.GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeCloudBrainTwo, string(models.JobTypeTrain), models.NPUResource) + count, err := cloudbrainTask.GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeCloudBrainTwo, string(models.JobTypeTrain)) if err != nil { log.Error("GetCloudbrainTrainJobCountByUserID failed:%v", err, ctx.Data["MsgID"]) @@ -1323,7 +1323,7 @@ func TrainJobCreateVersion(ctx *context.Context, form auth.CreateModelArtsTrainJ return } - count, err := cloudbrainTask.GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeCloudBrainTwo, string(models.JobTypeTrain), models.NPUResource) + count, err := cloudbrainTask.GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeCloudBrainTwo, string(models.JobTypeTrain)) if err != nil { log.Error("GetCloudbrainTrainJobCountByUserID failed:%v", err, ctx.Data["MsgID"]) trainJobNewVersionDataPrepare(ctx) @@ -1974,7 +1974,7 @@ func InferenceJobCreate(ctx *context.Context, form auth.CreateModelArtsInference } defer lock.UnLock() - count, err := cloudbrainTask.GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeCloudBrainTwo, string(models.JobTypeInference), models.NPUResource) + count, err := cloudbrainTask.GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeCloudBrainTwo, string(models.JobTypeInference)) if err != nil { log.Error("GetCloudbrainInferenceJobCountByUserID failed:%v", err, ctx.Data["MsgID"]) @@ -2377,7 +2377,7 @@ func inferenceJobNewDataPrepare(ctx *context.Context) error { ctx.Data["datasetType"] = models.TypeCloudBrainTwo waitCount := cloudbrain.GetWaitingCloudbrainCount(models.TypeCloudBrainTwo, "") ctx.Data["WaitCount"] = waitCount - NotStopTaskCount, _ := cloudbrainTask.GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeCloudBrainTwo, string(models.JobTypeInference), models.NPUResource) + NotStopTaskCount, _ := cloudbrainTask.GetNotFinalStatusTaskCount(ctx.User.ID, models.TypeCloudBrainTwo, string(models.JobTypeInference)) ctx.Data["NotStopTaskCount"] = NotStopTaskCount return nil From 363116b80fa2e12c7eeb51e499568e1d204cd991 Mon Sep 17 00:00:00 2001 From: zhoupzh Date: Fri, 21 Oct 2022 16:54:21 +0800 Subject: [PATCH 19/29] fix issue --- templates/org/member/members.tmpl | 80 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 templates/org/member/members.tmpl diff --git a/templates/org/member/members.tmpl b/templates/org/member/members.tmpl new file mode 100644 index 000000000..cd8a691a7 --- /dev/null +++ b/templates/org/member/members.tmpl @@ -0,0 +1,80 @@ +{{template "base/head" .}} +
+ {{template "org/header" .}} +
+ {{template "base/alert" .}} + {{template "org/navber" .}} +
+ +
+ {{ range .Members}} +
+
+ +
+
+ +
{{.FullName}}
+
+
+
+ {{$.i18n.Tr "org.members.membership_visibility"}} +
+
+ {{ $isPublic := index $.MembersIsPublicMember .ID}} + {{if $isPublic}} + {{$.i18n.Tr "org.members.public"}} + {{if or (eq $.SignedUser.ID .ID) $.IsOrganizationOwner}}({{$.i18n.Tr "org.members.public_helper"}}){{end}} + {{else}} + {{$.i18n.Tr "org.members.private"}} + {{if or (eq $.SignedUser.ID .ID) $.IsOrganizationOwner}}({{$.i18n.Tr "org.members.private_helper"}}){{end}} + {{end}} +
+
+
+
+ {{$.i18n.Tr "org.members.member_role"}} +
+
+ {{if index $.MembersIsUserOrgOwner .ID}}{{svg "octicon-shield-lock" 16}} {{$.i18n.Tr "org.members.owner"}}{{else}}{{$.i18n.Tr "org.members.member"}}{{end}} +
+
+
+
+ 2FA +
+
+ + {{if index $.MembersTwoFaStatus .ID}} + {{svg "octicon-check" 16}} + {{else}} + {{svg "octicon-x" 16}} + {{end}} + +
+
+
+
+ {{if eq $.SignedUser.ID .ID}} +
+ {{$.CsrfTokenHtml}} + +
+ {{else if $.IsOrganizationOwner}} +
+ {{$.CsrfTokenHtml}} + +
+ {{end}} +
+
+
+ {{end}} +
+ + {{template "base/paginate" .}} +
+ +
+
+{{template "base/footer" .}} \ No newline at end of file From 98973bf82ea25399c0cea1487c290861a6aabf67 Mon Sep 17 00:00:00 2001 From: liuzx Date: Fri, 21 Oct 2022 17:00:42 +0800 Subject: [PATCH 20/29] fix-bug --- routers/api/v1/repo/cloudbrain_dashboard.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routers/api/v1/repo/cloudbrain_dashboard.go b/routers/api/v1/repo/cloudbrain_dashboard.go index c665fe256..935006476 100755 --- a/routers/api/v1/repo/cloudbrain_dashboard.go +++ b/routers/api/v1/repo/cloudbrain_dashboard.go @@ -121,7 +121,7 @@ func GetOverviewDuration(ctx *context.Context) { now := time.Now() endTime := now page := 1 - pagesize := 10000 + pagesize := 1000 count := pagesize worker_server_num := 1 cardNum := 1 From ff4873129000f36993fe1a68a4ff8418cdccb0f3 Mon Sep 17 00:00:00 2001 From: zhoupzh Date: Mon, 24 Oct 2022 16:31:07 +0800 Subject: [PATCH 21/29] fix issue --- templates/repo/modelarts/notebook/new.tmpl | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/templates/repo/modelarts/notebook/new.tmpl b/templates/repo/modelarts/notebook/new.tmpl index f9c4670a5..0ada241bc 100755 --- a/templates/repo/modelarts/notebook/new.tmpl +++ b/templates/repo/modelarts/notebook/new.tmpl @@ -179,17 +179,7 @@ } } - $('select.dropdown') - .dropdown(); - $(function() { - $("#cloudbrain_job_type").change(function() { - if ($(this).val() == 'BENCHMARK') { - $(".cloudbrain_benchmark").show(); - } else { - $(".cloudbrain_benchmark").hide(); - } - }) - }) + $(document).ready(function(){ $(document).keydown(function(event){ if(event.keyCode==13){ @@ -209,4 +199,5 @@ shared_memory: {{$.i18n.Tr "cloudbrain.shared_memory"}}, }); })(); + console.log("-------------:",{{.NotStopTaskCount}}) From b306e35a31ddb8b45d5aac47c96eac8e30829b91 Mon Sep 17 00:00:00 2001 From: zhoupzh Date: Mon, 24 Oct 2022 17:38:51 +0800 Subject: [PATCH 22/29] fix issue --- templates/custom/alert_cb.tmpl | 12 ++++++++++++ templates/repo/cloudbrain/new.tmpl | 1 + templates/repo/modelarts/notebook/new.tmpl | 14 +++++++++++++- web_src/js/features/cloudrbanin.js | 3 +++ web_src/less/_form.less | 15 +++++++++++---- 5 files changed, 40 insertions(+), 5 deletions(-) create mode 100644 templates/custom/alert_cb.tmpl diff --git a/templates/custom/alert_cb.tmpl b/templates/custom/alert_cb.tmpl new file mode 100644 index 000000000..1e3ed5873 --- /dev/null +++ b/templates/custom/alert_cb.tmpl @@ -0,0 +1,12 @@ +{{if .NotStopTaskCount}} +
+ +
+ +
+
您已经有 同类任务 正在等待或运行中,请等待任务结束再创建
+
可以在 “个人中心 > 云脑任务” 查看您所有的云脑任务
+
+
+
+{{end}} \ No newline at end of file diff --git a/templates/repo/cloudbrain/new.tmpl b/templates/repo/cloudbrain/new.tmpl index fb7ccbed1..48cadf278 100755 --- a/templates/repo/cloudbrain/new.tmpl +++ b/templates/repo/cloudbrain/new.tmpl @@ -28,6 +28,7 @@ + {{template "custom/alert_cb" .}}
{{.CsrfTokenHtml}} diff --git a/templates/repo/modelarts/notebook/new.tmpl b/templates/repo/modelarts/notebook/new.tmpl index 0ada241bc..4eaaf3cd4 100755 --- a/templates/repo/modelarts/notebook/new.tmpl +++ b/templates/repo/modelarts/notebook/new.tmpl @@ -15,6 +15,8 @@

+ + {{template "custom/alert_cb" .}} {{.CsrfTokenHtml}}

@@ -178,8 +180,18 @@ document.getElementById("mask").style.display = "none" } } + $('select.dropdown') + .dropdown(); - + $(function() { + $("#cloudbrain_job_type").change(function() { + if ($(this).val() == 'BENCHMARK') { + $(".cloudbrain_benchmark").show(); + } else { + $(".cloudbrain_benchmark").hide(); + } + }) + }) $(document).ready(function(){ $(document).keydown(function(event){ if(event.keyCode==13){ diff --git a/web_src/js/features/cloudrbanin.js b/web_src/js/features/cloudrbanin.js index 698523d11..657ca1381 100644 --- a/web_src/js/features/cloudrbanin.js +++ b/web_src/js/features/cloudrbanin.js @@ -575,3 +575,6 @@ function AdaminSearchControll() { } userSearchControll(); AdaminSearchControll(); +$(".message .close").on("click", function () { + $(this).closest(".message").transition("fade"); +}); diff --git a/web_src/less/_form.less b/web_src/less/_form.less index e41c428c8..d481d1cee 100644 --- a/web_src/less/_form.less +++ b/web_src/less/_form.less @@ -1,8 +1,8 @@ .form { .help { color: #999999; - padding-top: .6em; - + padding-top: 0.6em; + display: inline-block; } } @@ -109,7 +109,7 @@ @media screen and (max-height: 575px) { #rc-imageselect, .g-recaptcha { - transform: scale(.77); + transform: scale(0.77); transform-origin: 0 0; } } @@ -141,7 +141,7 @@ } } - input[type=number] { + input[type="number"] { -moz-appearance: textfield; } @@ -157,6 +157,13 @@ &.new.repo, &.new.migrate, &.new.fork { + .ui.message { + @media only screen and (min-width: 768px) { + width: 800px !important; + } + margin: 0 auto; + margin-bottom: 1rem; + } #create-page-form; form { From 9c0acb703172c378526f20f72c6082f9ff734c93 Mon Sep 17 00:00:00 2001 From: zhoupzh Date: Mon, 24 Oct 2022 18:15:13 +0800 Subject: [PATCH 23/29] fix issue --- templates/repo/cloudbrain/benchmark/new.tmpl | 1 + templates/repo/cloudbrain/inference/new.tmpl | 1 + templates/repo/cloudbrain/trainjob/new.tmpl | 1 + templates/repo/modelarts/inferencejob/new.tmpl | 1 + templates/repo/modelarts/trainjob/new.tmpl | 1 + 5 files changed, 5 insertions(+) diff --git a/templates/repo/cloudbrain/benchmark/new.tmpl b/templates/repo/cloudbrain/benchmark/new.tmpl index 13665c036..d337db460 100755 --- a/templates/repo/cloudbrain/benchmark/new.tmpl +++ b/templates/repo/cloudbrain/benchmark/new.tmpl @@ -33,6 +33,7 @@ {{template "repo/header" .}}
{{template "base/alert" .}} + {{template "custom/alert_cb" .}}

{{.i18n.Tr "repo.modelarts.evaluate_job.new_job"}}

diff --git a/templates/repo/cloudbrain/inference/new.tmpl b/templates/repo/cloudbrain/inference/new.tmpl index 630df7a2e..0d5a5005a 100644 --- a/templates/repo/cloudbrain/inference/new.tmpl +++ b/templates/repo/cloudbrain/inference/new.tmpl @@ -41,6 +41,7 @@ {{template "repo/header" .}}
{{template "base/alert" .}} + {{template "custom/alert_cb" .}}

{{.i18n.Tr "repo.modelarts.train_job.new_infer"}} diff --git a/templates/repo/cloudbrain/trainjob/new.tmpl b/templates/repo/cloudbrain/trainjob/new.tmpl index 607af5f07..58ec9dd36 100755 --- a/templates/repo/cloudbrain/trainjob/new.tmpl +++ b/templates/repo/cloudbrain/trainjob/new.tmpl @@ -72,6 +72,7 @@
{{template "base/alert" .}} + {{template "custom/alert_cb" .}}

{{.i18n.Tr "repo.modelarts.train_job.new"}}

diff --git a/templates/repo/modelarts/inferencejob/new.tmpl b/templates/repo/modelarts/inferencejob/new.tmpl index d2f6a8194..2ffb16c57 100644 --- a/templates/repo/modelarts/inferencejob/new.tmpl +++ b/templates/repo/modelarts/inferencejob/new.tmpl @@ -40,6 +40,7 @@ {{template "repo/header" .}}
{{template "base/alert" .}} + {{template "custom/alert_cb" .}}

{{.i18n.Tr "repo.modelarts.train_job.new_infer"}} diff --git a/templates/repo/modelarts/trainjob/new.tmpl b/templates/repo/modelarts/trainjob/new.tmpl index 0e1e8eedb..29d91e633 100755 --- a/templates/repo/modelarts/trainjob/new.tmpl +++ b/templates/repo/modelarts/trainjob/new.tmpl @@ -64,6 +64,7 @@
{{template "base/alert" .}} + {{template "custom/alert_cb" .}}

{{.i18n.Tr "repo.modelarts.train_job.new"}}

From be3810d608cfb7139f1aeb6eb0dc94f190d4b6b4 Mon Sep 17 00:00:00 2001 From: zhoupzh Date: Tue, 25 Oct 2022 09:09:34 +0800 Subject: [PATCH 24/29] fix issue --- templates/custom/alert_cb.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/custom/alert_cb.tmpl b/templates/custom/alert_cb.tmpl index 1e3ed5873..3ea03b8e5 100644 --- a/templates/custom/alert_cb.tmpl +++ b/templates/custom/alert_cb.tmpl @@ -5,7 +5,7 @@
您已经有 同类任务 正在等待或运行中,请等待任务结束再创建
-
可以在 “个人中心 > 云脑任务” 查看您所有的云脑任务
+
可以在 “个人中心 > 云脑任务” 查看您所有的云脑任务

From 91e93b293b9daf6cb2d3fe65372e0774c244cff5 Mon Sep 17 00:00:00 2001 From: zhoupzh Date: Tue, 25 Oct 2022 09:16:00 +0800 Subject: [PATCH 25/29] fix issue --- templates/custom/alert_cb.tmpl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/templates/custom/alert_cb.tmpl b/templates/custom/alert_cb.tmpl index 3ea03b8e5..7961c2b16 100644 --- a/templates/custom/alert_cb.tmpl +++ b/templates/custom/alert_cb.tmpl @@ -9,4 +9,7 @@

-{{end}} \ No newline at end of file +{{end}} + \ No newline at end of file From e0a6f88c04aa2c3bb4068b417d31e2c05c4bb2c6 Mon Sep 17 00:00:00 2001 From: zhoupzh Date: Tue, 25 Oct 2022 09:19:59 +0800 Subject: [PATCH 26/29] fix issue --- templates/custom/alert_cb.tmpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/custom/alert_cb.tmpl b/templates/custom/alert_cb.tmpl index 7961c2b16..f8e46486a 100644 --- a/templates/custom/alert_cb.tmpl +++ b/templates/custom/alert_cb.tmpl @@ -11,5 +11,5 @@

{{end}} \ No newline at end of file From ea7d8ce9b743aa59cf8d8bafa93647c81571149c Mon Sep 17 00:00:00 2001 From: zhoupzh Date: Tue, 25 Oct 2022 10:00:54 +0800 Subject: [PATCH 27/29] fix-2982 issue --- templates/custom/alert_cb.tmpl | 5 +---- templates/repo/grampus/trainjob/gpu/new.tmpl | 1 + templates/repo/grampus/trainjob/npu/new.tmpl | 1 + templates/repo/modelsafety/new.tmpl | 1 + 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/templates/custom/alert_cb.tmpl b/templates/custom/alert_cb.tmpl index f8e46486a..3ea03b8e5 100644 --- a/templates/custom/alert_cb.tmpl +++ b/templates/custom/alert_cb.tmpl @@ -9,7 +9,4 @@
-{{end}} - \ No newline at end of file +{{end}} \ No newline at end of file diff --git a/templates/repo/grampus/trainjob/gpu/new.tmpl b/templates/repo/grampus/trainjob/gpu/new.tmpl index e97ccfe59..439991813 100755 --- a/templates/repo/grampus/trainjob/gpu/new.tmpl +++ b/templates/repo/grampus/trainjob/gpu/new.tmpl @@ -64,6 +64,7 @@
{{template "base/alert" .}} + {{template "custom/alert_cb" .}}

{{.i18n.Tr "repo.modelarts.train_job.new"}}

diff --git a/templates/repo/grampus/trainjob/npu/new.tmpl b/templates/repo/grampus/trainjob/npu/new.tmpl index 51a561d3d..4b5666c37 100755 --- a/templates/repo/grampus/trainjob/npu/new.tmpl +++ b/templates/repo/grampus/trainjob/npu/new.tmpl @@ -59,6 +59,7 @@
{{template "base/alert" .}} + {{template "custom/alert_cb" .}}

{{.i18n.Tr "repo.modelarts.train_job.new"}}

diff --git a/templates/repo/modelsafety/new.tmpl b/templates/repo/modelsafety/new.tmpl index 07bcd311d..9383c2f2a 100644 --- a/templates/repo/modelsafety/new.tmpl +++ b/templates/repo/modelsafety/new.tmpl @@ -56,6 +56,7 @@ {{$Grampus := (or (eq (index (SubJumpablePath .Link) 1) "create_grampus_gpu") (eq (index (SubJumpablePath .Link) 1) "create_grampus_npu"))}} {{template "base/alert" .}} + {{template "custom/alert_cb" .}}

{{.i18n.Tr "repo.modelarts.evaluate_job.new_job"}}

From 1567e9cff0640e9b3b918e18e82b1cf2b8242a29 Mon Sep 17 00:00:00 2001 From: ychao_1983 Date: Tue, 25 Oct 2022 10:54:32 +0800 Subject: [PATCH 28/29] =?UTF-8?q?=E6=8F=90=E4=BA=A4=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- services/cloudbrain/cloudbrainTask/count.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/cloudbrain/cloudbrainTask/count.go b/services/cloudbrain/cloudbrainTask/count.go index 25d56b0b6..c601edca6 100644 --- a/services/cloudbrain/cloudbrainTask/count.go +++ b/services/cloudbrain/cloudbrainTask/count.go @@ -49,7 +49,7 @@ var StatusInfoDict = map[string]StatusInfo{string(models.JobTypeDebug) + "-" + s ComputeResource: models.NPUResource, }, string(models.JobTypeInference) + "-" + strconv.Itoa(models.TypeCloudBrainTwo): { CloudBrainTypes: []int{models.TypeCloudBrainTwo}, - JobType: []models.JobType{models.JobTypeTrain}, + JobType: []models.JobType{models.JobTypeInference}, NotFinalStatuses: cloudbrainTwoNotFinalStatuses, ComputeResource: models.NPUResource, }, string(models.JobTypeTrain) + "-" + strconv.Itoa(models.TypeC2Net) + "-" + models.GPUResource: { From abafb72615231d39b8abbcf1c37dc4eed61715ca Mon Sep 17 00:00:00 2001 From: ychao_1983 Date: Tue, 25 Oct 2022 11:04:55 +0800 Subject: [PATCH 29/29] =?UTF-8?q?=E6=8F=90=E4=BA=A4=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- models/cloudbrain.go | 2 +- services/cloudbrain/cloudbrainTask/count.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/models/cloudbrain.go b/models/cloudbrain.go index f0e27995e..1eaeffcd3 100755 --- a/models/cloudbrain.go +++ b/models/cloudbrain.go @@ -2024,7 +2024,7 @@ func GetCloudbrainRunCountByRepoID(repoID int64) (int, error) { } func GetModelSafetyCountByUserID(userID int64) (int, error) { - count, err := x.In("status", JobWaiting, JobRunning).And("job_type = ? and user_id = ?", string(JobTypeModelSafety), userID).Count(new(Cloudbrain)) + count, err := x.In("status", JobWaiting, JobRunning,ModelArtsTrainJobInit,ModelArtsTrainJobImageCreating,ModelArtsTrainJobSubmitTrying,ModelArtsTrainJobScaling,ModelArtsTrainJobCheckInit,ModelArtsTrainJobCheckRunning,ModelArtsTrainJobCheckRunningCompleted).And("job_type = ? and user_id = ?", string(JobTypeModelSafety), userID).Count(new(Cloudbrain)) return int(count), err } diff --git a/services/cloudbrain/cloudbrainTask/count.go b/services/cloudbrain/cloudbrainTask/count.go index c601edca6..a9b254618 100644 --- a/services/cloudbrain/cloudbrainTask/count.go +++ b/services/cloudbrain/cloudbrainTask/count.go @@ -34,7 +34,7 @@ var StatusInfoDict = map[string]StatusInfo{string(models.JobTypeDebug) + "-" + s ComputeResource: models.GPUResource, }, string(models.JobTypeBenchmark) + "-" + strconv.Itoa(models.TypeCloudBrainOne): { CloudBrainTypes: []int{models.TypeCloudBrainOne}, - JobType: []models.JobType{models.JobTypeBenchmark, models.JobTypeModelSafety, models.JobTypeBrainScore, models.JobTypeSnn4imagenet}, + JobType: []models.JobType{models.JobTypeBenchmark, models.JobTypeBrainScore, models.JobTypeSnn4imagenet}, NotFinalStatuses: cloudbrainOneNotFinalStatuses, ComputeResource: models.GPUResource, }, string(models.JobTypeDebug) + "-" + strconv.Itoa(models.TypeCloudBrainTwo): {