@@ -89,6 +89,7 @@ type Action struct { | |||
IsTransformed bool `xorm:"INDEX NOT NULL DEFAULT false"` | |||
Content string `xorm:"TEXT"` | |||
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` | |||
Cloudbrain *Cloudbrain `xorm:"-"` | |||
} | |||
type ActionShow struct { | |||
@@ -100,6 +101,7 @@ type ActionShow struct { | |||
IssueInfos []string | |||
CommentLink string | |||
IssueTitle string | |||
Cloudbrain *CloudbrainShow4Action | |||
} | |||
// GetOpType gets the ActionType of this action. | |||
@@ -256,22 +258,25 @@ func (a *Action) ToShow() *ActionShow { | |||
actionShow.CommentLink = a.GetCommentLink() | |||
} | |||
if a.Cloudbrain != nil { | |||
c := &CloudbrainShow4Action{ | |||
ID: a.Cloudbrain.ID, | |||
Type: a.Cloudbrain.Type, | |||
JobType: a.Cloudbrain.JobType, | |||
DisplayJobName: a.Cloudbrain.DisplayJobName, | |||
ComputeResource: a.Cloudbrain.ComputeResource, | |||
} | |||
actionShow.Cloudbrain = c | |||
} | |||
return actionShow | |||
} | |||
func GetTaskOptType(action Action) ActionType { | |||
switch action.OpType { | |||
case ActionCreateDebugGPUTask, | |||
ActionCreateDebugNPUTask, | |||
ActionCreateTrainTask, | |||
ActionCreateInferenceTask, | |||
ActionCreateBenchMarkTask, | |||
ActionCreateGPUTrainTask: | |||
if action.IsCloudbrainAction() { | |||
return ActionCreateCloudbrainTask | |||
default: | |||
return action.OpType | |||
} | |||
return action.OpType | |||
} | |||
// GetRepositoryFromMatch returns a *Repository from a username and repo strings | |||
@@ -371,6 +376,19 @@ func (a *Action) GetIssueContent() string { | |||
return issue.Content | |||
} | |||
func (a *Action) IsCloudbrainAction() bool { | |||
switch a.OpType { | |||
case ActionCreateDebugGPUTask, | |||
ActionCreateDebugNPUTask, | |||
ActionCreateTrainTask, | |||
ActionCreateInferenceTask, | |||
ActionCreateBenchMarkTask, | |||
ActionCreateGPUTrainTask: | |||
return true | |||
} | |||
return false | |||
} | |||
// GetFeedsOptions options for retrieving feeds | |||
type GetFeedsOptions struct { | |||
RequestedUser *User // the user we want activity for | |||
@@ -4,7 +4,10 @@ | |||
package models | |||
import "fmt" | |||
import ( | |||
"fmt" | |||
"strconv" | |||
) | |||
// ActionList defines a list of actions | |||
type ActionList []*Action | |||
@@ -111,7 +114,9 @@ func (actions ActionList) loadComments(e Engine) ([]*Comment, error) { | |||
} | |||
for _, action := range actions { | |||
action.Comment = commentMaps[action.CommentID] | |||
if action.CommentID > 0 { | |||
action.Comment = commentMaps[action.CommentID] | |||
} | |||
} | |||
return valuesComment(commentMaps), nil | |||
} | |||
@@ -121,6 +126,52 @@ func (actions ActionList) LoadComments() ([]*Comment, error) { | |||
return actions.loadComments(x) | |||
} | |||
func (actions ActionList) getCloudbrainIDs() []int64 { | |||
cloudbrainIDs := make(map[int64]struct{}, 0) | |||
for _, action := range actions { | |||
if !action.IsCloudbrainAction() { | |||
continue | |||
} | |||
cloudbrainId, _ := strconv.ParseInt(action.Content, 10, 64) | |||
if _, ok := cloudbrainIDs[cloudbrainId]; !ok { | |||
cloudbrainIDs[cloudbrainId] = struct{}{} | |||
} | |||
} | |||
return keysInt64(cloudbrainIDs) | |||
} | |||
func (actions ActionList) loadCloudbrains(e Engine) ([]*Cloudbrain, error) { | |||
if len(actions) == 0 { | |||
return nil, nil | |||
} | |||
cloudbrainIDs := actions.getCloudbrainIDs() | |||
cloudbrainMaps := make(map[int64]*Cloudbrain, len(cloudbrainIDs)) | |||
if len(cloudbrainIDs) == 0 { | |||
return make([]*Cloudbrain, 0), nil | |||
} | |||
err := e. | |||
In("id", cloudbrainIDs).Unscoped(). | |||
Find(&cloudbrainMaps) | |||
if err != nil { | |||
return nil, fmt.Errorf("find cloudbrain: %v", err) | |||
} | |||
for _, action := range actions { | |||
cloudbrainId, _ := strconv.ParseInt(action.Content, 10, 64) | |||
if cloudbrainId > 0 { | |||
action.Cloudbrain = cloudbrainMaps[cloudbrainId] | |||
} | |||
} | |||
return valuesCloudbrain(cloudbrainMaps), nil | |||
} | |||
// LoadComments loads actions' all comments | |||
func (actions ActionList) LoadCloudbrains() ([]*Comment, error) { | |||
return actions.loadComments(x) | |||
} | |||
// loadAttributes loads all attributes | |||
func (actions ActionList) loadAttributes(e Engine) (err error) { | |||
if _, err = actions.loadUsers(e); err != nil { | |||
@@ -140,7 +191,7 @@ func (actions ActionList) LoadAttributes() error { | |||
} | |||
// LoadAllAttributes loads all attributes of the actions | |||
// compare with LoadAttributes() ,LoadAllAttributes() loads Comment attribute | |||
// compare with LoadAttributes() ,LoadAllAttributes() loads Comment and Cloudbrain attribute | |||
func (actions ActionList) LoadAllAttributes() error { | |||
return actions.loadAllAttributes(x) | |||
} | |||
@@ -159,5 +210,9 @@ func (actions ActionList) loadAllAttributes(e Engine) (err error) { | |||
return | |||
} | |||
if _, err = actions.loadCloudbrains(e); err != nil { | |||
return | |||
} | |||
return nil | |||
} |
@@ -179,6 +179,14 @@ type CloudbrainShow struct { | |||
ComputeResource string | |||
} | |||
type CloudbrainShow4Action struct { | |||
ID int64 | |||
Type int | |||
JobType string | |||
DisplayJobName string | |||
ComputeResource string | |||
} | |||
func (task *Cloudbrain) ToShow() *CloudbrainShow { | |||
return &CloudbrainShow{ | |||
ID: task.ID, | |||
@@ -35,3 +35,10 @@ func valuesComment(m map[int64]*Comment) []*Comment { | |||
} | |||
return values | |||
} | |||
func valuesCloudbrain(m map[int64]*Cloudbrain) []*Cloudbrain { | |||
var values = make([]*Cloudbrain, 0, len(m)) | |||
for _, v := range m { | |||
values = append(values, v) | |||
} | |||
return values | |||
} |
@@ -375,7 +375,7 @@ func (t *actionNotifier) NotifyDatasetRecommend(optUser *models.User, dataset *m | |||
ActUser: user, | |||
RepoID: dataset.RepoID, | |||
Repo: dataset.Repo, | |||
Content: fmt.Sprint(dataset.ID), | |||
Content: fmt.Sprintf("%d|%s", dataset.ID, dataset.Title), | |||
}) | |||
} | |||
if err := models.NotifyWatchers(actions...); err != nil { | |||
@@ -390,18 +390,14 @@ func (t *actionNotifier) NotifyCreateImage(doer *models.User, image models.Image | |||
ActUser: doer, | |||
OpType: models.ActionCreateImage, | |||
IsPrivate: image.IsPrivate, | |||
Content: fmt.Sprint(image.ID), | |||
Content: fmt.Sprintf("%d|%s", image.ID, image.Tag), | |||
} | |||
if err := models.NotifyWatchers(act); err != nil { | |||
log.Error("notifyWatchers: %v", err) | |||
} | |||
} | |||
func (t *actionNotifier) NotifyImageRecommend(optUser *models.User, imageId int64, action string) { | |||
image, err := models.GetImageByID(imageId) | |||
if err != nil { | |||
return | |||
} | |||
func (t *actionNotifier) NotifyImageRecommend(optUser *models.User, image *models.Image, action string) { | |||
u, err := models.GetUserByID(image.UID) | |||
if err != nil { | |||
return | |||
@@ -413,7 +409,7 @@ func (t *actionNotifier) NotifyImageRecommend(optUser *models.User, imageId int6 | |||
ActUser: u, | |||
OpType: models.ActionImageRecommend, | |||
IsPrivate: false, | |||
Content: fmt.Sprint(imageId), | |||
Content: fmt.Sprintf("%d|%s", image.ID, image.Tag), | |||
} | |||
if err := models.NotifyWatchers(act); err != nil { | |||
log.Error("notifyWatchers: %v", err) | |||
@@ -60,6 +60,6 @@ type Notifier interface { | |||
NotifyWechatBind(user *models.User, wechatOpenId string) | |||
NotifyDatasetRecommend(optUser *models.User, dataset *models.Dataset, action string) | |||
NotifyCreateImage(doer *models.User, image models.Image) | |||
NotifyImageRecommend(optUser *models.User, imageId int64, action string) | |||
NotifyImageRecommend(optUser *models.User, image *models.Image, action string) | |||
NotifyChangeUserAvatar(user *models.User, form auth.AvatarForm) | |||
} |
@@ -170,7 +170,7 @@ func (*NullNotifier) NotifyDatasetRecommend(optUser *models.User, dataset *model | |||
func (*NullNotifier) NotifyCreateImage(doer *models.User, image models.Image) { | |||
} | |||
func (*NullNotifier) NotifyImageRecommend(optUser *models.User, imageId int64, action string) { | |||
func (*NullNotifier) NotifyImageRecommend(optUser *models.User, image *models.Image, action string) { | |||
} | |||
func (*NullNotifier) NotifyChangeUserAvatar(user *models.User, form auth.AvatarForm) { | |||
@@ -293,9 +293,9 @@ func NotifyCreateImage(doer *models.User, image models.Image) { | |||
} | |||
// NotifyDatasetRecommend | |||
func NotifyImageRecommend(optUser *models.User, imageId int64, action string) { | |||
func NotifyImageRecommend(optUser *models.User, image *models.Image, action string) { | |||
for _, notifier := range notifiers { | |||
notifier.NotifyImageRecommend(optUser, imageId, action) | |||
notifier.NotifyImageRecommend(optUser, image, action) | |||
} | |||
} | |||
@@ -26,7 +26,10 @@ func Action(ctx *context.Context) { | |||
if err != nil { | |||
ctx.JSON(http.StatusOK, models.BaseErrorMessage(ctx.Tr("repo.star_fail", ctx.Params(":action")))) | |||
} else { | |||
notification.NotifyImageRecommend(ctx.User, imageId, ctx.Params(":action")) | |||
image, err := models.GetImageByID(imageId) | |||
if err == nil { | |||
notification.NotifyImageRecommend(ctx.User, image, ctx.Params(":action")) | |||
} | |||
ctx.JSON(http.StatusOK, models.BaseOKMessage) | |||
} | |||
} |