diff --git a/doc/notification.md b/doc/notification.md index f9fb1e0..db0e48d 100644 --- a/doc/notification.md +++ b/doc/notification.md @@ -17,6 +17,7 @@ Notified users are as follows: * individual repository's owner +* group members of group repository * collaborators * participants diff --git a/src/main/scala/gitbucket/core/controller/PullRequestsController.scala b/src/main/scala/gitbucket/core/controller/PullRequestsController.scala index 596d99e..4029ff0 100644 --- a/src/main/scala/gitbucket/core/controller/PullRequestsController.scala +++ b/src/main/scala/gitbucket/core/controller/PullRequestsController.scala @@ -281,11 +281,6 @@ // call hooks PluginRegistry().getPullRequestHooks.foreach(_.merged(issue, repository)) - // notifications TODO move to plugin - Notifier().toNotify(repository, issue, "merge"){ - Notifier.msgStatus(s"${context.baseUrl}/${owner}/${name}/pull/${issueId}") - } - redirect(s"/${owner}/${name}/pull/${issueId}") } } @@ -490,11 +485,6 @@ // call hooks PluginRegistry().getPullRequestHooks.foreach(_.created(issue, repository)) - - // notifications TODO move to plugin - Notifier().toNotify(repository, issue, form.content.getOrElse("")) { - Notifier.msgPullRequest(s"${context.baseUrl}/${owner}/${name}/pull/${issueId}") - } } redirect(s"/${owner}/${name}/pull/${issueId}") diff --git a/src/main/scala/gitbucket/core/service/HandleCommentService.scala b/src/main/scala/gitbucket/core/service/HandleCommentService.scala index 7fc0fc6..f7ce6ff 100644 --- a/src/main/scala/gitbucket/core/service/HandleCommentService.scala +++ b/src/main/scala/gitbucket/core/service/HandleCommentService.scala @@ -6,7 +6,6 @@ import gitbucket.core.plugin.PluginRegistry import gitbucket.core.util.SyntaxSugars._ import gitbucket.core.util.Implicits._ -import gitbucket.core.util.Notifier trait HandleCommentService { self: RepositoryService with IssuesService with ActivityService @@ -87,22 +86,6 @@ PluginRegistry().getIssueHooks.foreach(_.reopened(issue, repository)) } - // notifications // TODO move to plugin - Notifier() match { - case f => - content foreach { - f.toNotify(repository, issue, _){ - Notifier.msgComment(s"${context.baseUrl}/${owner}/${name}/${ - if(issue.isPullRequest) "pull" else "issues"}/${issue.issueId}#comment-${commentId.get}") - } - } - action foreach { - f.toNotify(repository, issue, _){ - Notifier.msgStatus(s"${context.baseUrl}/${owner}/${name}/issues/${issue.issueId}") - } - } - } - commentId.map( issue -> _ ) } } diff --git a/src/main/scala/gitbucket/core/service/IssueCreationService.scala b/src/main/scala/gitbucket/core/service/IssueCreationService.scala index 1439c04..09e7dfb 100644 --- a/src/main/scala/gitbucket/core/service/IssueCreationService.scala +++ b/src/main/scala/gitbucket/core/service/IssueCreationService.scala @@ -5,7 +5,6 @@ import gitbucket.core.model.Profile.profile.blockingApi._ import gitbucket.core.plugin.PluginRegistry import gitbucket.core.service.RepositoryService.RepositoryInfo -import gitbucket.core.util.Notifier import gitbucket.core.util.Implicits._ trait IssueCreationService { @@ -49,10 +48,6 @@ // call hooks PluginRegistry().getIssueHooks.foreach(_.created(issue, repository)) - // notifications TODO move to plugin - Notifier().toNotify(repository, issue, body.getOrElse("")) { - Notifier.msgIssue(s"${context.baseUrl}/${owner}/${name}/issues/${issueId}") - } issue } diff --git a/src/main/scala/gitbucket/core/util/Notifier.scala b/src/main/scala/gitbucket/core/util/Notifier.scala index 3c8dba5..0c7d861 100644 --- a/src/main/scala/gitbucket/core/util/Notifier.scala +++ b/src/main/scala/gitbucket/core/util/Notifier.scala @@ -1,10 +1,9 @@ package gitbucket.core.util -import gitbucket.core.model.{Session, Issue, Account} +import gitbucket.core.model.{Session, Account} import gitbucket.core.model.Profile.profile.blockingApi._ -import gitbucket.core.service.{RepositoryService, AccountService, IssuesService, SystemSettingsService} +import gitbucket.core.service.SystemSettingsService import gitbucket.core.servlet.Database -import gitbucket.core.view.Markdown import scala.concurrent._ import scala.util.{Success, Failure} @@ -13,87 +12,38 @@ import org.slf4j.LoggerFactory import gitbucket.core.controller.Context import SystemSettingsService.Smtp -import SyntaxSugars.defining -trait Notifier extends RepositoryService with AccountService with IssuesService { +/** + * The trait for notifications. + * This is used by notifications plugin, which provides notifications feature on GitBucket. + * Please see the plugin for details. + */ +trait Notifier { - def toNotify(r: RepositoryService.RepositoryInfo, issue: Issue, content: String) - (msg: String => String)(implicit context: Context): Unit + def toNotify(subject: String, msg: String) + (recipients: Account => Session => Seq[String])(implicit context: Context): Unit - protected def recipients(issue: Issue, loginAccount: Account)(notify: String => Unit)(implicit session: Session) = - ( - // individual repository's owner - issue.userName :: - // group members of group repository - getGroupMembers(issue.userName).map(_.userName) ::: - // collaborators - getCollaboratorUserNames(issue.userName, issue.repositoryName) ::: - // participants - issue.openedUserName :: - getComments(issue.userName, issue.repositoryName, issue.issueId).map(_.commentedUserName) - ) - .distinct - .withFilter ( _ != loginAccount.userName ) // the operation in person is excluded - .foreach ( - getAccountByUserName(_) - .filterNot (_.isGroupAccount) - .filterNot (LDAPUtil.isDummyMailAddress(_)) - .foreach (x => notify(x.mailAddress)) - ) } object Notifier { - // TODO We want to be able to switch to mock. def apply(): Notifier = new SystemSettingsService {}.loadSystemSettings match { case settings if (settings.notification && settings.useSMTP) => new Mailer(settings.smtp.get) case _ => new MockMailer } - - def msgIssue(url: String) = (content: String) => s""" - |${content}<br/> - |--<br/> - |<a href="${url}">View it on GitBucket</a> - """.stripMargin - - def msgPullRequest(url: String) = (content: String) => s""" - |${content}<hr/> - |View, comment on, or merge it at:<br/> - |<a href="${url}">${url}</a> - """.stripMargin - - def msgComment(url: String) = (content: String) => s""" - |${content}<br/> - |--<br/> - |<a href="${url}">View it on GitBucket</a> - """.stripMargin - - def msgStatus(url: String) = (content: String) => s""" - |${content} <a href="${url}">#${url split('/') last}</a> - """.stripMargin } class Mailer(private val smtp: Smtp) extends Notifier { private val logger = LoggerFactory.getLogger(classOf[Mailer]) - def toNotify(r: RepositoryService.RepositoryInfo, issue: Issue, content: String) - (msg: String => String)(implicit context: Context): Unit = { + def toNotify(subject: String, msg: String) + (recipients: Account => Session => Seq[String])(implicit context: Context): Unit = { context.loginAccount.foreach { loginAccount => val database = Database() val f = Future { - database withSession { implicit session => - defining( - s"[${r.owner}/${r.name}] ${issue.title} (#${issue.issueId})" -> - msg(Markdown.toHtml( - markdown = content, - repository = r, - enableWikiLink = false, - enableRefsLink = true, - enableAnchor = false, - enableLineBreaks = false - )) - ) { case (subject, msg) => - recipients(issue, loginAccount) { to => send(to, subject, msg, loginAccount) } + database withSession { session => + recipients(loginAccount)(session) foreach { to => + send(to, subject, msg, loginAccount) } } "Notifications Successful." @@ -137,6 +87,6 @@ } class MockMailer extends Notifier { - def toNotify(r: RepositoryService.RepositoryInfo, issue: Issue, content: String) - (msg: String => String)(implicit context: Context): Unit = {} + def toNotify(subject: String, msg: String) + (recipients: Account => Session => Seq[String])(implicit context: Context): Unit = () }