Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move all mail related codes from models to services/mailer #7200

Merged
merged 18 commits into from
Sep 24, 2019
57 changes: 57 additions & 0 deletions models/context.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package models

// DBContext represents a db context
type DBContext struct {
e Engine
}

var defaultDBContext = DBContext{x}

// DefaultDBContext represents a DBContext with default Engine
func DefaultDBContext() DBContext {
return defaultDBContext
}

// Committer represents an interface to Commit or Close the dbcontext
type Committer interface {
Commit() error
Close()
}

// TxDBContext represents a transaction DBContext
func TxDBContext() (DBContext, Committer, error) {
sess := x.NewSession()
if err := sess.Begin(); err != nil {
sess.Close()
return DBContext{}, nil, err
}

return DBContext{sess}, sess, nil
}

// WithContext represents executing database operations
func WithContext(f func(ctx DBContext) error) error {
return f(DBContext{x})
}

// WithTx represents executing database operations on a trasaction
func WithTx(f func(ctx DBContext) error) error {
sess := x.NewSession()
if err := sess.Begin(); err != nil {
sess.Close()
return err
}

if err := f(DBContext{sess}); err != nil {
sess.Close()
return err
}

err := sess.Commit()
sess.Close()
return err
}
15 changes: 15 additions & 0 deletions models/error.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,21 @@ import (
"code.gitea.io/gitea/modules/git"
)

// ErrNotExist represents a non-exist error.
type ErrNotExist struct {
ID int64
}

// IsErrNotExist checks if an error is an ErrNotExist
func IsErrNotExist(err error) bool {
_, ok := err.(ErrNotExist)
return ok
}

func (err ErrNotExist) Error() string {
return fmt.Sprintf("record is not exist [id: %d]", err.ID)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return fmt.Sprintf("record is not exist [id: %d]", err.ID)
return fmt.Sprintf("record does not exist [id: %d]", err.ID)

}

