Reviewed-on: https://git.openi.org.cn/OpenI/aiforge/pulls/2933 Reviewed-by: chenshihai <chenshh@pcl.ac.cn>tags/v1.22.9.2^2
| @@ -61,13 +61,10 @@ const ( | |||
| ActionCreateGrampusNPUTrainTask //32 | |||
| ActionCreateGrampusGPUTrainTask //33 | |||
| ActionBindWechat //34 | |||
| ActionCreateCloudbrainTask //35 | |||
| ActionDatasetRecommended //36 | |||
| ActionCreateImage //37 | |||
| ActionImageRecommend //38 | |||
| ActionChangeUserAvatar //39 | |||
| ActionPushCommits //40 | |||
| ActionForkRepo //41 | |||
| ActionDatasetRecommended //35 | |||
| ActionCreateImage //36 | |||
| ActionImageRecommend //37 | |||
| ActionChangeUserAvatar //38 | |||
| ) | |||
| @@ -95,6 +92,7 @@ type Action struct { | |||
| type ActionShow struct { | |||
| OpType ActionType | |||
| TaskType TaskType | |||
| RepoLink string | |||
| ShortRepoFullDisplayName string | |||
| Content string | |||
| @@ -241,7 +239,8 @@ func (a *Action) GetRepoLink() string { | |||
| func (a *Action) ToShow() *ActionShow { | |||
| actionShow := &ActionShow{} | |||
| actionShow.OpType = GetTaskOptType(*a) | |||
| actionShow.OpType = a.OpType | |||
| actionShow.TaskType = GetTaskTypeFromAction(a.OpType) | |||
| actionShow.Content = a.Content | |||
| actionShow.RefName = a.RefName | |||
| @@ -272,14 +271,6 @@ func (a *Action) ToShow() *ActionShow { | |||
| return actionShow | |||
| } | |||
| func GetTaskOptType(action Action) ActionType { | |||
| //Convert all types of cloudbrain tasks action into ActionCreateCloudbrainTask | |||
| if action.IsCloudbrainAction() { | |||
| return ActionCreateCloudbrainTask | |||
| } | |||
| return action.OpType | |||
| } | |||
| // GetRepositoryFromMatch returns a *Repository from a username and repo strings | |||
| func GetRepositoryFromMatch(ownerName string, repoName string) (*Repository, error) { | |||
| var err error | |||
| @@ -203,16 +203,17 @@ type Cloudbrain struct { | |||
| } | |||
| type CloudbrainShow struct { | |||
| ID int64 | |||
| JobID string | |||
| RepoFullName string | |||
| Type int | |||
| JobType string | |||
| DisplayJobName string | |||
| Duration string | |||
| ResourceSpec *Specification | |||
| ComputeResource string | |||
| AiCenter string | |||
| ID int64 | |||
| JobID string | |||
| RepoFullName string | |||
| Type int | |||
| JobType string | |||
| DisplayJobName string | |||
| Duration string | |||
| ResourceSpec *Specification | |||
| ComputeResource string | |||
| AiCenter string | |||
| WorkServerNumber int | |||
| } | |||
| type CloudbrainShow4Action struct { | |||
| @@ -225,15 +226,20 @@ type CloudbrainShow4Action struct { | |||
| } | |||
| func (task *Cloudbrain) ToShow() *CloudbrainShow { | |||
| n := 1 | |||
| if task.WorkServerNumber > 1 { | |||
| n = task.WorkServerNumber | |||
| } | |||
| c := &CloudbrainShow{ | |||
| ID: task.ID, | |||
| JobID: task.JobID, | |||
| JobType: task.JobType, | |||
| Type: task.Type, | |||
| DisplayJobName: task.DisplayJobName, | |||
| Duration: task.TrainJobDuration, | |||
| ResourceSpec: task.Spec, | |||
| ComputeResource: task.ComputeResource, | |||
| ID: task.ID, | |||
| JobID: task.JobID, | |||
| JobType: task.JobType, | |||
| Type: task.Type, | |||
| DisplayJobName: task.DisplayJobName, | |||
| Duration: task.TrainJobDuration, | |||
| ResourceSpec: task.Spec, | |||
| ComputeResource: task.ComputeResource, | |||
| WorkServerNumber: n, | |||
| } | |||
| if task.Repo != nil { | |||
| c.RepoFullName = task.Repo.FullName() | |||
| @@ -123,10 +123,14 @@ func GetResourceSpecMapByCloudbrainIDs(ids []int64) (map[int64]*Specification, e | |||
| return r, nil | |||
| } | |||
| func GetCloudbrainTaskUnitPrice(cloudbrainId int64) (int, error) { | |||
| s, err := GetCloudbrainSpecByID(cloudbrainId) | |||
| func GetCloudbrainTaskUnitPrice(task Cloudbrain) (int, error) { | |||
| s, err := GetCloudbrainSpecByID(task.ID) | |||
| if err != nil { | |||
| return 0, err | |||
| } | |||
| return s.UnitPrice, nil | |||
| var n = 1 | |||
| if task.WorkServerNumber > 1 { | |||
| n = task.WorkServerNumber | |||
| } | |||
| return s.UnitPrice * n, nil | |||
| } | |||
| @@ -183,6 +183,7 @@ func notifyWatchers(e Engine, actions ...*Action) error { | |||
| var permCode []bool | |||
| var permIssue []bool | |||
| var permPR []bool | |||
| var permDataset []bool | |||
| for _, act := range actions { | |||
| repoChanged := repo == nil || repo.ID != act.RepoID | |||
| @@ -234,12 +235,14 @@ func notifyWatchers(e Engine, actions ...*Action) error { | |||
| permCode = make([]bool, len(watchers)) | |||
| permIssue = make([]bool, len(watchers)) | |||
| permPR = make([]bool, len(watchers)) | |||
| permDataset = make([]bool, len(watchers)) | |||
| for i, watcher := range watchers { | |||
| user, err := getUserByID(e, watcher.UserID) | |||
| if err != nil { | |||
| permCode[i] = false | |||
| permIssue[i] = false | |||
| permPR[i] = false | |||
| permDataset[i] = false | |||
| continue | |||
| } | |||
| perm, err := getUserRepoPermission(e, repo, user) | |||
| @@ -247,11 +250,13 @@ func notifyWatchers(e Engine, actions ...*Action) error { | |||
| permCode[i] = false | |||
| permIssue[i] = false | |||
| permPR[i] = false | |||
| permDataset[i] = false | |||
| continue | |||
| } | |||
| permCode[i] = perm.CanRead(UnitTypeCode) | |||
| permIssue[i] = perm.CanRead(UnitTypeIssues) | |||
| permPR[i] = perm.CanRead(UnitTypePullRequests) | |||
| permDataset[i] = perm.CanRead(UnitTypeDatasets) | |||
| } | |||
| } | |||
| @@ -276,6 +281,10 @@ func notifyWatchers(e Engine, actions ...*Action) error { | |||
| if !permPR[i] { | |||
| continue | |||
| } | |||
| case ActionDatasetRecommended: | |||
| if !permDataset[i] { | |||
| continue | |||
| } | |||
| } | |||
| if _, err = e.InsertOne(act); err != nil { | |||
| @@ -2,7 +2,6 @@ package models | |||
| import ( | |||
| "code.gitea.io/gitea/modules/timeutil" | |||
| "fmt" | |||
| "strconv" | |||
| "strings" | |||
| "xorm.io/builder" | |||
| @@ -355,7 +354,7 @@ type RewardRecordListOpts struct { | |||
| OperateType RewardOperateType | |||
| RewardType RewardType | |||
| SourceType string | |||
| ActionType int | |||
| TaskType string | |||
| SerialNo string | |||
| OrderBy RewardOperateOrderBy | |||
| IsAdmin bool | |||
| @@ -381,8 +380,8 @@ func (opts *RewardRecordListOpts) toCond() builder.Cond { | |||
| if opts.SourceType != "" { | |||
| cond = cond.And(builder.Eq{"reward_operate_record.source_type": opts.SourceType}) | |||
| } | |||
| if opts.ActionType > 0 { | |||
| cond = cond.And(builder.Eq{"reward_operate_record.source_template_id": fmt.Sprint(opts.ActionType)}) | |||
| if opts.TaskType != "" { | |||
| cond = cond.And(builder.Eq{"reward_operate_record.source_template_id": opts.TaskType}) | |||
| } | |||
| if opts.SerialNo != "" { | |||
| cond = cond.And(builder.Like{"reward_operate_record.serial_no", opts.SerialNo}) | |||
| @@ -2,7 +2,6 @@ package models | |||
| import ( | |||
| "code.gitea.io/gitea/modules/timeutil" | |||
| "fmt" | |||
| "xorm.io/builder" | |||
| ) | |||
| @@ -11,6 +10,66 @@ const ( | |||
| PeriodDaily = "DAILY" | |||
| ) | |||
| type TaskType string | |||
| const ( | |||
| TaskCreatePublicRepo TaskType = "CreatePublicRepo" | |||
| TaskCreateIssue TaskType = "CreateIssue" | |||
| TaskCreatePullRequest TaskType = "CreatePullRequest" | |||
| TaskCommentIssue TaskType = "CommentIssue" | |||
| TaskUploadAttachment TaskType = "UploadAttachment" | |||
| TaskCreateNewModelTask TaskType = "CreateNewModelTask" | |||
| TaskBindWechat TaskType = "BindWechat" | |||
| TaskCreateCloudbrainTask TaskType = "CreateCloudbrainTask" | |||
| TaskDatasetRecommended TaskType = "DatasetRecommended" | |||
| TaskCreateImage TaskType = "CreateImage" | |||
| TaskImageRecommend TaskType = "ImageRecommend" | |||
| TaskChangeUserAvatar TaskType = "ChangeUserAvatar" | |||
| TaskPushCommits TaskType = "PushCommits" | |||
| ) | |||
| func GetTaskTypeFromAction(a ActionType) TaskType { | |||
| switch a { | |||
| case ActionCreateDebugGPUTask, | |||
| ActionCreateDebugNPUTask, | |||
| ActionCreateTrainTask, | |||
| ActionCreateInferenceTask, | |||
| ActionCreateBenchMarkTask, | |||
| ActionCreateGPUTrainTask, | |||
| ActionCreateGrampusNPUTrainTask, | |||
| ActionCreateGrampusGPUTrainTask: | |||
| return TaskCreateCloudbrainTask | |||
| case ActionCreateRepo: | |||
| return TaskCreatePublicRepo | |||
| case ActionCreatePullRequest: | |||
| return TaskCreatePullRequest | |||
| case ActionCommentIssue: | |||
| return TaskCommentIssue | |||
| case ActionUploadAttachment: | |||
| return TaskUploadAttachment | |||
| case ActionCreateNewModelTask: | |||
| return TaskCreateNewModelTask | |||
| case ActionBindWechat: | |||
| return TaskBindWechat | |||
| case ActionDatasetRecommended: | |||
| return TaskDatasetRecommended | |||
| case ActionImageRecommend: | |||
| return TaskImageRecommend | |||
| case ActionCreateImage: | |||
| return TaskCreateImage | |||
| case ActionChangeUserAvatar: | |||
| return TaskChangeUserAvatar | |||
| case ActionCommitRepo, | |||
| ActionDeleteBranch, | |||
| ActionPushTag, | |||
| ActionDeleteTag: | |||
| return TaskPushCommits | |||
| case ActionCreateIssue: | |||
| return TaskCreateIssue | |||
| } | |||
| return "" | |||
| } | |||
| //PointTaskConfig Only add and delete are allowed, edit is not allowed | |||
| //so if you want to edit config for some task code,please delete first and add new one | |||
| type TaskConfig struct { | |||
| @@ -124,8 +183,8 @@ func GetTaskConfigList() ([]*TaskConfig, error) { | |||
| type GetTaskConfigOpts struct { | |||
| ListOptions | |||
| Status int //1 normal 2 deleted | |||
| ActionType int | |||
| Status int //1 normal 2 deleted | |||
| TaskType string | |||
| } | |||
| func GetTaskConfigPageWithDeleted(opt GetTaskConfigOpts) ([]*TaskAndLimiterConfig, int64, error) { | |||
| @@ -133,8 +192,8 @@ func GetTaskConfigPageWithDeleted(opt GetTaskConfigOpts) ([]*TaskAndLimiterConfi | |||
| opt.Page = 1 | |||
| } | |||
| cond := builder.NewCond() | |||
| if opt.ActionType > 0 { | |||
| cond = cond.And(builder.Eq{"task_code": fmt.Sprint(opt.ActionType)}) | |||
| if opt.TaskType != "" { | |||
| cond = cond.And(builder.Eq{"task_code": opt.TaskType}) | |||
| } | |||
| var count int64 | |||
| @@ -363,22 +363,15 @@ func (t *actionNotifier) NotifyWechatBind(user *models.User, wechatOpenId string | |||
| func (t *actionNotifier) NotifyDatasetRecommend(optUser *models.User, dataset *models.Dataset, action string) { | |||
| switch action { | |||
| case "recommend": | |||
| users, err := models.GetAllDatasetContributorByDatasetId(dataset.ID) | |||
| if err != nil { | |||
| return | |||
| } | |||
| var actions = make([]*models.Action, 0) | |||
| for _, user := range users { | |||
| actions = append(actions, &models.Action{ | |||
| OpType: models.ActionDatasetRecommended, | |||
| ActUserID: user.ID, | |||
| ActUser: user, | |||
| RepoID: dataset.RepoID, | |||
| Repo: dataset.Repo, | |||
| Content: fmt.Sprintf("%d|%s", dataset.ID, dataset.Title), | |||
| }) | |||
| act := &models.Action{ | |||
| OpType: models.ActionDatasetRecommended, | |||
| ActUserID: dataset.UserID, | |||
| RepoID: dataset.RepoID, | |||
| IsPrivate: false, | |||
| Content: fmt.Sprintf("%d|%s", dataset.ID, dataset.Title), | |||
| } | |||
| if err := models.NotifyWatchers(actions...); err != nil { | |||
| if err := models.NotifyWatchers(act); err != nil { | |||
| log.Error("notifyWatchers: %v", err) | |||
| } | |||
| } | |||
| @@ -428,19 +421,3 @@ func (t *actionNotifier) NotifyChangeUserAvatar(user *models.User, form auth.Ava | |||
| log.Error("notifyWatchers: %v", err) | |||
| } | |||
| } | |||
| func (t *actionNotifier) NotifyPushCommits(pusher *models.User, repo *models.Repository, refName, oldCommitID, newCommitID string, commits *repository.PushCommits) { | |||
| act := &models.Action{ | |||
| ActUserID: pusher.ID, | |||
| ActUser: pusher, | |||
| OpType: models.ActionPushCommits, | |||
| RepoID: repo.ID, | |||
| Repo: repo, | |||
| RefName: refName, | |||
| IsPrivate: repo.IsPrivate, | |||
| Content: fmt.Sprintf("%s|%s", oldCommitID, newCommitID), | |||
| } | |||
| if err := models.NotifyWatchers(act); err != nil { | |||
| log.Error("notifyWatchers: %v", err) | |||
| } | |||
| } | |||
| @@ -3074,6 +3074,11 @@ task_createmodel=`created new model <a href="%s/modelmanage/show_model_info?name | |||
| task_gputrainjob=`created CPU/GPU training task <a href="%s/cloudbrain/train-job/%s">%s</a>` | |||
| task_c2netnputrainjob=`created NPU training task <a href="%s/grampus/train-job/%s">%s</a>` | |||
| task_c2netgputrainjob=`created CPU/GPU training task <a href="%s/grampus/train-job/%s">%s</a>` | |||
| binded_wechat=binded WeChat | |||
| dataset_recommended=`created dataset <a href="%s/datasets">%s</a> was set as recommended dataset` | |||
| create_image=`committed image <span style="font-weight:bold;">%s</span>` | |||
| image_recommended=`committed image <span style="font-weight:bold;">%s</span> was set as recommended image` | |||
| update_user_avatar=updated avatar | |||
| [tool] | |||
| ago = %s ago | |||
| @@ -3091,6 +3091,11 @@ task_createmodel=`导入了新模型 <a href="%s/modelmanage/show_model_info?nam | |||
| task_gputrainjob=`创建了CPU/GPU类型训练任务 <a href="%s/cloudbrain/train-job/%s">%s</a>` | |||
| task_c2netnputrainjob=`创建了NPU类型训练任务 <a href="%s/grampus/train-job/%s">%s</a>` | |||
| task_c2netgputrainjob=`创建了CPU/GPU类型训练任务 <a href="%s/grampus/train-job/%s">%s</a>` | |||
| binded_wechat=绑定微信 | |||
| dataset_recommended=`创建的数据集<a href="%s/datasets">%s</a>被设置为推荐数据集` | |||
| create_image=`提交了镜像<span style="font-weight:bold;">%s</span>` | |||
| image_recommended=`提交的镜像<span style="font-weight:bold;">%s</span>被设置为推荐镜像` | |||
| update_user_avatar=更新了头像 | |||
| [tool] | |||
| ago=%s前 | |||
| @@ -163,6 +163,11 @@ document.onreadystatechange = function () { | |||
| html += recordPrefix + actionName; | |||
| html += " <a href=\"" + getTaskLink(record) + "\" rel=\"nofollow\">" + record.RefName + "</a>" | |||
| } | |||
| else if(record.OpType == "35"){ | |||
| var datasetLink = "<a href=\"" + getRepoLink(record) + "/datasets" + "\" rel=\"nofollow\">" + record.Content.split('|')[1] + "</a>"; | |||
| actionName = actionName.replace('{dataset}', datasetLink); | |||
| html += recordPrefix + actionName; | |||
| } | |||
| else{ | |||
| continue; | |||
| } | |||
| @@ -354,7 +359,10 @@ var actionNameZH={ | |||
| "30":"导入了新模型", | |||
| "31":"创建了CPU/GPU类型训练任务", | |||
| "32":"创建了NPU类型训练任务", | |||
| "33":"创建了CPU/GPU类型训练任务" | |||
| "33":"创建了CPU/GPU类型训练任务", | |||
| "35":"创建的数据集 {dataset} 被设置为推荐数据集", | |||
| "36":"提交了镜像 {image}", | |||
| "37":"提交的镜像 {image} 被设置为推荐镜像", | |||
| }; | |||
| var actionNameEN={ | |||
| @@ -382,7 +390,10 @@ var actionNameEN={ | |||
| "30":" created new model", | |||
| "31":" created CPU/GPU type training task", | |||
| "32":" created NPU type training task", | |||
| "33":" created CPU/GPU type training task" | |||
| "33":" created CPU/GPU type training task", | |||
| "35":" created dataset {dataset} was set as recommended dataset", | |||
| "36":"committed image {image}", | |||
| "37":"committed image {image} was set as recommended image", | |||
| }; | |||
| var repoAndOrgZH={ | |||
| @@ -1052,7 +1052,7 @@ func TrainJobCreate(ctx *context.Context, form auth.CreateModelArtsTrainJobForm) | |||
| ctx.RenderWithErr("Resource specification not available", tplModelArtsTrainJobNew, &form) | |||
| return | |||
| } | |||
| if !account.IsPointBalanceEnough(ctx.User.ID, spec.UnitPrice) { | |||
| if !account.IsPointBalanceEnough(ctx.User.ID, spec.UnitPrice*form.WorkServerNumber) { | |||
| log.Error("point balance is not enough,userId=%d specId=%d", ctx.User.ID, spec.ID) | |||
| cloudBrainNewDataPrepare(ctx) | |||
| ctx.RenderWithErr(ctx.Tr("points.insufficient_points_balance"), tplModelArtsTrainJobNew, &form) | |||
| @@ -141,7 +141,7 @@ func GetAdminRewardList(ctx *context.Context) { | |||
| func buildAdminRewardRecordListOpts(ctx *context.Context) (*models.RewardRecordListOpts, error) { | |||
| operateType := ctx.Query("operate") | |||
| sourceType := ctx.Query("source") | |||
| actionType := ctx.QueryInt("action") | |||
| taskType := ctx.Query("action") | |||
| serialNo := ctx.Query("serialNo") | |||
| status := ctx.Query("status") | |||
| @@ -161,7 +161,7 @@ func buildAdminRewardRecordListOpts(ctx *context.Context) (*models.RewardRecordL | |||
| RewardType: models.RewardTypePoint, | |||
| OrderBy: orderBy, | |||
| SourceType: sourceType, | |||
| ActionType: actionType, | |||
| TaskType: taskType, | |||
| SerialNo: serialNo, | |||
| IsAdmin: true, | |||
| Status: status, | |||
| @@ -13,11 +13,11 @@ import ( | |||
| func GetTaskConfigList(ctx *context.Context) { | |||
| page := ctx.QueryInt("Page") | |||
| status := ctx.QueryInt("Status") | |||
| action := ctx.QueryInt("Action") | |||
| action := ctx.Query("Action") | |||
| r, err := task.GetTaskConfigWithLimitList(models.GetTaskConfigOpts{ | |||
| ListOptions: models.ListOptions{PageSize: 20, Page: page}, | |||
| Status: status, | |||
| ActionType: action, | |||
| TaskType: action, | |||
| }) | |||
| if err != nil { | |||
| log.Error("GetTaskConfigList error.%v", err) | |||
| @@ -25,20 +25,32 @@ func AcceptStatusChangeAction() { | |||
| } | |||
| func StartAndGetCloudBrainPointDeductTask(task models.Cloudbrain) (*models.RewardPeriodicTask, error) { | |||
| sourceId := getCloudBrainPointTaskSourceId(task) | |||
| r, err := GetPeriodicTask(models.SourceTypeRunCloudbrainTask, sourceId, sourceId, models.OperateTypeDecrease) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| if r != nil { | |||
| log.Debug("PeriodicTask is already exist.cloudbrain.ID = %d", task.ID) | |||
| return r, nil | |||
| } | |||
| if !setting.CloudBrainPaySwitch { | |||
| log.Debug("CloudBrainPaySwitch is off") | |||
| return nil, nil | |||
| } | |||
| unitPrice, err := models.GetCloudbrainTaskUnitPrice(task.ID) | |||
| unitPrice, err := models.GetCloudbrainTaskUnitPrice(task) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| if unitPrice == 0 { | |||
| log.Debug("finish StartAndGetCloudBrainPointDeductTask, UnitPrice = 0 task.ID=%d", task.ID) | |||
| log.Debug("Finish startAndGetCloudBrainPointDeductTask, UnitPrice = 0 task.ID=%d", task.ID) | |||
| return nil, nil | |||
| } | |||
| return StartAndGetPeriodicTask(&models.StartPeriodicTaskOpts{ | |||
| return StartPeriodicTask(&models.StartPeriodicTaskOpts{ | |||
| SourceType: models.SourceTypeRunCloudbrainTask, | |||
| SourceId: getCloudBrainPointTaskSourceId(task), | |||
| TargetUserId: task.UserID, | |||
| @@ -180,43 +180,41 @@ func UpdateRewardRecordToFinalStatus(sourceType, requestId, newStatus string) er | |||
| return nil | |||
| } | |||
| func StartPeriodicTaskAsyn(opts *models.StartPeriodicTaskOpts) { | |||
| go StartAndGetPeriodicTask(opts) | |||
| func GetPeriodicTask(sourceType models.SourceType, sourceId, requestId string, operateType models.RewardOperateType) (*models.RewardPeriodicTask, error) { | |||
| _, err := models.GetPointOperateRecordBySourceTypeAndRequestId(sourceType.Name(), requestId, operateType.Name()) | |||
| if err == nil { | |||
| task, err := models.GetPeriodicTaskBySourceIdAndType(sourceType, sourceId, operateType) | |||
| if err != nil { | |||
| log.Error("GetPeriodicTaskBySourceIdAndType error,%v", err) | |||
| return nil, err | |||
| } | |||
| return task, nil | |||
| } | |||
| if err != nil && !models.IsErrRecordNotExist(err) { | |||
| log.Error("GetPointOperateRecordBySourceTypeAndRequestId error,%v", err) | |||
| return nil, err | |||
| } | |||
| return nil, nil | |||
| } | |||
| func StartAndGetPeriodicTask(opts *models.StartPeriodicTaskOpts) (*models.RewardPeriodicTask, error) { | |||
| defer func() { | |||
| if err := recover(); err != nil { | |||
| combinedErr := fmt.Errorf("%s\n%s", err, log.Stack(2)) | |||
| log.Error("PANIC:%v", combinedErr) | |||
| } | |||
| }() | |||
| func StartPeriodicTask(opts *models.StartPeriodicTaskOpts) (*models.RewardPeriodicTask, error) { | |||
| //add lock | |||
| var rewardLock = redis_lock.NewDistributeLock(redis_key.RewardOperateLock(opts.RequestId, opts.SourceType.Name(), opts.OperateType.Name())) | |||
| isOk, err := rewardLock.Lock(3 * time.Second) | |||
| if err != nil { | |||
| log.Error("StartAndGetPeriodicTask RewardOperateLock error. %v", err) | |||
| return nil, err | |||
| } | |||
| if !isOk { | |||
| log.Info("duplicated operate request,targetUserId=%d requestId=%s", opts.TargetUserId, opts.RequestId) | |||
| return nil, nil | |||
| } | |||
| defer rewardLock.UnLock() | |||
| _, err = models.GetPointOperateRecordBySourceTypeAndRequestId(opts.SourceType.Name(), opts.RequestId, opts.OperateType.Name()) | |||
| if err == nil { | |||
| task, err := models.GetPeriodicTaskBySourceIdAndType(opts.SourceType, opts.SourceId, opts.OperateType) | |||
| if err != nil { | |||
| log.Error("GetPeriodicTaskBySourceIdAndType error,%v", err) | |||
| return nil, err | |||
| } | |||
| return task, nil | |||
| r, err := GetPeriodicTask(opts.SourceType, opts.SourceId, opts.RequestId, opts.OperateType) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| if err != nil && !models.IsErrRecordNotExist(err) { | |||
| log.Error("operate is handled error,%v", err) | |||
| return nil, err | |||
| if r != nil { | |||
| return r, nil | |||
| } | |||
| //new reward operate record | |||
| @@ -10,7 +10,7 @@ import ( | |||
| "github.com/elliotchance/orderedmap" | |||
| ) | |||
| var opTypes = []int{1, 2, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 17, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33} | |||
| var opTypes = []int{1, 2, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 17, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 35} | |||
| type ClientsManager struct { | |||
| Clients *orderedmap.OrderedMap | |||
| @@ -107,16 +107,18 @@ func initActionQueue() { | |||
| func filterUserPrivateInfo(action *models.Action) { | |||
| action.Comment = nil | |||
| action.ActUser.Email = "" | |||
| action.ActUser.Passwd = "" | |||
| action.ActUser.PasswdHashAlgo = "" | |||
| action.ActUser.PrivateKey = "" | |||
| action.ActUser.PublicKey = "" | |||
| action.ActUser.Salt = "" | |||
| action.ActUser.FullName = "" | |||
| action.ActUser.AvatarEmail = "" | |||
| action.ActUser.IsAdmin = false | |||
| action.ActUser.EmailNotificationsPreference = "" | |||
| action.ActUser.IsOperator = false | |||
| if action.ActUser != nil { | |||
| action.ActUser.Email = "" | |||
| action.ActUser.Passwd = "" | |||
| action.ActUser.PasswdHashAlgo = "" | |||
| action.ActUser.PrivateKey = "" | |||
| action.ActUser.PublicKey = "" | |||
| action.ActUser.Salt = "" | |||
| action.ActUser.FullName = "" | |||
| action.ActUser.AvatarEmail = "" | |||
| action.ActUser.IsAdmin = false | |||
| action.ActUser.EmailNotificationsPreference = "" | |||
| action.ActUser.IsOperator = false | |||
| } | |||
| } | |||
| @@ -6,6 +6,8 @@ import ( | |||
| "code.gitea.io/gitea/services/reward" | |||
| "code.gitea.io/gitea/services/reward/limiter" | |||
| "fmt" | |||
| "strconv" | |||
| "strings" | |||
| ) | |||
| func Accomplish(action models.Action) { | |||
| @@ -15,19 +17,25 @@ func Accomplish(action models.Action) { | |||
| log.Error("PANIC:%v", combinedErr) | |||
| } | |||
| }() | |||
| action.OpType = models.GetTaskOptType(action) | |||
| switch action.OpType { | |||
| taskType := models.GetTaskTypeFromAction(action.OpType) | |||
| if taskType == "" { | |||
| log.Info("Accomplish finished.taskType is not exist.action.ID=%d", action.ID) | |||
| return | |||
| } | |||
| actions := make([]models.Action, 0) | |||
| actions = append(actions, action) | |||
| switch taskType { | |||
| //only creating public repo can be rewarded | |||
| case models.ActionCreateRepo: | |||
| case models.TaskCreatePublicRepo: | |||
| if action.Repo.IsPrivate { | |||
| return | |||
| } | |||
| //only creating public image can be rewarded | |||
| case models.ActionCreateImage: | |||
| case models.TaskCreateImage: | |||
| if action.IsPrivate { | |||
| return | |||
| } | |||
| case models.ActionBindWechat: | |||
| case models.TaskBindWechat: | |||
| n, err := models.CountWechatBindLog(action.Content, models.WECHAT_BIND) | |||
| if err != nil { | |||
| log.Error("CountWechatBindLog error when accomplish task,err=%v", err) | |||
| @@ -38,23 +46,48 @@ func Accomplish(action models.Action) { | |||
| log.Debug("the wechat account has been bound before,wechatOpenId = %s", action.Content) | |||
| return | |||
| } | |||
| case models.TaskDatasetRecommended: | |||
| datasetIdStr := strings.Split(action.Content, "|")[0] | |||
| datasetId, _ := strconv.ParseInt(datasetIdStr, 10, 64) | |||
| users, err := models.GetAllDatasetContributorByDatasetId(datasetId) | |||
| if err != nil { | |||
| return | |||
| } | |||
| for _, user := range users { | |||
| if user.ID == action.ActUserID { | |||
| continue | |||
| } | |||
| actions = append(actions, models.Action{ | |||
| ID: action.ID, | |||
| OpType: models.ActionDatasetRecommended, | |||
| ActUserID: action.UserID, | |||
| UserID: user.ID, | |||
| RepoID: action.RepoID, | |||
| Content: action.Content, | |||
| }) | |||
| } | |||
| } | |||
| batchAccomplish(taskType, actions...) | |||
| } | |||
| func batchAccomplish(taskType models.TaskType, actions ...models.Action) { | |||
| for _, act := range actions { | |||
| go accomplish(act, taskType) | |||
| } | |||
| go accomplish(action) | |||
| } | |||
| func accomplish(action models.Action) error { | |||
| func accomplish(action models.Action, taskType models.TaskType) error { | |||
| defer func() { | |||
| if err := recover(); err != nil { | |||
| combinedErr := fmt.Errorf("%s\n%s", err, log.Stack(2)) | |||
| log.Error("PANIC:%v", combinedErr) | |||
| } | |||
| }() | |||
| userId := action.ActUserID | |||
| taskType := fmt.Sprint(action.OpType) | |||
| userId := action.UserID | |||
| //get task config | |||
| config, err := GetTaskConfig(taskType) | |||
| config, err := GetTaskConfig(string(taskType)) | |||
| if err != nil { | |||
| log.Error("GetTaskConfig error,%v", err) | |||
| return err | |||
| @@ -86,7 +119,7 @@ func accomplish(action models.Action) error { | |||
| reward.Operate(&models.RewardOperateContext{ | |||
| SourceType: models.SourceTypeAccomplishTask, | |||
| SourceId: fmt.Sprint(action.ID), | |||
| SourceTemplateId: fmt.Sprint(action.OpType), | |||
| SourceTemplateId: string(taskType), | |||
| Title: config.Title, | |||
| Reward: models.Reward{ | |||
| Amount: config.AwardAmount, | |||
| @@ -27,79 +27,79 @@ | |||
| <th style="width:200px;">上限值</th> | |||
| <th>奖励细节澄清</th> | |||
| </tr> | |||
| <tr key="34"> | |||
| <tr key="BindWechat"> | |||
| <td class="t-center">完成微信扫码验证</td> | |||
| <td class="t-center point">-</td> | |||
| <td class="t-center"><span class="typ">累计</span>积分获取上限<span class="limit"> - </span></td> | |||
| <td>1、首次完成微信扫码验证,即获取积分。<br>2、同个账号,更换微信号码再验证不重复给积分。<br>3、同一个微信,绑定第一个账号时奖励积分,下次绑定其他账号时不再奖励。</td> | |||
| </tr> | |||
| <tr key="1"> | |||
| <tr key="CreatePublicRepo"> | |||
| <td class="t-center">创建或Fork公开项目</td> | |||
| <td class="t-center point">-</td> | |||
| <td class="t-center"><span class="typ">每日</span>积分获取上限<span class="limit"> - </span></td> | |||
| <td>请注意项目质量,请勿复制粘贴或者重复公开项目,任何非常规的以公开项目去获取积分的行为将被认定为积分舞弊,将扣除所有积分。</td> | |||
| </tr> | |||
| <tr key="7"> | |||
| <tr key="CreatePullRequest"> | |||
| <td class="t-center">每日提出PR</td> | |||
| <td class="t-center point">-</td> | |||
| <td class="t-center"><span class="typ">每日</span>积分获取上限<span class="limit"> - </span></td> | |||
| <td></td> | |||
| </tr> | |||
| <tr key="40"> | |||
| <tr key="PushCommits"> | |||
| <td class="t-center">每日commit</td> | |||
| <td class="t-center point">-</td> | |||
| <td class="t-center"><span class="typ">每日</span>积分获取上限<span class="limit"> - </span></td> | |||
| <td>通过前台界面和后台命令行方式commit,都可获得奖励积分。</td> | |||
| </tr> | |||
| <tr key="6"> | |||
| <tr key="CreateIssue"> | |||
| <td class="t-center">每日提出任务</td> | |||
| <td class="t-center point">-</td> | |||
| <td class="t-center"><span class="typ">每日</span>积分获取上限<span class="limit"> - </span></td> | |||
| <td></td> | |||
| </tr> | |||
| <tr key="10"> | |||
| <tr key="CommentIssue"> | |||
| <td class="t-center">发表评论</td> | |||
| <td class="t-center point">-</td> | |||
| <td class="t-center"><span class="typ">每日</span>积分获取上限<span class="limit"> - </span></td> | |||
| <td>禁止空评论或评论后马上删除等非正常获取积分的方式,一经发现将扣除所有积分。</td> | |||
| </tr> | |||
| <tr key="24"> | |||
| <tr key="UploadAttachment"> | |||
| <td class="t-center">上传数据集文件</td> | |||
| <td class="t-center point">-</td> | |||
| <td class="t-center"><span class="typ">每日</span>积分获取上限<span class="limit"> - </span></td> | |||
| <td>请注意数据集质量,请勿复制粘贴或者重复公开数据集,任何非常规的以公开数据集去获取积分的行为将被认定为积分舞弊,将扣除所有积分。</td> | |||
| </tr> | |||
| <tr key="36"> | |||
| <tr key="DatasetRecommended"> | |||
| <td class="t-center">数据集被平台推荐</td> | |||
| <td class="t-center point">-</td> | |||
| <td class="t-center"><span class="typ">每日</span>积分获取上限<span class="limit"> - </span></td> | |||
| <td>仅统计属于个人的数据集,属于组织的数据集暂不统计。</td> | |||
| </tr> | |||
| <tr key="30"> | |||
| <tr key="CreateNewModelTask"> | |||
| <td class="t-center">导入新模型</td> | |||
| <td class="t-center point">-</td> | |||
| <td class="t-center"><span class="typ">每日</span>积分获取上限<span class="limit"> - </span></td> | |||
| <td>请注意模型质量,请勿重复导入相同模型,任何非常规的以导入新模型去获取 积分的行为将被认定为积分舞弊,将扣除所有积分。</td> | |||
| </tr> | |||
| <tr key="35"> | |||
| <tr key="CreateCloudbrainTask"> | |||
| <td class="t-center">每日运行云脑任务</td> | |||
| <td class="t-center point">-</td> | |||
| <td class="t-center"><span class="typ">每日</span>积分获取上限<span class="limit"> - </span></td> | |||
| <td> 每日运行调试、训练、推理、评测中任何一种任务,即可获得。</td> | |||
| </tr> | |||
| <tr key="37"> | |||
| <tr key="CreateImage"> | |||
| <td class="t-center">提交新公开镜像</td> | |||
| <td class="t-center point">-</td> | |||
| <td class="t-center"><span class="typ">每日</span>积分获取上限<span class="limit"> - </span></td> | |||
| <td></td> | |||
| </tr> | |||
| <tr key="38"> | |||
| <tr key="ImageRecommend"> | |||
| <td class="t-center">镜像被平台推荐</td> | |||
| <td class="t-center point">-</td> | |||
| <td class="t-center"><span class="typ">每日</span>积分获取上限<span class="limit"> - </span></td> | |||
| <td></td> | |||
| </tr> | |||
| <tr key="39"> | |||
| <tr key="ChangeUserAvatar"> | |||
| <td class="t-center">首次更换头像</td> | |||
| <td class="t-center point">-</td> | |||
| <td class="t-center"><span class="typ">累计</span>积分获取上限<span class="limit"> - </span></td> | |||
| @@ -133,7 +133,7 @@ | |||
| if (taskRule.TaskCode == key) { | |||
| ruleTr.find('.point').text(taskRule.AwardAmount); | |||
| ruleTr.find('.typ').text(taskRule.RefreshRate == 'DAILY' ? '每日' : taskRule.RefreshRate == 'NOT_CYCLE' ? '累计' : taskRule.RefreshRate); | |||
| ruleTr.find('.limit').text(taskRule.LimitNum); | |||
| ruleTr.find('.limit').text(taskRule.AwardAmount * taskRule.LimitNum); | |||
| findOr = true; | |||
| break; | |||
| } | |||
| @@ -90,6 +90,8 @@ | |||
| {{$.i18n.Tr "action.task_c2netnputrainjob" .GetRepoLink .Content .RefName | Str2html}} | |||
| {{else if eq .GetOpType 33}} | |||
| {{$.i18n.Tr "action.task_c2netgputrainjob" .GetRepoLink .Content .RefName | Str2html}} | |||
| {{else if eq .GetOpType 35}} | |||
| {{$.i18n.Tr "action.dataset_recommended" .GetRepoLink (index .GetIssueInfos 1 | RenderEmoji) | Str2html}} | |||
| {{end}} | |||
| </p> | |||
| {{if or (eq .GetOpType 5) (eq .GetOpType 18)}} | |||
| @@ -137,6 +139,8 @@ | |||
| <span class="text grey"><i class="ri-picture-in-picture-exit-line icon big"></i></span> | |||
| {{else if eq .GetOpType 31}} | |||
| <span class="text grey"><i class="ri-character-recognition-line icon big"></i></span> | |||
| {{else if eq .GetOpType 35}} | |||
| <span class="text grey"><i class="thumbs up outline icon big"></i></span> | |||
| {{else}} | |||
| <span class="text grey">{{svg (printf "octicon-%s" (ActionIcon .GetOpType)) 32}}</span> | |||
| {{end}} | |||
| @@ -3,8 +3,8 @@ import { i18n } from '~/langs'; | |||
| export const SOURCE_TYPE = [{ k: 'ACCOMPLISH_TASK', v: i18n.t('accomplishTask') }, { k: 'ADMIN_OPERATE', v: i18n.t('adminOperate') }, { k: 'RUN_CLOUDBRAIN_TASK', v: i18n.t('runCloudBrainTask') }]; | |||
| export const CONSUME_STATUS = [{ k: 'OPERATING', v: i18n.t('operating') }, { k: 'SUCCEEDED', v: i18n.t('succeeded') }]; | |||
| export const POINT_ACTIONS = [ | |||
| { k: 1, v: i18n.t('createPublicProject') }, { k: 6, v: i18n.t('dailyPutforwardTasks') }, { k: 7, v: i18n.t('dailyPR') }, { k: 10, v: i18n.t('comment') }, { k: 24, v: i18n.t('uploadDatasetFile') }, { k: 30, v: i18n.t('importNewModel') }, { k: 34, v: i18n.t('completeWechatCodeScanningVerification') }, | |||
| { k: 35, v: i18n.t('dailyRunCloudbrainTasks') }, { k: 36, v: i18n.t('datasetRecommendedByThePlatform') }, { k: 37, v: i18n.t('submitNewPublicImage') }, { k: 38, v: i18n.t('imageRecommendedByThePlatform') }, { k: 39, v: i18n.t('firstChangeofAvatar') }, { k: 40, v: i18n.t('dailyCommit') }, | |||
| { k: 'CreatePublicRepo', v: i18n.t('createPublicProject') }, { k: 'CreateIssue', v: i18n.t('dailyPutforwardTasks') }, { k: 'CreatePullRequest', v: i18n.t('dailyPR') }, { k: 'CommentIssue', v: i18n.t('comment') }, { k: 'UploadAttachment', v: i18n.t('uploadDatasetFile') }, { k: 'CreateNewModelTask', v: i18n.t('importNewModel') }, { k: 'BindWechat', v: i18n.t('completeWechatCodeScanningVerification') }, | |||
| { k: 'CreateCloudbrainTask', v: i18n.t('dailyRunCloudbrainTasks') }, { k: 'DatasetRecommended', v: i18n.t('datasetRecommendedByThePlatform') }, { k: 'CreateImage', v: i18n.t('submitNewPublicImage') }, { k: 'ImageRecommend', v: i18n.t('imageRecommendedByThePlatform') }, { k: 'ChangeUserAvatar', v: i18n.t('firstChangeofAvatar') }, { k: 'PushCommits', v: i18n.t('dailyCommit') }, | |||
| ]; | |||
| export const JOB_TYPE = [{ k: 'DEBUG', v: i18n.t('debugTask') }, { k: 'TRAIN', v: i18n.t('trainTask') }, { k: 'INFERENCE', v: i18n.t('inferenceTask') }, { k: 'BENCHMARK', v: i18n.t('benchmarkTask') }]; | |||
| @@ -69,6 +69,9 @@ const en = { | |||
| setAsRecommendedImage: ' was set as recommended image', | |||
| updatedAvatar: 'updated avatar', | |||
| pushedBranch: 'pushed to {branch} at ', | |||
| deleteBranch: 'deleted branch {branch} from {repo}', | |||
| pushedTag: ' pushed tag {tag} to ', | |||
| deleteTag: ' deleted tag {tag} from {repo}', | |||
| dailyMaxTips: `can't get full points when reach the daily upper limit`, | |||
| memory: 'Memory', | |||
| sharedMemory: 'Shared Memory', | |||
| @@ -129,6 +132,7 @@ const en = { | |||
| shareMem: 'Share Memory', | |||
| unitPrice: 'Unit Price', | |||
| point_hr: 'Point/hr', | |||
| node: 'node', | |||
| free: 'Free', | |||
| onShelfConfirm: 'Are you sure to on shelf the resources specification?', | |||
| offShelfConfirm: 'Are you sure to off shelf the resources specification?', | |||
| @@ -69,6 +69,9 @@ const zh = { | |||
| setAsRecommendedImage: '被设置为推荐镜像', | |||
| updatedAvatar: '更新了头像', | |||
| pushedBranch: '推送了{branch}分支代码到', | |||
| deleteBranch: '从{repo}删除分支{branch}', | |||
| pushedTag: '推送了标签{tag}到', | |||
| deleteTag: '从{repo}删除了标签{tag}', | |||
| dailyMaxTips: '达到每日上限积分,不能拿满分', | |||
| memory: '内存', | |||
| sharedMemory: '共享内存', | |||
| @@ -129,6 +132,7 @@ const zh = { | |||
| shareMem: '共享内存', | |||
| unitPrice: '单价', | |||
| point_hr: '积分/时', | |||
| node: '节点', | |||
| free: '免费', | |||
| onShelfConfirm: '请确认上架该规格?', | |||
| offShelfConfirm: '请确认下架该规格?', | |||
| @@ -60,7 +60,9 @@ const renderSpecStr = (spec, showPoint) => { | |||
| var ngpu = `${spec.ComputeResource}: ${spec.AccCardsNum + '*' + getListValueWithKey(ACC_CARD_TYPE, spec.AccCardType)}`; | |||
| var gpuMemStr = spec.GPUMemGiB != 0 ? `${i18n.t('resourcesManagement.gpuMem')}: ${spec.GPUMemGiB}GB, ` : ''; | |||
| var sharedMemStr = spec.ShareMemGiB != 0 ? `, ${i18n.t('resourcesManagement.shareMem')}: ${spec.ShareMemGiB}GB` : ''; | |||
| var pointStr = showPoint ? `, ${spec.UnitPrice == 0 ? i18n.t('resourcesManagement.free') : spec.UnitPrice + i18n.t('resourcesManagement.point_hr')}` : ''; | |||
| var workServerNum = spec.workServerNumber; | |||
| var workServerNumStr = showPoint && workServerNum != 1 && spec.UnitPrice != 0 ? '*' + workServerNum + i18n.t('resourcesManagement.node') : ''; | |||
| var pointStr = showPoint ? `, ${spec.UnitPrice == 0 ? i18n.t('resourcesManagement.free') : spec.UnitPrice + i18n.t('resourcesManagement.point_hr') + workServerNumStr}` : ''; | |||
| var specStr = `${ngpu}, CPU: ${spec.CpuCores}, ${gpuMemStr}${i18n.t('resourcesManagement.mem')}: ${spec.MemGiB}GB${sharedMemStr}${pointStr}`; | |||
| return specStr; | |||
| }; | |||
| @@ -77,7 +79,7 @@ export const getRewardPointRecordInfo = (record) => { | |||
| duration: record?.Cloudbrain?.Duration || '--', | |||
| taskName: record?.Cloudbrain?.DisplayJobName || '--', | |||
| taskId: record?.Cloudbrain?.ID, | |||
| action: record?.Action?.OpType ? getPointAction(record.Action.OpType) : '--', | |||
| action: record?.Action?.TaskType ? getPointAction(record.Action.TaskType) : '--', | |||
| remark: record.Remark, | |||
| amount: record.Amount, | |||
| }; | |||
| @@ -85,49 +87,72 @@ export const getRewardPointRecordInfo = (record) => { | |||
| if (record.SourceType === 'ADMIN_OPERATE') { | |||
| out.remark = record.Remark; | |||
| } else if (record.SourceType === 'ACCOMPLISH_TASK') { | |||
| switch (record?.Action?.OpType) { | |||
| case 1: // 创建公开项目 - 创建了项目OpenI/aiforge | |||
| switch (record?.Action?.TaskType) { | |||
| case 'CreatePublicRepo': // 创建公开项目 - 创建了项目OpenI/aiforge | |||
| out.remark = `${i18n.t('createdRepository')}<a href="${record.Action.RepoLink}" rel="nofollow">${record.Action.ShortRepoFullDisplayName}</a>`; | |||
| break; | |||
| case 6: // 每日提出任务 - 创建了任务PCL-Platform.Intelligence/AISynergy#19 | |||
| case 'CreateIssue': // 每日提出任务 - 创建了任务PCL-Platform.Intelligence/AISynergy#19 | |||
| out.remark = `${i18n.t('openedIssue')}<a href="${record.Action.RepoLink}/issues/${record.Action.IssueInfos[0]}" rel="nofollow">${record.Action.ShortRepoFullDisplayName}#${record.Action.IssueInfos[0]}</a>`; | |||
| break; | |||
| case 7: // 每日提出PR - 创建了合并请求OpenI/aiforge#1 | |||
| case 'CreatePullRequest': // 每日提出PR - 创建了合并请求OpenI/aiforge#1 | |||
| out.remark = `${i18n.t('createdPullRequest')}<a href="${record.Action.RepoLink}/pulls/${record.Action.IssueInfos[0]}" rel="nofollow">${record.Action.ShortRepoFullDisplayName}#${record.Action.IssueInfos[0]}</a>`; | |||
| break; | |||
| case 10: // 发表评论 - 评论了任务PCL-Platform.Intelligence/AISynergy#19 | |||
| case 'CommentIssue': // 发表评论 - 评论了任务PCL-Platform.Intelligence/AISynergy#19 | |||
| out.remark = `${i18n.t('commentedOnIssue')}<a href="${record.Action.CommentLink}" rel="nofollow">${record.Action.ShortRepoFullDisplayName}#${record.Action.IssueInfos[0]}</a>`; | |||
| break; | |||
| case 24: // 上传数据集文件 - 上传了数据集文件MMISTData.zip | |||
| case 'UploadAttachment': // 上传数据集文件 - 上传了数据集文件MMISTData.zip | |||
| out.remark = `${i18n.t('uploadDataset')}<a href="${record.Action.RepoLink}/datasets" rel="nofollow">${record.Action.RefName}</a>`; | |||
| break; | |||
| case 30: // 导入新模型 - 导入了新模型resnet50_qx7l | |||
| case 'CreateNewModelTask': // 导入新模型 - 导入了新模型resnet50_qx7l | |||
| out.remark = `${i18n.t('createdNewModel')}<a href="${record.Action.RepoLink}/modelmanage/show_model_info?name=${record.Action.RefName}" rel="nofollow">${record.Action.RefName}</a>`; | |||
| break; | |||
| case 34: // 完成微信扫码验证 - 首次绑定微信奖励 | |||
| case 'BindWechat': // 完成微信扫码验证 - 首次绑定微信奖励 | |||
| out.remark = `${i18n.t('firstBindingWechatRewards')}`; | |||
| break; | |||
| case 35: // 每日运行云脑任务 - 创建了(CPU/GPU/NPU)类型(调试/训练/推理/评测)任务tangl202204131431995 | |||
| case 'CreateCloudbrainTask': // 每日运行云脑任务 - 创建了(CPU/GPU/NPU)类型(调试/训练/推理/评测)任务tangl202204131431995 | |||
| out.remark = `${i18n.t('created')}${record.Action?.Cloudbrain?.ComputeResource}${i18n.t('type')}${getJobType(record.Action?.Cloudbrain?.JobType)} <a href="${getJobTypeLink(record, 'INCREASE')}" rel="nofollow">${record.Action.RefName}</a>`; | |||
| break; | |||
| case 36: // 数据集被平台推荐 - 数据集XXX被设置为推荐数据集 | |||
| case 'DatasetRecommended': // 数据集被平台推荐 - 数据集XXX被设置为推荐数据集 | |||
| out.remark = `${i18n.t('dataset')}<a href="${record.Action.RepoLink}/datasets" rel="nofollow">${record.Action.Content && record.Action.Content.split('|')[1]}</a>${i18n.t('setAsRecommendedDataset')}`; | |||
| break; | |||
| case 37: // 提交新公开镜像 - 提交了镜像jiangxiang_ceshi_tang03 | |||
| case 'CreateImage': // 提交新公开镜像 - 提交了镜像jiangxiang_ceshi_tang03 | |||
| out.remark = `${i18n.t('committedImage')}<span style="font-weight:bold;">${record.Action.Content && record.Action.Content.split('|')[1]}</span>`; | |||
| break; | |||
| case 38: // 镜像被平台推荐 - 镜像XXX被设置为推荐镜像 | |||
| case 'ImageRecommend': // 镜像被平台推荐 - 镜像XXX被设置为推荐镜像 | |||
| out.remark = `${i18n.t('image')}<span style="font-weight:bold;">${record.Action.Content && record.Action.Content.split('|')[1]}</span>${i18n.t('setAsRecommendedImage')}`; | |||
| break; | |||
| case 39: // 首次更换头像 - 更新了头像 | |||
| case 'ChangeUserAvatar': // 首次更换头像 - 更新了头像 | |||
| out.remark = `${i18n.t('updatedAvatar')}`; | |||
| break; | |||
| case 40: // 每日commit - 推送了xxxx分支的代码到OpenI/aiforge | |||
| const words = record.Action.RefName.split('/'); | |||
| const branch = words[words.length - 1]; | |||
| out.remark = `${i18n.t('pushedBranch', { | |||
| branch: `<a href="${record.Action.RepoLink}/src/branch/${branch}" rel="nofollow">${branch}</a>` | |||
| })}<a href="${record.Action.RepoLink}" rel="nofollow">${record.Action.ShortRepoFullDisplayName}</a>`; | |||
| case 'PushCommits': // 每日commit - 推送了xxxx分支的代码到OpenI/aiforge | |||
| const opType = record.Action.OpType; | |||
| if (opType == 5) { | |||
| const words = record.Action.RefName.split('/'); | |||
| const branch = words[words.length - 1]; | |||
| out.remark = `${i18n.t('pushedBranch', { | |||
| branch: `<a href="${record.Action.RepoLink}/src/branch/${branch}" rel="nofollow">${branch}</a>` | |||
| })}<a href="${record.Action.RepoLink}" rel="nofollow">${record.Action.ShortRepoFullDisplayName}</a>`; | |||
| } else if (opType == 9) { | |||
| const words = record.Action.RefName.split('/'); | |||
| const tag = words[words.length - 1]; | |||
| out.remark = `${i18n.t('pushedTag', { | |||
| tag: `<a href="${record.Action.RepoLink}/src/tag/${tag}" rel="nofollow">${tag}</a>` | |||
| })}<a href="${record.Action.RepoLink}" rel="nofollow">${record.Action.ShortRepoFullDisplayName}</a>`; | |||
| } else if (opType == 16) { | |||
| const words = record.Action.RefName.split('/'); | |||
| const tag = words[words.length - 1]; | |||
| out.remark = `${i18n.t('deleteTag', { | |||
| repo: `<a href="${record.Action.RepoLink}" rel="nofollow">${record.Action.ShortRepoFullDisplayName}</a>`, | |||
| tag: tag, | |||
| })}`; | |||
| } else if (opType == 17) { | |||
| const words = record.Action.RefName.split('/'); | |||
| const branch = words[words.length - 1]; | |||
| out.remark = `${i18n.t('deleteBranch', { | |||
| repo: `<a href="${record.Action.RepoLink}" rel="nofollow">${record.Action.ShortRepoFullDisplayName}</a>`, | |||
| branch: branch, | |||
| })}`; | |||
| } | |||
| break; | |||
| default: | |||
| break; | |||
| @@ -145,15 +170,10 @@ export const getRewardPointRecordInfo = (record) => { | |||
| } else if (record.SourceType === 'ACCOMPLISH_TASK') { | |||
| // | |||
| } else if (record.SourceType === 'RUN_CLOUDBRAIN_TASK') { | |||
| out.taskName = `<a href="${getJobTypeLink(record, 'DECREASE')}" rel="nofollow">${record?.Cloudbrain?.DisplayJobName}</a>`; | |||
| // if (record?.Cloudbrain?.ComputeResource === 'CPU/GPU') { | |||
| // const resourceSpec = record?.Cloudbrain?.ResourceSpec?.ResourceSpec; | |||
| // out.remark = `【${getJobType(record?.Cloudbrain?.JobType)}】【${record?.Cloudbrain?.ComputeResource}】【GPU: ${resourceSpec?.gpu}, CPU: ${resourceSpec?.cpu}, ${i18n.t('memory')}: ${(resourceSpec?.memMiB / 1024).toFixed(2)}GB, ${i18n.t('sharedMemory')}: ${(resourceSpec?.shareMemMiB / 1024).toFixed(2)}GB】`; | |||
| // } else { | |||
| // out.remark = `【${getJobType(record?.Cloudbrain?.JobType)}】【${record?.Cloudbrain?.ComputeResource}】【${record?.Cloudbrain?.ResourceSpec.FlavorInfo.desc}】`; | |||
| // } | |||
| out.taskName = `<a href="${getJobTypeLink(record, 'DECREASE')}" rel="nofollow">${record?.Cloudbrain?.DisplayJobName}</a>`; | |||
| const resourceSpec = record?.Cloudbrain?.ResourceSpec; | |||
| if (resourceSpec) { | |||
| resourceSpec.workServerNumber = record?.Cloudbrain?.WorkServerNumber || 1; | |||
| out.remark = `【${getJobType(record?.Cloudbrain?.JobType)}】【${renderSpecStr(resourceSpec, true)}】`; | |||
| } | |||
| } | |||