소스 검색

Move models/mail.go to modules/mail.go

To use interface to replace *models.User in avoiding cycle import.
Unknwon 8 년 전
부모
커밋
4bc98f7aa2
12개의 변경된 파일148개의 추가작업 그리고 48개의 파일을 삭제
  1. 2 1
      cmd/web.go
  2. 1 1
      gogs.go
  3. 74 2
      models/issue_mail.go
  4. 55 34
      modules/mailer/mail.go
  5. 2 1
      routers/admin/admin.go
  6. 2 1
      routers/admin/users.go
  7. 2 1
      routers/api/v1/admin/user.go
  8. 2 1
      routers/repo/setting.go
  9. 4 3
      routers/user/auth.go
  10. 2 1
      routers/user/setting.go
  11. 1 1
      templates/.VERSION
  12. 1 1
      templates/mail/issue/mention.tmpl

+ 2 - 1
cmd/web.go

@@ -37,6 +37,7 @@ import (
 	"github.com/gogits/gogs/modules/bindata"
 	"github.com/gogits/gogs/modules/context"
 	"github.com/gogits/gogs/modules/log"
+	"github.com/gogits/gogs/modules/mailer"
 	"github.com/gogits/gogs/modules/setting"
 	"github.com/gogits/gogs/modules/template"
 	"github.com/gogits/gogs/routers"
@@ -140,7 +141,7 @@ func newMacaron() *macaron.Macaron {
 		Funcs:             funcMap,
 		IndentJSON:        macaron.Env != macaron.PROD,
 	}))