// ErrNameReserved represents a "reserved name" error.
type ErrNameReserved struct {
Name string
Expand Down
8 changes: 4 additions & 4 deletions models/issue.go
Original file line number Diff line number Diff line change
Expand Up @@ -1503,7 +1503,7 @@ func getParticipantsByIssueID(e Engine, issueID int64) ([]*User, error) {

// UpdateIssueMentions extracts mentioned people from content and
// updates issue-user relations for them.
func UpdateIssueMentions(e Engine, issueID int64, mentions []string) error {
func UpdateIssueMentions(ctx DBContext, issueID int64, mentions []string) error {
if len(mentions) == 0 {
return nil
}
Expand All @@ -1513,7 +1513,7 @@ func UpdateIssueMentions(e Engine, issueID int64, mentions []string) error {
}
users := make([]*User, 0, len(mentions))

if err := e.In("lower_name", mentions).Asc("lower_name").Find(&users); err != nil {
if err := ctx.e.In("lower_name", mentions).Asc("lower_name").Find(&users); err != nil {
return fmt.Errorf("find mentioned users: %v", err)
}

Expand All @@ -1525,7 +1525,7 @@ func UpdateIssueMentions(e Engine, issueID int64, mentions []string) error {
}

memberIDs := make([]int64, 0, user.NumMembers)
orgUsers, err := getOrgUsersByOrgID(e, user.ID)
orgUsers, err := getOrgUsersByOrgID(ctx.e, user.ID)
if err != nil {
return fmt.Errorf("GetOrgUsersByOrgID [%d]: %v", user.ID, err)
}
Expand All @@ -1537,7 +1537,7 @@ func UpdateIssueMentions(e Engine, issueID int64, mentions []string) error {
ids = append(ids, memberIDs...)
}

if err := UpdateIssueUsersByMentions(e, issueID, ids); err != nil {
if err := UpdateIssueUsersByMentions(ctx, issueID, ids); err != nil {
return fmt.Errorf("UpdateIssueUsersByMentions: %v", err)
}

Expand Down
35 changes: 0 additions & 35 deletions models/issue_comment.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import (

"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/markup"
"code.gitea.io/gitea/modules/markup/markdown"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/timeutil"
Expand Down Expand Up @@ -395,40 +394,6 @@ func (c *Comment) LoadDepIssueDetails() (err error) {
return err
}

// MailParticipants sends new comment emails to repository watchers
// and mentioned people.
func (c *Comment) MailParticipants(opType ActionType, issue *Issue) (err error) {
return c.mailParticipants(x, opType, issue)
}

func (c *Comment) mailParticipants(e Engine, opType ActionType, issue *Issue) (err error) {
mentions := markup.FindAllMentions(c.Content)
if err = UpdateIssueMentions(e, c.IssueID, mentions); err != nil {
return fmt.Errorf("UpdateIssueMentions [%d]: %v", c.IssueID, err)
}

if len(c.Content) > 0 {
if err = mailIssueCommentToParticipants(e, issue, c.Poster, c.Content, c, mentions); err != nil {
log.Error("mailIssueCommentToParticipants: %v", err)
}
}

switch opType {
case ActionCloseIssue:
ct := fmt.Sprintf("Closed #%d.", issue.Index)
if err = mailIssueCommentToParticipants(e, issue, c.Poster, ct, c, mentions); err != nil {
log.Error("mailIssueCommentToParticipants: %v", err)
}
case ActionReopenIssue:
ct := fmt.Sprintf("Reopened #%d.", issue.Index)
if err = mailIssueCommentToParticipants(e, issue, c.Poster, ct, c, mentions); err != nil {
log.Error("mailIssueCommentToParticipants: %v", err)
}
}

return nil
}

func (c *Comment) loadReactions(e Engine) (err error) {
if c.Reactions != nil {
return nil
Expand Down
8 changes: 4 additions & 4 deletions models/issue_user.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,22 +94,22 @@ func UpdateIssueUserByRead(uid, issueID int64) error {
}

// UpdateIssueUsersByMentions updates issue-user pairs by mentioning.
func UpdateIssueUsersByMentions(e Engine, issueID int64, uids []int64) error {
func UpdateIssueUsersByMentions(ctx DBContext, issueID int64, uids []int64) error {
Copy link
Contributor

@zeripath zeripath Jun 17, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be in a transaction or should start its own

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could be, but not from the function itself.

for _, uid := range uids {
iu := &IssueUser{
UID: uid,
IssueID: issueID,
}
has, err := e.Get(iu)
has, err := ctx.e.Get(iu)
if err != nil {
return err
}

iu.IsMentioned = true
if has {
_, err = e.ID(iu.ID).Cols("is_mentioned").Update(iu)
_, err = ctx.e.ID(iu.ID).Cols("is_mentioned").Update(iu)
} else {
_, err = e.Insert(iu)
_, err = ctx.e.Insert(iu)
}
if err != nil {
return err
Expand Down
2 changes: 1 addition & 1 deletion models/issue_user_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func TestUpdateIssueUsersByMentions(t *testing.T) {
issue := AssertExistsAndLoadBean(t, &Issue{ID: 1}).(*Issue)

uids := []int64{2, 5}
assert.NoError(t, UpdateIssueUsersByMentions(x, issue.ID, uids))
assert.NoError(t, UpdateIssueUsersByMentions(DefaultDBContext(), issue.ID, uids))
for _, uid := range uids {
AssertExistsAndLoadBean(t, &IssueUser{IssueID: issue.ID, UID: uid}, "is_mentioned=1")
}
Expand Down
11 changes: 6 additions & 5 deletions modules/notification/mail/mail.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/notification/base"
"code.gitea.io/gitea/services/mailer"
)

type mailNotifier struct {
Expand Down Expand Up @@ -36,13 +37,13 @@ func (m *mailNotifier) NotifyCreateIssueComment(doer *models.User, repo *models.
act = models.ActionCommentIssue
}

if err := comment.MailParticipants(act, issue); err != nil {
if err := mailer.MailParticipantsComment(comment, act, issue); err != nil {
log.Error("MailParticipants: %v", err)
}
}

func (m *mailNotifier) NotifyNewIssue(issue *models.Issue) {
if err := issue.MailParticipants(issue.Poster, models.ActionCreateIssue); err != nil {
if err := mailer.MailParticipants(issue, issue.Poster, models.ActionCreateIssue); err != nil {
log.Error("MailParticipants: %v", err)
}
}
Expand All @@ -63,13 +64,13 @@ func (m *mailNotifier) NotifyIssueChangeStatus(doer *models.User, issue *models.
}
}

if err := issue.MailParticipants(doer, actionType); err != nil {
if err := mailer.MailParticipants(issue, doer, actionType); err != nil {
log.Error("MailParticipants: %v", err)
}
}

func (m *mailNotifier) NotifyNewPullRequest(pr *models.PullRequest) {
if err := pr.Issue.MailParticipants(pr.Issue.Poster, models.ActionCreatePullRequest); err != nil {
if err := mailer.MailParticipants(pr.Issue, pr.Issue.Poster, models.ActionCreatePullRequest); err != nil {
log.Error("MailParticipants: %v", err)
}
}
Expand All @@ -83,7 +84,7 @@ func (m *mailNotifier) NotifyPullRequestReview(pr *models.PullRequest, r *models
} else if comment.Type == models.CommentTypeComment {
act = models.ActionCommentIssue
}
if err := comment.MailParticipants(act, pr.Issue); err != nil {
if err := mailer.MailParticipantsComment(comment, act, pr.Issue); err != nil {
log.Error("MailParticipants: %v", err)
}
}
3 changes: 2 additions & 1 deletion routers/admin/admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"code.gitea.io/gitea/modules/process"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/services/mailer"

"gitea.com/macaron/macaron"
"github.com/unknwon/com"
Expand Down Expand Up @@ -197,7 +198,7 @@ func Dashboard(ctx *context.Context) {
func SendTestMail(ctx *context.Context) {
email := ctx.Query("email")
// Send a test email to the user's email address and redirect back to Config
if err := models.SendTestMail(email); err != nil {
if err := mailer.SendTestMail(email); err != nil {
ctx.Flash.Error(ctx.Tr("admin.config.test_mail_failed", email, err))
} else {
ctx.Flash.Info(ctx.Tr("admin.config.test_mail_sent", email))
Expand Down
5 changes: 3 additions & 2 deletions routers/admin/users.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/routers"
"code.gitea.io/gitea/services/mailer"

"github.com/unknwon/com"
)
Expand Down Expand Up @@ -116,8 +117,8 @@ func NewUserPost(ctx *context.Context, form auth.AdminCreateUserForm) {
log.Trace("Account created by admin (%s): %s", ctx.User.Name, u.Name)

// Send email notification.
if form.SendNotify && setting.MailService != nil {
models.SendRegisterNotifyMail(ctx.Context, u)
if form.SendNotify {
mailer.SendRegisterNotifyMail(ctx.Locale, u)
}

ctx.Flash.Success(ctx.Tr("admin.users.new_success", u.Name))
Expand Down
6 changes: 3 additions & 3 deletions routers/api/v1/admin/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ import (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/routers/api/v1/convert"
"code.gitea.io/gitea/routers/api/v1/user"
"code.gitea.io/gitea/services/mailer"
)

func parseLoginSource(ctx *context.APIContext, u *models.User, sourceID int64, loginName string) {
Expand Down Expand Up @@ -88,8 +88,8 @@ func CreateUser(ctx *context.APIContext, form api.CreateUserOption) {
log.Trace("Account created by admin (%s): %s", ctx.User.Name, u.Name)

// Send email notification.
if form.SendNotify && setting.MailService != nil {
models.SendRegisterNotifyMail(ctx.Context.Context, u)
if form.SendNotify {
mailer.SendRegisterNotifyMail(ctx.Locale, u)
}
ctx.JSON(201, convert.ToUser(u, ctx.IsSigned, ctx.User.IsAdmin))
}
Expand Down
2 changes: 1 addition & 1 deletion routers/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ import (
"code.gitea.io/gitea/modules/highlight"
issue_indexer "code.gitea.io/gitea/modules/indexer/issues"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/mailer"
"code.gitea.io/gitea/modules/markup"
"code.gitea.io/gitea/modules/markup/external"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/ssh"
"code.gitea.io/gitea/services/mailer"

"gitea.com/macaron/macaron"
)
Expand Down
3 changes: 2 additions & 1 deletion routers/repo/setting.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/validation"
"code.gitea.io/gitea/routers/utils"
"code.gitea.io/gitea/services/mailer"

"github.com/unknwon/com"
"mvdan.cc/xurls/v2"
Expand Down Expand Up @@ -549,7 +550,7 @@ func CollaborationPost(ctx *context.Context) {
}

if setting.Service.EnableNotifyMail {
models.SendCollaboratorMail(u, ctx.User, ctx.Repo.Repository)
mailer.SendCollaboratorMail(u, ctx.User, ctx.Repo.Repository)
}

ctx.Flash.Success(ctx.Tr("repo.settings.add_collaborator_success"))
Expand Down
3 changes: 2 additions & 1 deletion routers/routes/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import (
"code.gitea.io/gitea/routers/repo"
"code.gitea.io/gitea/routers/user"
userSetting "code.gitea.io/gitea/routers/user/setting"
"code.gitea.io/gitea/services/mailer"

// to registers all internal adapters
_ "code.gitea.io/gitea/modules/session"
Expand Down Expand Up @@ -166,7 +167,7 @@ func NewMacaron() *macaron.Macaron {
))

m.Use(templates.HTMLRenderer())
models.InitMailRender(templates.Mailer())
mailer.InitMailRender(templates.Mailer())

localeNames, err := options.Dir("locale")

Expand Down
Loading