summaryrefslogtreecommitdiffstats
path: root/models/action.go
diff options
context:
space:
mode:
authorLunny Xiao <xiaolunwen@gmail.com>2021-12-12 23:48:20 +0800
committerGitHub <noreply@github.com>2021-12-12 23:48:20 +0800
commit572324049008ac803d3d7c17a7b3a81ef00386fc (patch)
treea9c3709643a23165d27aa67e76f10f26a89936d5 /models/action.go
parent0a7e8327a017c5dd43e552bbcd0d0f056bc1671b (diff)
downloadgitea-572324049008ac803d3d7c17a7b3a81ef00386fc.tar.gz
gitea-572324049008ac803d3d7c17a7b3a81ef00386fc.zip
Some repository refactors (#17950)
* some repository refactors * remove unnecessary code * Fix test * Remove unnecessary banner
Diffstat (limited to 'models/action.go')
-rw-r--r--models/action.go125
1 files changed, 125 insertions, 0 deletions
diff --git a/models/action.go b/models/action.go
index 16d6c42aa5..da9e6776b1 100644
--- a/models/action.go
+++ b/models/action.go
@@ -16,6 +16,7 @@ import (
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo"
+ "code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/git"
@@ -414,3 +415,127 @@ func DeleteOldActions(olderThan time.Duration) (err error) {
_, err = db.GetEngine(db.DefaultContext).Where("created_unix < ?", time.Now().Add(-olderThan).Unix()).Delete(&Action{})
return
}
+
+func notifyWatchers(ctx context.Context, actions ...*Action) error {
+ var watchers []*repo_model.Watch
+ var repo *repo_model.Repository
+ var err error
+ var permCode []bool
+ var permIssue []bool
+ var permPR []bool
+
+ e := db.GetEngine(ctx)
+
+ for _, act := range actions {
+ repoChanged := repo == nil || repo.ID != act.RepoID
+
+ if repoChanged {
+ // Add feeds for user self and all watchers.
+ watchers, err = repo_model.GetWatchers(ctx, act.RepoID)
+ if err != nil {
+ return fmt.Errorf("get watchers: %v", err)
+ }
+ }
+
+ // Add feed for actioner.
+ act.UserID = act.ActUserID
+ if _, err = e.Insert(act); err != nil {
+ return fmt.Errorf("insert new actioner: %v", err)
+ }
+
+ if repoChanged {
+ act.loadRepo()
+ repo = act.Repo
+
+ // check repo owner exist.
+ if err := act.Repo.GetOwner(ctx); err != nil {
+ return fmt.Errorf("can't get repo owner: %v", err)
+ }
+ } else if act.Repo == nil {
+ act.Repo = repo
+ }
+
+ // Add feed for organization
+ if act.Repo.Owner.IsOrganization() && act.ActUserID != act.Repo.Owner.ID {
+ act.ID = 0
+ act.UserID = act.Repo.Owner.ID
+ if _, err = e.InsertOne(act); err != nil {
+ return fmt.Errorf("insert new actioner: %v", err)
+ }
+ }
+
+ if repoChanged {
+ permCode = make([]bool, len(watchers))
+ permIssue = make([]bool, len(watchers))
+ permPR = make([]bool, len(watchers))
+ for i, watcher := range watchers {
+ user, err := user_model.GetUserByIDEngine(e, watcher.UserID)
+ if err != nil {
+ permCode[i] = false
+ permIssue[i] = false
+ permPR[i] = false
+ continue
+ }
+ perm, err := getUserRepoPermission(ctx, repo, user)
+ if err != nil {
+ permCode[i] = false
+ permIssue[i] = false
+ permPR[i] = false
+ continue
+ }
+ permCode[i] = perm.CanRead(unit.TypeCode)
+ permIssue[i] = perm.CanRead(unit.TypeIssues)
+ permPR[i] = perm.CanRead(unit.TypePullRequests)
+ }
+ }
+
+ for i, watcher := range watchers {
+ if act.ActUserID == watcher.UserID {
+ continue
+ }
+ act.ID = 0
+ act.UserID = watcher.UserID
+ act.Repo.Units = nil
+
+ switch act.OpType {
+ case ActionCommitRepo, ActionPushTag, ActionDeleteTag, ActionPublishRelease, ActionDeleteBranch:
+ if !permCode[i] {
+ continue
+ }
+ case ActionCreateIssue, ActionCommentIssue, ActionCloseIssue, ActionReopenIssue:
+ if !permIssue[i] {
+ continue
+ }
+ case ActionCreatePullRequest, ActionCommentPull, ActionMergePullRequest, ActionClosePullRequest, ActionReopenPullRequest:
+ if !permPR[i] {
+ continue
+ }
+ }
+
+ if _, err = e.InsertOne(act); err != nil {
+ return fmt.Errorf("insert new action: %v", err)
+ }
+ }
+ }
+ return nil
+}
+
+// NotifyWatchers creates batch of actions for every watcher.
+func NotifyWatchers(actions ...*Action) error {
+ return notifyWatchers(db.DefaultContext, actions...)
+}
+
+// NotifyWatchersActions creates batch of actions for every watcher.
+func NotifyWatchersActions(acts []*Action) error {
+ ctx, committer, err := db.TxContext()
+ if err != nil {
+ return err
+ }
+ defer committer.Close()
+ for _, act := range acts {
+ if err := notifyWatchers(ctx, act); err != nil {
+ return err
+ }
+ }
+ return committer.Commit()
+}