Fix activity feed (#1779)
* Fix activity feed Preserve actions after user/repo name change * Add missing comment * Fix migration, and remove fields completely * Tests
This commit is contained in:
		
							parent
							
								
									03912ce014
								
							
						
					
					
						commit
						0c332f0480
					
				| @ -6,7 +6,7 @@ DB_TYPE  = mysql | ||||
| HOST     = 127.0.0.1:3306 | ||||
| NAME     = testgitea | ||||
| USER     = root | ||||
| PASSWD   = | ||||
| PASSWD   =  | ||||
| SSL_MODE = disable | ||||
| PATH     = data/gitea.db | ||||
| 
 | ||||
| @ -26,14 +26,14 @@ OFFLINE_MODE     = false | ||||
| ENABLED = false | ||||
| 
 | ||||
| [service] | ||||
| REGISTER_EMAIL_CONFIRM     = false | ||||
| ENABLE_NOTIFY_MAIL         = false | ||||
| DISABLE_REGISTRATION       = false | ||||
| ENABLE_CAPTCHA             = false | ||||
| REQUIRE_SIGNIN_VIEW        = false | ||||
| DEFAULT_KEEP_EMAIL_PRIVATE = false | ||||
| REGISTER_EMAIL_CONFIRM            = false | ||||
| ENABLE_NOTIFY_MAIL                = false | ||||
| DISABLE_REGISTRATION              = false | ||||
| ENABLE_CAPTCHA                    = false | ||||
| REQUIRE_SIGNIN_VIEW               = false | ||||
| DEFAULT_KEEP_EMAIL_PRIVATE        = false | ||||
| DEFAULT_ALLOW_CREATE_ORGANIZATION = true | ||||
| NO_REPLY_ADDRESS           = noreply.example.org | ||||
| NO_REPLY_ADDRESS                  = noreply.example.org | ||||
| 
 | ||||
| [picture] | ||||
| DISABLE_GRAVATAR        = false | ||||
| @ -53,5 +53,7 @@ LEVEL = Warn | ||||
| LEVEL = Info | ||||
| 
 | ||||
| [security] | ||||
| INSTALL_LOCK = true | ||||
| SECRET_KEY   = 9pCviYTWSb | ||||
| INSTALL_LOCK   = true | ||||
| SECRET_KEY     = 9pCviYTWSb | ||||
| INTERNAL_TOKEN = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYmYiOjE0OTU1NTE2MTh9.hhSVGOANkaKk3vfCd2jDOIww4pUk0xtg9JRde5UogyQ | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										144
									
								
								models/action.go
									
									
									
									
									
								
							
							
						
						
									
										144
									
								
								models/action.go
									
									
									
									
									
								
							| @ -70,20 +70,18 @@ func init() { | ||||
| // repository. It implemented interface base.Actioner so that can be
 | ||||
| // used in template render.
 | ||||
| type Action struct { | ||||
| 	ID           int64 `xorm:"pk autoincr"` | ||||
| 	UserID       int64 `xorm:"INDEX"` // Receiver user id.
 | ||||
| 	OpType       ActionType | ||||
| 	ActUserID    int64  `xorm:"INDEX"` // Action user id.
 | ||||
| 	ActUserName  string // Action user name.
 | ||||
| 	ActAvatar    string `xorm:"-"` | ||||
| 	RepoID       int64  `xorm:"INDEX"` | ||||
| 	RepoUserName string | ||||
| 	RepoName     string | ||||
| 	RefName      string | ||||
| 	IsPrivate    bool      `xorm:"INDEX NOT NULL DEFAULT false"` | ||||
| 	Content      string    `xorm:"TEXT"` | ||||
| 	Created      time.Time `xorm:"-"` | ||||
| 	CreatedUnix  int64     `xorm:"INDEX"` | ||||
| 	ID          int64 `xorm:"pk autoincr"` | ||||
| 	UserID      int64 `xorm:"INDEX"` // Receiver user id.
 | ||||
| 	OpType      ActionType | ||||
| 	ActUserID   int64       `xorm:"INDEX"` // Action user id.
 | ||||
| 	ActUser     *User       `xorm:"-"` | ||||
| 	RepoID      int64       `xorm:"INDEX"` | ||||
| 	Repo        *Repository `xorm:"-"` | ||||
| 	RefName     string | ||||
| 	IsPrivate   bool      `xorm:"INDEX NOT NULL DEFAULT false"` | ||||
| 	Content     string    `xorm:"TEXT"` | ||||
| 	Created     time.Time `xorm:"-"` | ||||
| 	CreatedUnix int64     `xorm:"INDEX"` | ||||
| } | ||||
| 
 | ||||
| // BeforeInsert will be invoked by XORM before inserting a record
 | ||||
| @ -106,42 +104,71 @@ func (a *Action) GetOpType() int { | ||||
| 	return int(a.OpType) | ||||
| } | ||||
| 
 | ||||
| func (a *Action) loadActUser() { | ||||
| 	if a.ActUser != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	var err error | ||||
| 	a.ActUser, err = GetUserByID(a.ActUserID) | ||||
| 	if err == nil { | ||||
| 		return | ||||
| 	} else if IsErrUserNotExist(err) { | ||||
| 		a.ActUser = NewGhostUser() | ||||
| 	} else { | ||||
| 		log.Error(4, "GetUserByID(%d): %v", a.ActUserID, err) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (a *Action) loadRepo() { | ||||
| 	if a.ActUser != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	var err error | ||||
| 	a.Repo, err = GetRepositoryByID(a.RepoID) | ||||
| 	if err != nil { | ||||
| 		log.Error(4, "GetRepositoryByID(%d): %v", a.RepoID, err) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // GetActUserName gets the action's user name.
 | ||||
| func (a *Action) GetActUserName() string { | ||||
| 	return a.ActUserName | ||||
| 	a.loadActUser() | ||||
| 	return a.ActUser.Name | ||||
| } | ||||
| 
 | ||||
| // ShortActUserName gets the action's user name trimmed to max 20
 | ||||
| // chars.
 | ||||
| func (a *Action) ShortActUserName() string { | ||||
| 	return base.EllipsisString(a.ActUserName, 20) | ||||
| 	return base.EllipsisString(a.GetActUserName(), 20) | ||||
| } | ||||
| 
 | ||||
| // GetRepoUserName returns the name of the action repository owner.
 | ||||
| func (a *Action) GetRepoUserName() string { | ||||
| 	return a.RepoUserName | ||||
| 	a.loadRepo() | ||||
| 	return a.Repo.MustOwner().Name | ||||
| } | ||||
| 
 | ||||
| // ShortRepoUserName returns the name of the action repository owner
 | ||||
| // trimmed to max 20 chars.
 | ||||
| func (a *Action) ShortRepoUserName() string { | ||||
| 	return base.EllipsisString(a.RepoUserName, 20) | ||||
| 	return base.EllipsisString(a.GetRepoUserName(), 20) | ||||
| } | ||||
| 
 | ||||
| // GetRepoName returns the name of the action repository.
 | ||||
| func (a *Action) GetRepoName() string { | ||||
| 	return a.RepoName | ||||
| 	a.loadRepo() | ||||
| 	return a.Repo.Name | ||||
| } | ||||
| 
 | ||||
| // ShortRepoName returns the name of the action repository
 | ||||
| // trimmed to max 33 chars.
 | ||||
| func (a *Action) ShortRepoName() string { | ||||
| 	return base.EllipsisString(a.RepoName, 33) | ||||
| 	return base.EllipsisString(a.GetRepoName(), 33) | ||||
| } | ||||
| 
 | ||||
| // GetRepoPath returns the virtual path to the action repository.
 | ||||
| func (a *Action) GetRepoPath() string { | ||||
| 	return path.Join(a.RepoUserName, a.RepoName) | ||||
| 	return path.Join(a.GetRepoUserName(), a.GetRepoName()) | ||||
| } | ||||
| 
 | ||||
| // ShortRepoPath returns the virtual path to the action repository
 | ||||
| @ -205,13 +232,12 @@ func (a *Action) GetIssueContent() string { | ||||
| 
 | ||||
| func newRepoAction(e Engine, u *User, repo *Repository) (err error) { | ||||
| 	if err = notifyWatchers(e, &Action{ | ||||
| 		ActUserID:    u.ID, | ||||
| 		ActUserName:  u.Name, | ||||
| 		OpType:       ActionCreateRepo, | ||||
| 		RepoID:       repo.ID, | ||||
| 		RepoUserName: repo.Owner.Name, | ||||
| 		RepoName:     repo.Name, | ||||
| 		IsPrivate:    repo.IsPrivate, | ||||
| 		ActUserID: u.ID, | ||||
| 		ActUser:   u, | ||||
| 		OpType:    ActionCreateRepo, | ||||
| 		RepoID:    repo.ID, | ||||
| 		Repo:      repo, | ||||
| 		IsPrivate: repo.IsPrivate, | ||||
| 	}); err != nil { | ||||
| 		return fmt.Errorf("notify watchers '%d/%d': %v", u.ID, repo.ID, err) | ||||
| 	} | ||||
| @ -227,14 +253,13 @@ func NewRepoAction(u *User, repo *Repository) (err error) { | ||||
| 
 | ||||
| func renameRepoAction(e Engine, actUser *User, oldRepoName string, repo *Repository) (err error) { | ||||
| 	if err = notifyWatchers(e, &Action{ | ||||
| 		ActUserID:    actUser.ID, | ||||
| 		ActUserName:  actUser.Name, | ||||
| 		OpType:       ActionRenameRepo, | ||||
| 		RepoID:       repo.ID, | ||||
| 		RepoUserName: repo.Owner.Name, | ||||
| 		RepoName:     repo.Name, | ||||
| 		IsPrivate:    repo.IsPrivate, | ||||
| 		Content:      oldRepoName, | ||||
| 		ActUserID: actUser.ID, | ||||
| 		ActUser:   actUser, | ||||
| 		OpType:    ActionRenameRepo, | ||||
| 		RepoID:    repo.ID, | ||||
| 		Repo:      repo, | ||||
| 		IsPrivate: repo.IsPrivate, | ||||
| 		Content:   oldRepoName, | ||||
| 	}); err != nil { | ||||
| 		return fmt.Errorf("notify watchers: %v", err) | ||||
| 	} | ||||
| @ -521,15 +546,14 @@ func CommitRepoAction(opts CommitRepoActionOptions) error { | ||||
| 
 | ||||
| 	refName := git.RefEndName(opts.RefFullName) | ||||
| 	if err = NotifyWatchers(&Action{ | ||||
| 		ActUserID:    pusher.ID, | ||||
| 		ActUserName:  pusher.Name, | ||||
| 		OpType:       opType, | ||||
| 		Content:      string(data), | ||||
| 		RepoID:       repo.ID, | ||||
| 		RepoUserName: repo.MustOwner().Name, | ||||
| 		RepoName:     repo.Name, | ||||
| 		RefName:      refName, | ||||
| 		IsPrivate:    repo.IsPrivate, | ||||
| 		ActUserID: pusher.ID, | ||||
| 		ActUser:   pusher, | ||||
| 		OpType:    opType, | ||||
| 		Content:   string(data), | ||||
| 		RepoID:    repo.ID, | ||||
| 		Repo:      repo, | ||||
| 		RefName:   refName, | ||||
| 		IsPrivate: repo.IsPrivate, | ||||
| 	}); err != nil { | ||||
| 		return fmt.Errorf("NotifyWatchers: %v", err) | ||||
| 	} | ||||
| @ -598,14 +622,13 @@ func CommitRepoAction(opts CommitRepoActionOptions) error { | ||||
| 
 | ||||
| func transferRepoAction(e Engine, doer, oldOwner *User, repo *Repository) (err error) { | ||||
| 	if err = notifyWatchers(e, &Action{ | ||||
| 		ActUserID:    doer.ID, | ||||
| 		ActUserName:  doer.Name, | ||||
| 		OpType:       ActionTransferRepo, | ||||
| 		RepoID:       repo.ID, | ||||
| 		RepoUserName: repo.Owner.Name, | ||||
| 		RepoName:     repo.Name, | ||||
| 		IsPrivate:    repo.IsPrivate, | ||||
| 		Content:      path.Join(oldOwner.Name, repo.Name), | ||||
| 		ActUserID: doer.ID, | ||||
| 		ActUser:   doer, | ||||
| 		OpType:    ActionTransferRepo, | ||||
| 		RepoID:    repo.ID, | ||||
| 		Repo:      repo, | ||||
| 		IsPrivate: repo.IsPrivate, | ||||
| 		Content:   path.Join(oldOwner.Name, repo.Name), | ||||
| 	}); err != nil { | ||||
| 		return fmt.Errorf("notifyWatchers: %v", err) | ||||
| 	} | ||||
| @ -628,14 +651,13 @@ func TransferRepoAction(doer, oldOwner *User, repo *Repository) error { | ||||
| 
 | ||||
| func mergePullRequestAction(e Engine, doer *User, repo *Repository, issue *Issue) error { | ||||
| 	return notifyWatchers(e, &Action{ | ||||
| 		ActUserID:    doer.ID, | ||||
| 		ActUserName:  doer.Name, | ||||
| 		OpType:       ActionMergePullRequest, | ||||
| 		Content:      fmt.Sprintf("%d|%s", issue.Index, issue.Title), | ||||
| 		RepoID:       repo.ID, | ||||
| 		RepoUserName: repo.Owner.Name, | ||||
| 		RepoName:     repo.Name, | ||||
| 		IsPrivate:    repo.IsPrivate, | ||||
| 		ActUserID: doer.ID, | ||||
| 		ActUser:   doer, | ||||
| 		OpType:    ActionMergePullRequest, | ||||
| 		Content:   fmt.Sprintf("%d|%s", issue.Index, issue.Title), | ||||
| 		RepoID:    repo.ID, | ||||
| 		Repo:      repo, | ||||
| 		IsPrivate: repo.IsPrivate, | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -1,6 +1,7 @@ | ||||
| package models | ||||
| 
 | ||||
| import ( | ||||
| 	"path" | ||||
| 	"strings" | ||||
| 	"testing" | ||||
| 
 | ||||
| @ -10,22 +11,21 @@ import ( | ||||
| ) | ||||
| 
 | ||||
| func TestAction_GetRepoPath(t *testing.T) { | ||||
| 	action := &Action{ | ||||
| 		RepoUserName: "username", | ||||
| 		RepoName:     "reponame", | ||||
| 	} | ||||
| 	assert.Equal(t, "username/reponame", action.GetRepoPath()) | ||||
| 	assert.NoError(t, PrepareTestDatabase()) | ||||
| 	repo := AssertExistsAndLoadBean(t, &Repository{}).(*Repository) | ||||
| 	owner := AssertExistsAndLoadBean(t, &User{ID: repo.OwnerID}).(*User) | ||||
| 	action := &Action{RepoID: repo.ID} | ||||
| 	assert.Equal(t, path.Join(owner.Name, repo.Name), action.GetRepoPath()) | ||||
| } | ||||
| 
 | ||||
| func TestAction_GetRepoLink(t *testing.T) { | ||||
| 	action := &Action{ | ||||
| 		RepoUserName: "username", | ||||
| 		RepoName:     "reponame", | ||||
| 	} | ||||
| 	assert.NoError(t, PrepareTestDatabase()) | ||||
| 	repo := AssertExistsAndLoadBean(t, &Repository{}).(*Repository) | ||||
| 	owner := AssertExistsAndLoadBean(t, &User{ID: repo.OwnerID}).(*User) | ||||
| 	action := &Action{RepoID: repo.ID} | ||||
| 	setting.AppSubURL = "/suburl/" | ||||
| 	assert.Equal(t, "/suburl/username/reponame", action.GetRepoLink()) | ||||
| 	setting.AppSubURL = "" | ||||
| 	assert.Equal(t, "/username/reponame", action.GetRepoLink()) | ||||
| 	expected := path.Join(setting.AppSubURL, owner.Name, repo.Name) | ||||
| 	assert.Equal(t, expected, action.GetRepoLink()) | ||||
| } | ||||
| 
 | ||||
| func TestNewRepoAction(t *testing.T) { | ||||
| @ -36,13 +36,12 @@ func TestNewRepoAction(t *testing.T) { | ||||
| 	repo.Owner = user | ||||
| 
 | ||||
| 	actionBean := &Action{ | ||||
| 		OpType:       ActionCreateRepo, | ||||
| 		ActUserID:    user.ID, | ||||
| 		RepoID:       repo.ID, | ||||
| 		ActUserName:  user.Name, | ||||
| 		RepoName:     repo.Name, | ||||
| 		RepoUserName: repo.Owner.Name, | ||||
| 		IsPrivate:    repo.IsPrivate, | ||||
| 		OpType:    ActionCreateRepo, | ||||
| 		ActUserID: user.ID, | ||||
| 		RepoID:    repo.ID, | ||||
| 		ActUser:   user, | ||||
| 		Repo:      repo, | ||||
| 		IsPrivate: repo.IsPrivate, | ||||
| 	} | ||||
| 
 | ||||
| 	AssertNotExistsBean(t, actionBean) | ||||
| @ -64,14 +63,13 @@ func TestRenameRepoAction(t *testing.T) { | ||||
| 	repo.LowerName = strings.ToLower(newRepoName) | ||||
| 
 | ||||
| 	actionBean := &Action{ | ||||
| 		OpType:       ActionRenameRepo, | ||||
| 		ActUserID:    user.ID, | ||||
| 		ActUserName:  user.Name, | ||||
| 		RepoID:       repo.ID, | ||||
| 		RepoName:     repo.Name, | ||||
| 		RepoUserName: repo.Owner.Name, | ||||
| 		IsPrivate:    repo.IsPrivate, | ||||
| 		Content:      oldRepoName, | ||||
| 		OpType:    ActionRenameRepo, | ||||
| 		ActUserID: user.ID, | ||||
| 		ActUser:   user, | ||||
| 		RepoID:    repo.ID, | ||||
| 		Repo:      repo, | ||||
| 		IsPrivate: repo.IsPrivate, | ||||
| 		Content:   oldRepoName, | ||||
| 	} | ||||
| 	AssertNotExistsBean(t, actionBean) | ||||
| 	assert.NoError(t, RenameRepoAction(user, oldRepoName, repo)) | ||||
| @ -232,13 +230,13 @@ func TestCommitRepoAction(t *testing.T) { | ||||
| 	pushCommits.Len = len(pushCommits.Commits) | ||||
| 
 | ||||
| 	actionBean := &Action{ | ||||
| 		OpType:      ActionCommitRepo, | ||||
| 		ActUserID:   user.ID, | ||||
| 		ActUserName: user.Name, | ||||
| 		RepoID:      repo.ID, | ||||
| 		RepoName:    repo.Name, | ||||
| 		RefName:     "refName", | ||||
| 		IsPrivate:   repo.IsPrivate, | ||||
| 		OpType:    ActionCommitRepo, | ||||
| 		ActUserID: user.ID, | ||||
| 		ActUser:   user, | ||||
| 		RepoID:    repo.ID, | ||||
| 		Repo:      repo, | ||||
| 		RefName:   "refName", | ||||
| 		IsPrivate: repo.IsPrivate, | ||||
| 	} | ||||
| 	AssertNotExistsBean(t, actionBean) | ||||
| 	assert.NoError(t, CommitRepoAction(CommitRepoActionOptions{ | ||||
| @ -265,13 +263,12 @@ func TestTransferRepoAction(t *testing.T) { | ||||
| 	repo.Owner = user4 | ||||
| 
 | ||||
| 	actionBean := &Action{ | ||||
| 		OpType:       ActionTransferRepo, | ||||
| 		ActUserID:    user2.ID, | ||||
| 		ActUserName:  user2.Name, | ||||
| 		RepoID:       repo.ID, | ||||
| 		RepoName:     repo.Name, | ||||
| 		RepoUserName: repo.Owner.Name, | ||||
| 		IsPrivate:    repo.IsPrivate, | ||||
| 		OpType:    ActionTransferRepo, | ||||
| 		ActUserID: user2.ID, | ||||
| 		ActUser:   user2, | ||||
| 		RepoID:    repo.ID, | ||||
| 		Repo:      repo, | ||||
| 		IsPrivate: repo.IsPrivate, | ||||
| 	} | ||||
| 	AssertNotExistsBean(t, actionBean) | ||||
| 	assert.NoError(t, TransferRepoAction(user2, user2, repo)) | ||||
| @ -290,13 +287,12 @@ func TestMergePullRequestAction(t *testing.T) { | ||||
| 	issue := AssertExistsAndLoadBean(t, &Issue{ID: 3, RepoID: repo.ID}).(*Issue) | ||||
| 
 | ||||
| 	actionBean := &Action{ | ||||
| 		OpType:       ActionMergePullRequest, | ||||
| 		ActUserID:    user.ID, | ||||
| 		ActUserName:  user.Name, | ||||
| 		RepoID:       repo.ID, | ||||
| 		RepoName:     repo.Name, | ||||
| 		RepoUserName: repo.Owner.Name, | ||||
| 		IsPrivate:    repo.IsPrivate, | ||||
| 		OpType:    ActionMergePullRequest, | ||||
| 		ActUserID: user.ID, | ||||
| 		ActUser:   user, | ||||
| 		RepoID:    repo.ID, | ||||
| 		Repo:      repo, | ||||
| 		IsPrivate: repo.IsPrivate, | ||||
| 	} | ||||
| 	AssertNotExistsBean(t, actionBean) | ||||
| 	assert.NoError(t, MergePullRequestAction(user, repo, issue)) | ||||
|  | ||||
| @ -162,11 +162,5 @@ func (team *Team) checkForConsistency(t *testing.T) { | ||||
| 
 | ||||
| func (action *Action) checkForConsistency(t *testing.T) { | ||||
| 	repo := AssertExistsAndLoadBean(t, &Repository{ID: action.RepoID}).(*Repository) | ||||
| 	owner := AssertExistsAndLoadBean(t, &User{ID: repo.OwnerID}).(*User) | ||||
| 	actor := AssertExistsAndLoadBean(t, &User{ID: action.ActUserID}).(*User) | ||||
| 
 | ||||
| 	assert.Equal(t, repo.Name, action.RepoName, "action: %+v", action) | ||||
| 	assert.Equal(t, repo.IsPrivate, action.IsPrivate, "action: %+v", action) | ||||
| 	assert.Equal(t, owner.Name, action.RepoUserName, "action: %+v", action) | ||||
| 	assert.Equal(t, actor.Name, action.ActUserName, "action: %+v", action) | ||||
| } | ||||
|  | ||||
| @ -3,10 +3,7 @@ | ||||
|   user_id: 2 | ||||
|   op_type: 12 # close issue | ||||
|   act_user_id: 2 | ||||
|   act_user_name: user2 | ||||
|   repo_id: 2 | ||||
|   repo_user_name: user2 | ||||
|   repo_name: repo2 | ||||
|   is_private: true | ||||
| 
 | ||||
| - | ||||
| @ -14,10 +11,7 @@ | ||||
|   user_id: 3 | ||||
|   op_type: 2 # rename repo | ||||
|   act_user_id: 3 | ||||
|   act_user_name: user3 | ||||
|   repo_id: 3 | ||||
|   repo_user_name: user3 | ||||
|   repo_name: repo3 | ||||
|   is_private: true | ||||
|   content: oldRepoName | ||||
| 
 | ||||
| @ -26,8 +20,5 @@ | ||||
|   user_id: 11 | ||||
|   op_type: 1 # create repo | ||||
|   act_user_id: 11 | ||||
|   act_user_name: user11 | ||||
|   repo_id: 9 | ||||
|   repo_user_name: user11 | ||||
|   repo_name: repo9 | ||||
|   is_private: false | ||||
|  | ||||
| @ -918,14 +918,13 @@ func NewIssue(repo *Repository, issue *Issue, labelIDs []int64, uuids []string) | ||||
| 	} | ||||
| 
 | ||||
| 	if err = NotifyWatchers(&Action{ | ||||
| 		ActUserID:    issue.Poster.ID, | ||||
| 		ActUserName:  issue.Poster.Name, | ||||
| 		OpType:       ActionCreateIssue, | ||||
| 		Content:      fmt.Sprintf("%d|%s", issue.Index, issue.Title), | ||||
| 		RepoID:       repo.ID, | ||||
| 		RepoUserName: repo.Owner.Name, | ||||
| 		RepoName:     repo.Name, | ||||
| 		IsPrivate:    repo.IsPrivate, | ||||
| 		ActUserID: issue.Poster.ID, | ||||
| 		ActUser:   issue.Poster, | ||||
| 		OpType:    ActionCreateIssue, | ||||
| 		Content:   fmt.Sprintf("%d|%s", issue.Index, issue.Title), | ||||
| 		RepoID:    repo.ID, | ||||
| 		Repo:      repo, | ||||
| 		IsPrivate: repo.IsPrivate, | ||||
| 	}); err != nil { | ||||
| 		log.Error(4, "NotifyWatchers: %v", err) | ||||
| 	} | ||||
|  | ||||
| @ -329,13 +329,12 @@ func createComment(e *xorm.Session, opts *CreateCommentOptions) (_ *Comment, err | ||||
| 	// Compose comment action, could be plain comment, close or reopen issue/pull request.
 | ||||
| 	// This object will be used to notify watchers in the end of function.
 | ||||
| 	act := &Action{ | ||||
| 		ActUserID:    opts.Doer.ID, | ||||
| 		ActUserName:  opts.Doer.Name, | ||||
| 		Content:      fmt.Sprintf("%d|%s", opts.Issue.Index, strings.Split(opts.Content, "\n")[0]), | ||||
| 		RepoID:       opts.Repo.ID, | ||||
| 		RepoUserName: opts.Repo.Owner.Name, | ||||
| 		RepoName:     opts.Repo.Name, | ||||
| 		IsPrivate:    opts.Repo.IsPrivate, | ||||
| 		ActUserID: opts.Doer.ID, | ||||
| 		ActUser:   opts.Doer, | ||||
| 		Content:   fmt.Sprintf("%d|%s", opts.Issue.Index, strings.Split(opts.Content, "\n")[0]), | ||||
| 		RepoID:    opts.Repo.ID, | ||||
| 		Repo:      opts.Repo, | ||||
| 		IsPrivate: opts.Repo.IsPrivate, | ||||
| 	} | ||||
| 
 | ||||
| 	// Check comment type.
 | ||||
|  | ||||
| @ -114,6 +114,8 @@ var migrations = []Migration{ | ||||
| 	NewMigration("add field for login source synchronization", addLoginSourceSyncEnabledColumn), | ||||
| 	// v32 -> v33
 | ||||
| 	NewMigration("add units for team", addUnitsToRepoTeam), | ||||
| 	// v33 -> v34
 | ||||
| 	NewMigration("remove columns from action", removeActionColumns), | ||||
| } | ||||
| 
 | ||||
| // Migrate database to current version
 | ||||
|  | ||||
							
								
								
									
										44
									
								
								models/migrations/v34.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								models/migrations/v34.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,44 @@ | ||||
| // Copyright 2017 Gitea. All rights reserved.
 | ||||
| // Use of this source code is governed by a MIT-style
 | ||||
| // license that can be found in the LICENSE file.
 | ||||
| 
 | ||||
| package migrations | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 
 | ||||
| 	"code.gitea.io/gitea/modules/log" | ||||
| 	"code.gitea.io/gitea/modules/setting" | ||||
| 
 | ||||
| 	"github.com/go-xorm/xorm" | ||||
| ) | ||||
| 
 | ||||
| // ActionV34 describes the removed fields
 | ||||
| type ActionV34 struct { | ||||
| 	ActUserName  string `xorm:"-"` | ||||
| 	RepoUserName string `xorm:"-"` | ||||
| 	RepoName     string `xorm:"-"` | ||||
| } | ||||
| 
 | ||||
| // TableName will be invoked by XORM to customize the table name
 | ||||
| func (*ActionV34) TableName() string { | ||||
| 	return "action" | ||||
| } | ||||
| 
 | ||||
| func removeActionColumns(x *xorm.Engine) error { | ||||
| 	switch { | ||||
| 	case setting.UseSQLite3: | ||||
| 		log.Warn("Unable to drop columns in SQLite") | ||||
| 	case setting.UseMySQL, setting.UsePostgreSQL, setting.UseMSSQL, setting.UseTiDB: | ||||
| 		if _, err := x.Exec("ALTER TABLE action DROP COLUMN act_user_name"); err != nil { | ||||
| 			return fmt.Errorf("DROP COLUMN act_user_name: %v", err) | ||||
| 		} else if _, err = x.Exec("ALTER TABLE action DROP COLUMN repo_user_name"); err != nil { | ||||
| 			return fmt.Errorf("DROP COLUMN repo_user_name: %v", err) | ||||
| 		} else if _, err = x.Exec("ALTER TABLE action DROP COLUMN repo_name"); err != nil { | ||||
| 			return fmt.Errorf("DROP COLUMN repo_name: %v", err) | ||||
| 		} | ||||
| 	default: | ||||
| 		log.Fatal(4, "Unrecognized DB") | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
| @ -635,14 +635,13 @@ func NewPullRequest(repo *Repository, pull *Issue, labelIDs []int64, uuids []str | ||||
| 	} | ||||
| 
 | ||||
| 	if err = NotifyWatchers(&Action{ | ||||
| 		ActUserID:    pull.Poster.ID, | ||||
| 		ActUserName:  pull.Poster.Name, | ||||
| 		OpType:       ActionCreatePullRequest, | ||||
| 		Content:      fmt.Sprintf("%d|%s", pull.Index, pull.Title), | ||||
| 		RepoID:       repo.ID, | ||||
| 		RepoUserName: repo.Owner.Name, | ||||
| 		RepoName:     repo.Name, | ||||
| 		IsPrivate:    repo.IsPrivate, | ||||
| 		ActUserID: pull.Poster.ID, | ||||
| 		ActUser:   pull.Poster, | ||||
| 		OpType:    ActionCreatePullRequest, | ||||
| 		Content:   fmt.Sprintf("%d|%s", pull.Index, pull.Title), | ||||
| 		RepoID:    repo.ID, | ||||
| 		Repo:      repo, | ||||
| 		IsPrivate: repo.IsPrivate, | ||||
| 	}); err != nil { | ||||
| 		log.Error(4, "NotifyWatchers: %v", err) | ||||
| 	} else if err = pull.MailParticipants(); err != nil { | ||||
|  | ||||
| @ -65,25 +65,50 @@ func retrieveFeeds(ctx *context.Context, ctxUser *models.User, userID, offset in | ||||
| 
 | ||||
| 	// Check access of private repositories.
 | ||||
| 	feeds := make([]*models.Action, 0, len(actions)) | ||||
| 	unameAvatars := map[string]string{ | ||||
| 		ctxUser.Name: ctxUser.RelAvatarLink(), | ||||
| 	} | ||||
| 	userCache := map[int64]*models.User{ctxUser.ID: ctxUser} | ||||
| 	repoCache := map[int64]*models.Repository{} | ||||
| 	for _, act := range actions { | ||||
| 		// Cache results to reduce queries.
 | ||||
| 		_, ok := unameAvatars[act.ActUserName] | ||||
| 		u, ok := userCache[act.ActUserID] | ||||
| 		if !ok { | ||||
| 			u, err := models.GetUserByName(act.ActUserName) | ||||
| 			u, err = models.GetUserByID(act.ActUserID) | ||||
| 			if err != nil { | ||||
| 				if models.IsErrUserNotExist(err) { | ||||
| 					continue | ||||
| 				} | ||||
| 				ctx.Handle(500, "GetUserByName", err) | ||||
| 				ctx.Handle(500, "GetUserByID", err) | ||||
| 				return | ||||
| 			} | ||||
| 			unameAvatars[act.ActUserName] = u.RelAvatarLink() | ||||
| 			userCache[act.ActUserID] = u | ||||
| 		} | ||||
| 		act.ActUser = u | ||||
| 
 | ||||
| 		repo, ok := repoCache[act.RepoID] | ||||
| 		if !ok { | ||||
| 			repo, err = models.GetRepositoryByID(act.RepoID) | ||||
| 			if err != nil { | ||||
| 				if models.IsErrRepoNotExist(err) { | ||||
| 					continue | ||||
| 				} | ||||
| 				ctx.Handle(500, "GetRepositoryByID", err) | ||||
| 				return | ||||
| 			} | ||||
| 		} | ||||
| 		act.Repo = repo | ||||
| 
 | ||||
| 		repoOwner, ok := userCache[repo.OwnerID] | ||||
| 		if !ok { | ||||
| 			repoOwner, err = models.GetUserByID(repo.OwnerID) | ||||
| 			if err != nil { | ||||
| 				if models.IsErrUserNotExist(err) { | ||||
| 					continue | ||||
| 				} | ||||
| 				ctx.Handle(500, "GetUserByID", err) | ||||
| 				return | ||||
| 			} | ||||
| 		} | ||||
| 		repo.Owner = repoOwner | ||||
| 
 | ||||
| 		act.ActAvatar = unameAvatars[act.ActUserName] | ||||
| 		feeds = append(feeds, act) | ||||
| 	} | ||||
| 	ctx.Data["Feeds"] = feeds | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user