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
11 changed files with 238 additions and 165 deletions
|
@ -6,7 +6,7 @@ DB_TYPE = mysql
|
||||||
HOST = 127.0.0.1:3306
|
HOST = 127.0.0.1:3306
|
||||||
NAME = testgitea
|
NAME = testgitea
|
||||||
USER = root
|
USER = root
|
||||||
PASSWD =
|
PASSWD =
|
||||||
SSL_MODE = disable
|
SSL_MODE = disable
|
||||||
PATH = data/gitea.db
|
PATH = data/gitea.db
|
||||||
|
|
||||||
|
@ -26,14 +26,14 @@ OFFLINE_MODE = false
|
||||||
ENABLED = false
|
ENABLED = false
|
||||||
|
|
||||||
[service]
|
[service]
|
||||||
REGISTER_EMAIL_CONFIRM = false
|
REGISTER_EMAIL_CONFIRM = false
|
||||||
ENABLE_NOTIFY_MAIL = false
|
ENABLE_NOTIFY_MAIL = false
|
||||||
DISABLE_REGISTRATION = false
|
DISABLE_REGISTRATION = false
|
||||||
ENABLE_CAPTCHA = false
|
ENABLE_CAPTCHA = false
|
||||||
REQUIRE_SIGNIN_VIEW = false
|
REQUIRE_SIGNIN_VIEW = false
|
||||||
DEFAULT_KEEP_EMAIL_PRIVATE = false
|
DEFAULT_KEEP_EMAIL_PRIVATE = false
|
||||||
DEFAULT_ALLOW_CREATE_ORGANIZATION = true
|
DEFAULT_ALLOW_CREATE_ORGANIZATION = true
|
||||||
NO_REPLY_ADDRESS = noreply.example.org
|
NO_REPLY_ADDRESS = noreply.example.org
|
||||||
|
|
||||||
[picture]
|
[picture]
|
||||||
DISABLE_GRAVATAR = false
|
DISABLE_GRAVATAR = false
|
||||||
|
@ -53,5 +53,7 @@ LEVEL = Warn
|
||||||
LEVEL = Info
|
LEVEL = Info
|
||||||
|
|
||||||
[security]
|
[security]
|
||||||
INSTALL_LOCK = true
|
INSTALL_LOCK = true
|
||||||
SECRET_KEY = 9pCviYTWSb
|
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
|
// repository. It implemented interface base.Actioner so that can be
|
||||||
// used in template render.
|
// used in template render.
|
||||||
type Action struct {
|
type Action struct {
|
||||||
ID int64 `xorm:"pk autoincr"`
|
ID int64 `xorm:"pk autoincr"`
|
||||||
UserID int64 `xorm:"INDEX"` // Receiver user id.
|
UserID int64 `xorm:"INDEX"` // Receiver user id.
|
||||||
OpType ActionType
|
OpType ActionType
|
||||||
ActUserID int64 `xorm:"INDEX"` // Action user id.
|
ActUserID int64 `xorm:"INDEX"` // Action user id.
|
||||||
ActUserName string // Action user name.
|
ActUser *User `xorm:"-"`
|
||||||
ActAvatar string `xorm:"-"`
|
RepoID int64 `xorm:"INDEX"`
|
||||||
RepoID int64 `xorm:"INDEX"`
|
Repo *Repository `xorm:"-"`
|
||||||
RepoUserName string
|
RefName string
|
||||||
RepoName string
|
IsPrivate bool `xorm:"INDEX NOT NULL DEFAULT false"`
|
||||||
RefName string
|
Content string `xorm:"TEXT"`
|
||||||
IsPrivate bool `xorm:"INDEX NOT NULL DEFAULT false"`
|
Created time.Time `xorm:"-"`
|
||||||
Content string `xorm:"TEXT"`
|
CreatedUnix int64 `xorm:"INDEX"`
|
||||||
Created time.Time `xorm:"-"`
|
|
||||||
CreatedUnix int64 `xorm:"INDEX"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// BeforeInsert will be invoked by XORM before inserting a record
|
// BeforeInsert will be invoked by XORM before inserting a record
|
||||||
|
@ -106,42 +104,71 @@ func (a *Action) GetOpType() int {
|
||||||
return int(a.OpType)
|
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.
|
// GetActUserName gets the action's user name.
|
||||||
func (a *Action) GetActUserName() string {
|
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
|
// ShortActUserName gets the action's user name trimmed to max 20
|
||||||
// chars.
|
// chars.
|
||||||
func (a *Action) ShortActUserName() string {
|
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.
|
// GetRepoUserName returns the name of the action repository owner.
|
||||||
func (a *Action) GetRepoUserName() string {
|
func (a *Action) GetRepoUserName() string {
|
||||||
return a.RepoUserName
|
a.loadRepo()
|
||||||
|
return a.Repo.MustOwner().Name
|
||||||
}
|
}
|
||||||
|
|
||||||
// ShortRepoUserName returns the name of the action repository owner
|
// ShortRepoUserName returns the name of the action repository owner
|
||||||
// trimmed to max 20 chars.
|
// trimmed to max 20 chars.
|
||||||
func (a *Action) ShortRepoUserName() string {
|
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.
|
// GetRepoName returns the name of the action repository.
|
||||||
func (a *Action) GetRepoName() string {
|
func (a *Action) GetRepoName() string {
|
||||||
return a.RepoName
|
a.loadRepo()
|
||||||
|
return a.Repo.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
// ShortRepoName returns the name of the action repository
|
// ShortRepoName returns the name of the action repository
|
||||||
// trimmed to max 33 chars.
|
// trimmed to max 33 chars.
|
||||||
func (a *Action) ShortRepoName() string {
|
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.
|
// GetRepoPath returns the virtual path to the action repository.
|
||||||
func (a *Action) GetRepoPath() string {
|
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
|
// 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) {
|
func newRepoAction(e Engine, u *User, repo *Repository) (err error) {
|
||||||
if err = notifyWatchers(e, &Action{
|
if err = notifyWatchers(e, &Action{
|
||||||
ActUserID: u.ID,
|
ActUserID: u.ID,
|
||||||
ActUserName: u.Name,
|
ActUser: u,
|
||||||
OpType: ActionCreateRepo,
|
OpType: ActionCreateRepo,
|
||||||
RepoID: repo.ID,
|
RepoID: repo.ID,
|
||||||
RepoUserName: repo.Owner.Name,
|
Repo: repo,
|
||||||
RepoName: repo.Name,
|
IsPrivate: repo.IsPrivate,
|
||||||
IsPrivate: repo.IsPrivate,
|
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return fmt.Errorf("notify watchers '%d/%d': %v", u.ID, repo.ID, err)
|
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) {
|
func renameRepoAction(e Engine, actUser *User, oldRepoName string, repo *Repository) (err error) {
|
||||||
if err = notifyWatchers(e, &Action{
|
if err = notifyWatchers(e, &Action{
|
||||||
ActUserID: actUser.ID,
|
ActUserID: actUser.ID,
|
||||||
ActUserName: actUser.Name,
|
ActUser: actUser,
|
||||||
OpType: ActionRenameRepo,
|
OpType: ActionRenameRepo,
|
||||||
RepoID: repo.ID,
|
RepoID: repo.ID,
|
||||||
RepoUserName: repo.Owner.Name,
|
Repo: repo,
|
||||||
RepoName: repo.Name,
|
IsPrivate: repo.IsPrivate,
|
||||||
IsPrivate: repo.IsPrivate,
|
Content: oldRepoName,
|
||||||
Content: oldRepoName,
|
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return fmt.Errorf("notify watchers: %v", err)
|
return fmt.Errorf("notify watchers: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -521,15 +546,14 @@ func CommitRepoAction(opts CommitRepoActionOptions) error {
|
||||||
|
|
||||||
refName := git.RefEndName(opts.RefFullName)
|
refName := git.RefEndName(opts.RefFullName)
|
||||||
if err = NotifyWatchers(&Action{
|
if err = NotifyWatchers(&Action{
|
||||||
ActUserID: pusher.ID,
|
ActUserID: pusher.ID,
|
||||||
ActUserName: pusher.Name,
|
ActUser: pusher,
|
||||||
OpType: opType,
|
OpType: opType,
|
||||||
Content: string(data),
|
Content: string(data),
|
||||||
RepoID: repo.ID,
|
RepoID: repo.ID,
|
||||||
RepoUserName: repo.MustOwner().Name,
|
Repo: repo,
|
||||||
RepoName: repo.Name,
|
RefName: refName,
|
||||||
RefName: refName,
|
IsPrivate: repo.IsPrivate,
|
||||||
IsPrivate: repo.IsPrivate,
|
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return fmt.Errorf("NotifyWatchers: %v", err)
|
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) {
|
func transferRepoAction(e Engine, doer, oldOwner *User, repo *Repository) (err error) {
|
||||||
if err = notifyWatchers(e, &Action{
|
if err = notifyWatchers(e, &Action{
|
||||||
ActUserID: doer.ID,
|
ActUserID: doer.ID,
|
||||||
ActUserName: doer.Name,
|
ActUser: doer,
|
||||||
OpType: ActionTransferRepo,
|
OpType: ActionTransferRepo,
|
||||||
RepoID: repo.ID,
|
RepoID: repo.ID,
|
||||||
RepoUserName: repo.Owner.Name,
|
Repo: repo,
|
||||||
RepoName: repo.Name,
|
IsPrivate: repo.IsPrivate,
|
||||||
IsPrivate: repo.IsPrivate,
|
Content: path.Join(oldOwner.Name, repo.Name),
|
||||||
Content: path.Join(oldOwner.Name, repo.Name),
|
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return fmt.Errorf("notifyWatchers: %v", err)
|
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 {
|
func mergePullRequestAction(e Engine, doer *User, repo *Repository, issue *Issue) error {
|
||||||
return notifyWatchers(e, &Action{
|
return notifyWatchers(e, &Action{
|
||||||
ActUserID: doer.ID,
|
ActUserID: doer.ID,
|
||||||
ActUserName: doer.Name,
|
ActUser: doer,
|
||||||
OpType: ActionMergePullRequest,
|
OpType: ActionMergePullRequest,
|
||||||
Content: fmt.Sprintf("%d|%s", issue.Index, issue.Title),
|
Content: fmt.Sprintf("%d|%s", issue.Index, issue.Title),
|
||||||
RepoID: repo.ID,
|
RepoID: repo.ID,
|
||||||
RepoUserName: repo.Owner.Name,
|
Repo: repo,
|
||||||
RepoName: repo.Name,
|
IsPrivate: repo.IsPrivate,
|
||||||
IsPrivate: repo.IsPrivate,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
@ -10,22 +11,21 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestAction_GetRepoPath(t *testing.T) {
|
func TestAction_GetRepoPath(t *testing.T) {
|
||||||
action := &Action{
|
assert.NoError(t, PrepareTestDatabase())
|
||||||
RepoUserName: "username",
|
repo := AssertExistsAndLoadBean(t, &Repository{}).(*Repository)
|
||||||
RepoName: "reponame",
|
owner := AssertExistsAndLoadBean(t, &User{ID: repo.OwnerID}).(*User)
|
||||||
}
|
action := &Action{RepoID: repo.ID}
|
||||||
assert.Equal(t, "username/reponame", action.GetRepoPath())
|
assert.Equal(t, path.Join(owner.Name, repo.Name), action.GetRepoPath())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAction_GetRepoLink(t *testing.T) {
|
func TestAction_GetRepoLink(t *testing.T) {
|
||||||
action := &Action{
|
assert.NoError(t, PrepareTestDatabase())
|
||||||
RepoUserName: "username",
|
repo := AssertExistsAndLoadBean(t, &Repository{}).(*Repository)
|
||||||
RepoName: "reponame",
|
owner := AssertExistsAndLoadBean(t, &User{ID: repo.OwnerID}).(*User)
|
||||||
}
|
action := &Action{RepoID: repo.ID}
|
||||||
setting.AppSubURL = "/suburl/"
|
setting.AppSubURL = "/suburl/"
|
||||||
assert.Equal(t, "/suburl/username/reponame", action.GetRepoLink())
|
expected := path.Join(setting.AppSubURL, owner.Name, repo.Name)
|
||||||
setting.AppSubURL = ""
|
assert.Equal(t, expected, action.GetRepoLink())
|
||||||
assert.Equal(t, "/username/reponame", action.GetRepoLink())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNewRepoAction(t *testing.T) {
|
func TestNewRepoAction(t *testing.T) {
|
||||||
|
@ -36,13 +36,12 @@ func TestNewRepoAction(t *testing.T) {
|
||||||
repo.Owner = user
|
repo.Owner = user
|
||||||
|
|
||||||
actionBean := &Action{
|
actionBean := &Action{
|
||||||
OpType: ActionCreateRepo,
|
OpType: ActionCreateRepo,
|
||||||
ActUserID: user.ID,
|
ActUserID: user.ID,
|
||||||
RepoID: repo.ID,
|
RepoID: repo.ID,
|
||||||
ActUserName: user.Name,
|
ActUser: user,
|
||||||
RepoName: repo.Name,
|
Repo: repo,
|
||||||
RepoUserName: repo.Owner.Name,
|
IsPrivate: repo.IsPrivate,
|
||||||
IsPrivate: repo.IsPrivate,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AssertNotExistsBean(t, actionBean)
|
AssertNotExistsBean(t, actionBean)
|
||||||
|
@ -64,14 +63,13 @@ func TestRenameRepoAction(t *testing.T) {
|
||||||
repo.LowerName = strings.ToLower(newRepoName)
|
repo.LowerName = strings.ToLower(newRepoName)
|
||||||
|
|
||||||
actionBean := &Action{
|
actionBean := &Action{
|
||||||
OpType: ActionRenameRepo,
|
OpType: ActionRenameRepo,
|
||||||
ActUserID: user.ID,
|
ActUserID: user.ID,
|
||||||
ActUserName: user.Name,
|
ActUser: user,
|
||||||
RepoID: repo.ID,
|
RepoID: repo.ID,
|
||||||
RepoName: repo.Name,
|
Repo: repo,
|
||||||
RepoUserName: repo.Owner.Name,
|
IsPrivate: repo.IsPrivate,
|
||||||
IsPrivate: repo.IsPrivate,
|
Content: oldRepoName,
|
||||||
Content: oldRepoName,
|
|
||||||
}
|
}
|
||||||
AssertNotExistsBean(t, actionBean)
|
AssertNotExistsBean(t, actionBean)
|
||||||
assert.NoError(t, RenameRepoAction(user, oldRepoName, repo))
|
assert.NoError(t, RenameRepoAction(user, oldRepoName, repo))
|
||||||
|
@ -232,13 +230,13 @@ func TestCommitRepoAction(t *testing.T) {
|
||||||
pushCommits.Len = len(pushCommits.Commits)
|
pushCommits.Len = len(pushCommits.Commits)
|
||||||
|
|
||||||
actionBean := &Action{
|
actionBean := &Action{
|
||||||
OpType: ActionCommitRepo,
|
OpType: ActionCommitRepo,
|
||||||
ActUserID: user.ID,
|
ActUserID: user.ID,
|
||||||
ActUserName: user.Name,
|
ActUser: user,
|
||||||
RepoID: repo.ID,
|
RepoID: repo.ID,
|
||||||
RepoName: repo.Name,
|
Repo: repo,
|
||||||
RefName: "refName",
|
RefName: "refName",
|
||||||
IsPrivate: repo.IsPrivate,
|
IsPrivate: repo.IsPrivate,
|
||||||
}
|
}
|
||||||
AssertNotExistsBean(t, actionBean)
|
AssertNotExistsBean(t, actionBean)
|
||||||
assert.NoError(t, CommitRepoAction(CommitRepoActionOptions{
|
assert.NoError(t, CommitRepoAction(CommitRepoActionOptions{
|
||||||
|
@ -265,13 +263,12 @@ func TestTransferRepoAction(t *testing.T) {
|
||||||
repo.Owner = user4
|
repo.Owner = user4
|
||||||
|
|
||||||
actionBean := &Action{
|
actionBean := &Action{
|
||||||
OpType: ActionTransferRepo,
|
OpType: ActionTransferRepo,
|
||||||
ActUserID: user2.ID,
|
ActUserID: user2.ID,
|
||||||
ActUserName: user2.Name,
|
ActUser: user2,
|
||||||
RepoID: repo.ID,
|
RepoID: repo.ID,
|
||||||
RepoName: repo.Name,
|
Repo: repo,
|
||||||
RepoUserName: repo.Owner.Name,
|
IsPrivate: repo.IsPrivate,
|
||||||
IsPrivate: repo.IsPrivate,
|
|
||||||
}
|
}
|
||||||
AssertNotExistsBean(t, actionBean)
|
AssertNotExistsBean(t, actionBean)
|
||||||
assert.NoError(t, TransferRepoAction(user2, user2, repo))
|
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)
|
issue := AssertExistsAndLoadBean(t, &Issue{ID: 3, RepoID: repo.ID}).(*Issue)
|
||||||
|
|
||||||
actionBean := &Action{
|
actionBean := &Action{
|
||||||
OpType: ActionMergePullRequest,
|
OpType: ActionMergePullRequest,
|
||||||
ActUserID: user.ID,
|
ActUserID: user.ID,
|
||||||
ActUserName: user.Name,
|
ActUser: user,
|
||||||
RepoID: repo.ID,
|
RepoID: repo.ID,
|
||||||
RepoName: repo.Name,
|
Repo: repo,
|
||||||
RepoUserName: repo.Owner.Name,
|
IsPrivate: repo.IsPrivate,
|
||||||
IsPrivate: repo.IsPrivate,
|
|
||||||
}
|
}
|
||||||
AssertNotExistsBean(t, actionBean)
|
AssertNotExistsBean(t, actionBean)
|
||||||
assert.NoError(t, MergePullRequestAction(user, repo, issue))
|
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) {
|
func (action *Action) checkForConsistency(t *testing.T) {
|
||||||
repo := AssertExistsAndLoadBean(t, &Repository{ID: action.RepoID}).(*Repository)
|
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, 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
|
user_id: 2
|
||||||
op_type: 12 # close issue
|
op_type: 12 # close issue
|
||||||
act_user_id: 2
|
act_user_id: 2
|
||||||
act_user_name: user2
|
|
||||||
repo_id: 2
|
repo_id: 2
|
||||||
repo_user_name: user2
|
|
||||||
repo_name: repo2
|
|
||||||
is_private: true
|
is_private: true
|
||||||
|
|
||||||
-
|
-
|
||||||
|
@ -14,10 +11,7 @@
|
||||||
user_id: 3
|
user_id: 3
|
||||||
op_type: 2 # rename repo
|
op_type: 2 # rename repo
|
||||||
act_user_id: 3
|
act_user_id: 3
|
||||||
act_user_name: user3
|
|
||||||
repo_id: 3
|
repo_id: 3
|
||||||
repo_user_name: user3
|
|
||||||
repo_name: repo3
|
|
||||||
is_private: true
|
is_private: true
|
||||||
content: oldRepoName
|
content: oldRepoName
|
||||||
|
|
||||||
|
@ -26,8 +20,5 @@
|
||||||
user_id: 11
|
user_id: 11
|
||||||
op_type: 1 # create repo
|
op_type: 1 # create repo
|
||||||
act_user_id: 11
|
act_user_id: 11
|
||||||
act_user_name: user11
|
|
||||||
repo_id: 9
|
repo_id: 9
|
||||||
repo_user_name: user11
|
|
||||||
repo_name: repo9
|
|
||||||
is_private: false
|
is_private: false
|
||||||
|
|
|
@ -918,14 +918,13 @@ func NewIssue(repo *Repository, issue *Issue, labelIDs []int64, uuids []string)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = NotifyWatchers(&Action{
|
if err = NotifyWatchers(&Action{
|
||||||
ActUserID: issue.Poster.ID,
|
ActUserID: issue.Poster.ID,
|
||||||
ActUserName: issue.Poster.Name,
|
ActUser: issue.Poster,
|
||||||
OpType: ActionCreateIssue,
|
OpType: ActionCreateIssue,
|
||||||
Content: fmt.Sprintf("%d|%s", issue.Index, issue.Title),
|
Content: fmt.Sprintf("%d|%s", issue.Index, issue.Title),
|
||||||
RepoID: repo.ID,
|
RepoID: repo.ID,
|
||||||
RepoUserName: repo.Owner.Name,
|
Repo: repo,
|
||||||
RepoName: repo.Name,
|
IsPrivate: repo.IsPrivate,
|
||||||
IsPrivate: repo.IsPrivate,
|
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
log.Error(4, "NotifyWatchers: %v", err)
|
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.
|
// 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.
|
// This object will be used to notify watchers in the end of function.
|
||||||
act := &Action{
|
act := &Action{
|
||||||
ActUserID: opts.Doer.ID,
|
ActUserID: opts.Doer.ID,
|
||||||
ActUserName: opts.Doer.Name,
|
ActUser: opts.Doer,
|
||||||
Content: fmt.Sprintf("%d|%s", opts.Issue.Index, strings.Split(opts.Content, "\n")[0]),
|
Content: fmt.Sprintf("%d|%s", opts.Issue.Index, strings.Split(opts.Content, "\n")[0]),
|
||||||
RepoID: opts.Repo.ID,
|
RepoID: opts.Repo.ID,
|
||||||
RepoUserName: opts.Repo.Owner.Name,
|
Repo: opts.Repo,
|
||||||
RepoName: opts.Repo.Name,
|
IsPrivate: opts.Repo.IsPrivate,
|
||||||
IsPrivate: opts.Repo.IsPrivate,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check comment type.
|
// Check comment type.
|
||||||
|
|
|
@ -114,6 +114,8 @@ var migrations = []Migration{
|
||||||
NewMigration("add field for login source synchronization", addLoginSourceSyncEnabledColumn),
|
NewMigration("add field for login source synchronization", addLoginSourceSyncEnabledColumn),
|
||||||
// v32 -> v33
|
// v32 -> v33
|
||||||
NewMigration("add units for team", addUnitsToRepoTeam),
|
NewMigration("add units for team", addUnitsToRepoTeam),
|
||||||
|
// v33 -> v34
|
||||||
|
NewMigration("remove columns from action", removeActionColumns),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Migrate database to current version
|
// 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{
|
if err = NotifyWatchers(&Action{
|
||||||
ActUserID: pull.Poster.ID,
|
ActUserID: pull.Poster.ID,
|
||||||
ActUserName: pull.Poster.Name,
|
ActUser: pull.Poster,
|
||||||
OpType: ActionCreatePullRequest,
|
OpType: ActionCreatePullRequest,
|
||||||
Content: fmt.Sprintf("%d|%s", pull.Index, pull.Title),
|
Content: fmt.Sprintf("%d|%s", pull.Index, pull.Title),
|
||||||
RepoID: repo.ID,
|
RepoID: repo.ID,
|
||||||
RepoUserName: repo.Owner.Name,
|
Repo: repo,
|
||||||
RepoName: repo.Name,
|
IsPrivate: repo.IsPrivate,
|
||||||
IsPrivate: repo.IsPrivate,
|
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
log.Error(4, "NotifyWatchers: %v", err)
|
log.Error(4, "NotifyWatchers: %v", err)
|
||||||
} else if err = pull.MailParticipants(); err != nil {
|
} 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.
|
// Check access of private repositories.
|
||||||
feeds := make([]*models.Action, 0, len(actions))
|
feeds := make([]*models.Action, 0, len(actions))
|
||||||
unameAvatars := map[string]string{
|
userCache := map[int64]*models.User{ctxUser.ID: ctxUser}
|
||||||
ctxUser.Name: ctxUser.RelAvatarLink(),
|
repoCache := map[int64]*models.Repository{}
|
||||||
}
|
|
||||||
for _, act := range actions {
|
for _, act := range actions {
|
||||||
// Cache results to reduce queries.
|
// Cache results to reduce queries.
|
||||||
_, ok := unameAvatars[act.ActUserName]
|
u, ok := userCache[act.ActUserID]
|
||||||
if !ok {
|
if !ok {
|
||||||
u, err := models.GetUserByName(act.ActUserName)
|
u, err = models.GetUserByID(act.ActUserID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if models.IsErrUserNotExist(err) {
|
if models.IsErrUserNotExist(err) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
ctx.Handle(500, "GetUserByName", err)
|
ctx.Handle(500, "GetUserByID", err)
|
||||||
return
|
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)
|
feeds = append(feeds, act)
|
||||||
}
|
}
|
||||||
ctx.Data["Feeds"] = feeds
|
ctx.Data["Feeds"] = feeds
|
||||||
|
|
Reference in a new issue