-	models.InitMailRender(path.Join(setting.StaticRootPath, "templates/mail"),
+	mailer.InitMailRender(path.Join(setting.StaticRootPath, "templates/mail"),
 		path.Join(setting.CustomPath, "templates/mail"), funcMap)
 
 	localeNames, err := bindata.AssetDir("conf/locale")

+ 1 - 1
gogs.go

@@ -16,7 +16,7 @@ import (
 	"github.com/gogits/gogs/modules/setting"
 )
 
-const APP_VER = "0.9.126.0129"
+const APP_VER = "0.9.127.0130"
 
 func init() {
 	setting.AppVer = APP_VER

+ 74 - 2
models/issue_mail.go

@@ -10,6 +10,7 @@ import (
 	"github.com/Unknwon/com"
 
 	"github.com/gogits/gogs/modules/log"
+	"github.com/gogits/gogs/modules/mailer"
 	"github.com/gogits/gogs/modules/markdown"
 	"github.com/gogits/gogs/modules/setting"
 )
@@ -18,6 +19,77 @@ func (issue *Issue) MailSubject() string {
 	return fmt.Sprintf("[%s] %s (#%d)", issue.Repo.Name, issue.Title, issue.Index)
 }
 
+// mailerUser is a wrapper for satisfying mailer.User interface.
+type mailerUser struct {
+	user *User
+}
+
+func (this mailerUser) ID() int64 {
+	return this.user.ID
+}
+
+func (this mailerUser) DisplayName() string {
+	return this.user.DisplayName()
+}
+
+func (this mailerUser) Email() string {
+	return this.user.Email
+}
+
+func (this mailerUser) GenerateActivateCode() string {
+	return this.user.GenerateActivateCode()
+}
+
+func (this mailerUser) GenerateEmailActivateCode(email string) string {
+	return this.user.GenerateEmailActivateCode(email)
+}
+
+func NewMailerUser(u *User) mailer.User {
+	return mailerUser{u}
+}
+
+// mailerRepo is a wrapper for satisfying mailer.Repository interface.
+type mailerRepo struct {
+	repo *Repository
+}
+
+func (this mailerRepo) FullName() string {
+	return this.repo.FullName()
+}
+
+func (this mailerRepo) HTMLURL() string {
+	return this.repo.HTMLURL()
+}
+
+func (this mailerRepo) ComposeMetas() map[string]string {
+	return this.repo.ComposeMetas()
+}
+
+func NewMailerRepo(repo *Repository) mailer.Repository {
+	return mailerRepo{repo}
+}
+
+// mailerIssue is a wrapper for satisfying mailer.Issue interface.
+type mailerIssue struct {
+	issue *Issue
+}
+
+func (this mailerIssue) MailSubject() string {
+	return this.issue.MailSubject()
+}
+
+func (this mailerIssue) Content() string {
+	return this.issue.Content
+}
+
+func (this mailerIssue) HTMLURL() string {
+	return this.issue.HTMLURL()
+}
+
+func NewMailerIssue(issue *Issue) mailer.Issue {
+	return mailerIssue{issue}
+}
+
 // mailIssueCommentToParticipants can be used for both new issue creation and comment.
 func mailIssueCommentToParticipants(issue *Issue, doer *User, mentions []string) error {
 	if !setting.Service.EnableNotifyMail {
@@ -48,7 +120,7 @@ func mailIssueCommentToParticipants(issue *Issue, doer *User, mentions []string)
 		tos = append(tos, to.Email)
 		names = append(names, to.Name)
 	}
-	SendIssueCommentMail(issue, doer, tos)
+	mailer.SendIssueCommentMail(NewMailerIssue(issue), NewMailerRepo(issue.Repo), NewMailerUser(doer), tos)
 
 	// Mail mentioned people and exclude watchers.
 	names = append(names, doer.Name)
@@ -60,7 +132,7 @@ func mailIssueCommentToParticipants(issue *Issue, doer *User, mentions []string)
 
 		tos = append(tos, mentions[i])
 	}
-	SendIssueMentionMail(issue, doer, GetUserEmailsByNames(tos))
+	mailer.SendIssueMentionMail(NewMailerIssue(issue), NewMailerRepo(issue.Repo), NewMailerUser(doer), GetUserEmailsByNames(tos))
 
 	return nil
 }

+ 55 - 34
models/mail.go → modules/mailer/mail.go

@@ -2,19 +2,17 @@
 // Use of this source code is governed by a MIT-style
 // license that can be found in the LICENSE file.
 
-package models
+package mailer
 
 import (
 	"fmt"
 	"html/template"
-	"path"
 
 	"gopkg.in/gomail.v2"
 	"gopkg.in/macaron.v1"
 
 	"github.com/gogits/gogs/modules/base"
 	"github.com/gogits/gogs/modules/log"
-	"github.com/gogits/gogs/modules/mailer"
 	"github.com/gogits/gogs/modules/markdown"
 	"github.com/gogits/gogs/modules/setting"
 )
@@ -54,10 +52,34 @@ func InitMailRender(dir, appendDir string, funcMap []template.FuncMap) {
 }
 
 func SendTestMail(email string) error {
-	return gomail.Send(&mailer.Sender{}, mailer.NewMessage([]string{email}, "Gogs Test Email!", "Gogs Test Email!").Message)
+	return gomail.Send(&Sender{}, NewMessage([]string{email}, "Gogs Test Email!", "Gogs Test Email!").Message)
 }
 
-func SendUserMail(c *macaron.Context, u *User, tpl base.TplName, code, subject, info string) {
+/*
+	Setup interfaces of used methods in mail to avoid cycle import.
+*/
+
+type User interface {
+	ID() int64
+	DisplayName() string
+	Email() string
+	GenerateActivateCode() string
+	GenerateEmailActivateCode(string) string
+}
+
+type Repository interface {
+	FullName() string
+	HTMLURL() string
+	ComposeMetas() map[string]string
+}
+
+type Issue interface {
+	MailSubject() string
+	Content() string
+	HTMLURL() string
+}
+
+func SendUserMail(c *macaron.Context, u User, tpl base.TplName, code, subject, info string) {
 	data := map[string]interface{}{
 		"Username":          u.DisplayName(),
 		"ActiveCodeLives":   setting.Service.ActiveCodeLives / 60,
@@ -70,27 +92,27 @@ func SendUserMail(c *macaron.Context, u *User, tpl base.TplName, code, subject,
 		return
 	}
 
-	msg := mailer.NewMessage([]string{u.Email}, subject, body)
-	msg.Info = fmt.Sprintf("UID: %d, %s", u.ID, info)
+	msg := NewMessage([]string{u.Email()}, subject, body)
+	msg.Info = fmt.Sprintf("UID: %d, %s", u.ID(), info)
 
-	mailer.SendAsync(msg)
+	SendAsync(msg)
 }
 
-func SendActivateAccountMail(c *macaron.Context, u *User) {
+func SendActivateAccountMail(c *macaron.Context, u User) {
 	SendUserMail(c, u, MAIL_AUTH_ACTIVATE, u.GenerateActivateCode(), c.Tr("mail.activate_account"), "activate account")
 }
 
-func SendResetPasswordMail(c *macaron.Context, u *User) {
+func SendResetPasswordMail(c *macaron.Context, u User) {
 	SendUserMail(c, u, MAIL_AUTH_RESET_PASSWORD, u.GenerateActivateCode(), c.Tr("mail.reset_password"), "reset password")
 }
 
 // SendActivateAccountMail sends confirmation email.
-func SendActivateEmailMail(c *macaron.Context, u *User, email *EmailAddress) {
+func SendActivateEmailMail(c *macaron.Context, u User, email string) {
 	data := map[string]interface{}{
 		"Username":        u.DisplayName(),
 		"ActiveCodeLives": setting.Service.ActiveCodeLives / 60,
-		"Code":            u.GenerateEmailActivateCode(email.Email),
-		"Email":           email.Email,
+		"Code":            u.GenerateEmailActivateCode(email),
+		"Email":           email,
 	}
 	body, err := mailRender.HTMLString(string(MAIL_AUTH_ACTIVATE_EMAIL), data)
 	if err != nil {
@@ -98,14 +120,14 @@ func SendActivateEmailMail(c *macaron.Context, u *User, email *EmailAddress) {
 		return
 	}
 
-	msg := mailer.NewMessage([]string{email.Email}, c.Tr("mail.activate_email"), body)
-	msg.Info = fmt.Sprintf("UID: %d, activate email", u.ID)
+	msg := NewMessage([]string{email}, c.Tr("mail.activate_email"), body)
+	msg.Info = fmt.Sprintf("UID: %d, activate email", u.ID())
 
-	mailer.SendAsync(msg)
+	SendAsync(msg)
 }
 
 // SendRegisterNotifyMail triggers a notify e-mail by admin created a account.
-func SendRegisterNotifyMail(c *macaron.Context, u *User) {
+func SendRegisterNotifyMail(c *macaron.Context, u User) {
 	data := map[string]interface{}{
 		"Username": u.DisplayName(),
 	}
@@ -115,20 +137,19 @@ func SendRegisterNotifyMail(c *macaron.Context, u *User) {
 		return
 	}
 
-	msg := mailer.NewMessage([]string{u.Email}, c.Tr("mail.register_notify"), body)
-	msg.Info = fmt.Sprintf("UID: %d, registration notify", u.ID)
+	msg := NewMessage([]string{u.Email()}, c.Tr("mail.register_notify"), body)
+	msg.Info = fmt.Sprintf("UID: %d, registration notify", u.ID())
 
-	mailer.SendAsync(msg)
+	SendAsync(msg)
 }
 
 // SendCollaboratorMail sends mail notification to new collaborator.
-func SendCollaboratorMail(u, doer *User, repo *Repository) {
-	repoName := path.Join(repo.Owner.Name, repo.Name)
-	subject := fmt.Sprintf("%s added you to %s", doer.DisplayName(), repoName)
+func SendCollaboratorMail(u, doer User, repo Repository) {
+	subject := fmt.Sprintf("%s added you to %s", doer.DisplayName(), repo.FullName())
 
 	data := map[string]interface{}{
 		"Subject":  subject,
-		"RepoName": repoName,
+		"RepoName": repo.FullName(),
 		"Link":     repo.HTMLURL(),
 	}
 	body, err := mailRender.HTMLString(string(MAIL_NOTIFY_COLLABORATOR), data)
@@ -137,10 +158,10 @@ func SendCollaboratorMail(u, doer *User, repo *Repository) {
 		return
 	}
 
-	msg := mailer.NewMessage([]string{u.Email}, subject, body)
-	msg.Info = fmt.Sprintf("UID: %d, add collaborator", u.ID)
+	msg := NewMessage([]string{u.Email()}, subject, body)
+	msg.Info = fmt.Sprintf("UID: %d, add collaborator", u.ID())
 
-	mailer.SendAsync(msg)
+	SendAsync(msg)
 }
 
 func composeTplData(subject, body, link string) map[string]interface{} {
@@ -151,9 +172,9 @@ func composeTplData(subject, body, link string) map[string]interface{} {
 	return data
 }
 
-func composeIssueMessage(issue *Issue, doer *User, tplName base.TplName, tos []string, info string) *mailer.Message {
+func composeIssueMessage(issue Issue, repo Repository, doer User, tplName base.TplName, tos []string, info string) *Message {
 	subject := issue.MailSubject()
-	body := string(markdown.RenderSpecialLink([]byte(issue.Content), issue.Repo.HTMLURL(), issue.Repo.ComposeMetas()))
+	body := string(markdown.RenderSpecialLink([]byte(issue.Content()), repo.HTMLURL(), repo.ComposeMetas()))
 	data := composeTplData(subject, body, issue.HTMLURL())
 	data["Doer"] = doer
 	content, err := mailRender.HTMLString(string(tplName), data)
@@ -161,24 +182,24 @@ func composeIssueMessage(issue *Issue, doer *User, tplName base.TplName, tos []s
 		log.Error(3, "HTMLString (%s): %v", tplName, err)
 	}
 	from := gomail.NewMessage().FormatAddress(setting.MailService.FromEmail, doer.DisplayName())
-	msg := mailer.NewMessageFrom(tos, from, subject, content)
+	msg := NewMessageFrom(tos, from, subject, content)
 	msg.Info = fmt.Sprintf("Subject: %s, %s", subject, info)
 	return msg
 }
 
 // SendIssueCommentMail composes and sends issue comment emails to target receivers.
-func SendIssueCommentMail(issue *Issue, doer *User, tos []string) {
+func SendIssueCommentMail(issue Issue, repo Repository, doer User, tos []string) {
 	if len(tos) == 0 {
 		return
 	}
 
-	mailer.SendAsync(composeIssueMessage(issue, doer, MAIL_ISSUE_COMMENT, tos, "issue comment"))
+	SendAsync(composeIssueMessage(issue, repo, doer, MAIL_ISSUE_COMMENT, tos, "issue comment"))
 }
 
 // SendIssueMentionMail composes and sends issue mention emails to target receivers.
-func SendIssueMentionMail(issue *Issue, doer *User, tos []string) {
+func SendIssueMentionMail(issue Issue, repo Repository, doer User, tos []string) {
 	if len(tos) == 0 {
 		return
 	}
-	mailer.SendAsync(composeIssueMessage(issue, doer, MAIL_ISSUE_MENTION, tos, "issue mention"))
+	SendAsync(composeIssueMessage(issue, repo, doer, MAIL_ISSUE_MENTION, tos, "issue mention"))
 }

+ 2 - 1
routers/admin/admin.go

@@ -17,6 +17,7 @@ import (
 	"github.com/gogits/gogs/modules/base"
 	"github.com/gogits/gogs/modules/context"
 	"github.com/gogits/gogs/modules/cron"
+	"github.com/gogits/gogs/modules/mailer"
 	"github.com/gogits/gogs/modules/process"
 	"github.com/gogits/gogs/modules/setting"
 )
@@ -177,7 +178,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))

+ 2 - 1
routers/admin/users.go

@@ -14,6 +14,7 @@ import (
 	"github.com/gogits/gogs/modules/base"
 	"github.com/gogits/gogs/modules/context"
 	"github.com/gogits/gogs/modules/log"
+	"github.com/gogits/gogs/modules/mailer"
 	"github.com/gogits/gogs/modules/setting"
 	"github.com/gogits/gogs/routers"
 )
@@ -116,7 +117,7 @@ func NewUserPost(ctx *context.Context, form auth.AdminCrateUserForm) {
 
 	// Send email notification.
 	if form.SendNotify && setting.MailService != nil {
-		models.SendRegisterNotifyMail(ctx.Context, u)
+		mailer.SendRegisterNotifyMail(ctx.Context, models.NewMailerUser(u))
 	}
 
 	ctx.Flash.Success(ctx.Tr("admin.users.new_success", u.Name))

+ 2 - 1
routers/api/v1/admin/user.go

@@ -10,6 +10,7 @@ import (
 	"github.com/gogits/gogs/models"
 	"github.com/gogits/gogs/modules/context"
 	"github.com/gogits/gogs/modules/log"
+	"github.com/gogits/gogs/modules/mailer"
 	"github.com/gogits/gogs/modules/setting"
 	"github.com/gogits/gogs/routers/api/v1/user"
 )
@@ -65,7 +66,7 @@ func CreateUser(ctx *context.APIContext, form api.CreateUserOption) {
 
 	// Send email notification.
 	if form.SendNotify && setting.MailService != nil {
-		models.SendRegisterNotifyMail(ctx.Context.Context, u)
+		mailer.SendRegisterNotifyMail(ctx.Context.Context, models.NewMailerUser(u))
 	}
 
 	ctx.JSON(201, u.APIFormat())

+ 2 - 1
routers/repo/setting.go

@@ -15,6 +15,7 @@ import (
 	"github.com/gogits/gogs/modules/base"
 	"github.com/gogits/gogs/modules/context"
 	"github.com/gogits/gogs/modules/log"
+	"github.com/gogits/gogs/modules/mailer"
 	"github.com/gogits/gogs/modules/setting"
 )
 
@@ -344,7 +345,7 @@ func CollaborationPost(ctx *context.Context) {
 	}
 
 	if setting.Service.EnableNotifyMail {
-		models.SendCollaboratorMail(u, ctx.User, ctx.Repo.Repository)
+		mailer.SendCollaboratorMail(models.NewMailerUser(u), models.NewMailerUser(ctx.User), models.NewMailerRepo(ctx.Repo.Repository))
 	}
 
 	ctx.Flash.Success(ctx.Tr("repo.settings.add_collaborator_success"))

+ 4 - 3
routers/user/auth.go

@@ -15,6 +15,7 @@ import (
 	"github.com/gogits/gogs/modules/base"
 	"github.com/gogits/gogs/modules/context"
 	"github.com/gogits/gogs/modules/log"
+	"github.com/gogits/gogs/modules/mailer"
 	"github.com/gogits/gogs/modules/setting"
 )
 
@@ -228,7 +229,7 @@ func SignUpPost(ctx *context.Context, cpt *captcha.Captcha, form auth.RegisterFo
 
 	// Send confirmation email, no need for social account.
 	if setting.Service.RegisterEmailConfirm && u.ID > 1 {
-		models.SendActivateAccountMail(ctx.Context, u)
+		mailer.SendActivateAccountMail(ctx.Context, models.NewMailerUser(u))
 		ctx.Data["IsSendRegisterMail"] = true
 		ctx.Data["Email"] = u.Email
 		ctx.Data["Hours"] = setting.Service.ActiveCodeLives / 60
@@ -257,7 +258,7 @@ func Activate(ctx *context.Context) {
 				ctx.Data["ResendLimited"] = true
 			} else {
 				ctx.Data["Hours"] = setting.Service.ActiveCodeLives / 60
-				models.SendActivateAccountMail(ctx.Context, ctx.User)
+				mailer.SendActivateAccountMail(ctx.Context, models.NewMailerUser(ctx.User))
 
 				if err := ctx.Cache.Put("MailResendLimit_"+ctx.User.LowerName, ctx.User.LowerName, 180); err != nil {
 					log.Error(4, "Set cache(MailResendLimit) fail: %v", err)
@@ -367,7 +368,7 @@ func ForgotPasswdPost(ctx *context.Context) {
 		return
 	}
 
-	models.SendResetPasswordMail(ctx.Context, u)
+	mailer.SendResetPasswordMail(ctx.Context, models.NewMailerUser(u))
 	if err = ctx.Cache.Put("MailResendLimit_"+u.LowerName, u.LowerName, 180); err != nil {
 		log.Error(4, "Set cache(MailResendLimit) fail: %v", err)
 	}

+ 2 - 1
routers/user/setting.go

@@ -17,6 +17,7 @@ import (
 	"github.com/gogits/gogs/modules/base"
 	"github.com/gogits/gogs/modules/context"
 	"github.com/gogits/gogs/modules/log"
+	"github.com/gogits/gogs/modules/mailer"
 	"github.com/gogits/gogs/modules/setting"
 )
 
@@ -266,7 +267,7 @@ func SettingsEmailPost(ctx *context.Context, form auth.AddEmailForm) {
 
 	// Send confirmation email
 	if setting.Service.RegisterEmailConfirm {
-		models.SendActivateEmailMail(ctx.Context, ctx.User, email)
+		mailer.SendActivateEmailMail(ctx.Context, models.NewMailerUser(ctx.User), email.Email)
 
 		if err := ctx.Cache.Put("MailResendLimit_"+ctx.User.LowerName, ctx.User.LowerName, 180); err != nil {
 			log.Error(4, "Set cache(MailResendLimit) fail: %v", err)

+ 1 - 1
templates/.VERSION

@@ -1 +1 @@
-0.9.126.0129
+0.9.127.0130

+ 1 - 1
templates/mail/issue/mention.tmpl

@@ -6,7 +6,7 @@
 </head>
 
 <body>
-	<p>@{{.Doer.Name}} mentioned you:</p>
+	<p>@{{.Doer.DisplayName}} mentioned you:</p>
 	<p>{{.Body | Str2html}}</p>
 	<p>
 		---