diff --git a/src/main/scala/gitbucket/core/plugin/PluginRegistory.scala b/src/main/scala/gitbucket/core/plugin/PluginRegistory.scala index c6dcc62..d31cb76 100644 --- a/src/main/scala/gitbucket/core/plugin/PluginRegistory.scala +++ b/src/main/scala/gitbucket/core/plugin/PluginRegistory.scala @@ -39,7 +39,11 @@ private val repositoryHooks = new ListBuffer[RepositoryHook] private val issueHooks = new ListBuffer[IssueHook] + issueHooks += new gitbucket.core.util.Notifier.IssueHook() + private val pullRequestHooks = new ListBuffer[PullRequestHook] + pullRequestHooks += new gitbucket.core.util.Notifier.PullRequestHook() + private val globalMenus = new ListBuffer[(Context) => Option[Link]] private val repositoryMenus = new ListBuffer[(RepositoryInfo, Context) => Option[Link]] private val repositorySettingTabs = new ListBuffer[(RepositoryInfo, Context) => Option[Link]] diff --git a/src/main/scala/gitbucket/core/util/Notifier.scala b/src/main/scala/gitbucket/core/util/Notifier.scala index 0c7d861..3e8d39c 100644 --- a/src/main/scala/gitbucket/core/util/Notifier.scala +++ b/src/main/scala/gitbucket/core/util/Notifier.scala @@ -1,9 +1,10 @@ package gitbucket.core.util -import gitbucket.core.model.{Session, Account} +import gitbucket.core.model.{Session, Issue, Account} import gitbucket.core.model.Profile.profile.blockingApi._ -import gitbucket.core.service.SystemSettingsService +import gitbucket.core.service.{RepositoryService, AccountService, IssuesService, SystemSettingsService} import gitbucket.core.servlet.Database +import gitbucket.core.view.Markdown import scala.concurrent._ import scala.util.{Success, Failure} @@ -30,6 +31,125 @@ case settings if (settings.notification && settings.useSMTP) => new Mailer(settings.smtp.get) case _ => new MockMailer } + + + // TODO This class is temporary keeping the current feature until Notifications Plugin is available. + class IssueHook extends gitbucket.core.plugin.IssueHook + with RepositoryService with AccountService with IssuesService { + + override def created(issue: Issue, r: RepositoryService.RepositoryInfo)(implicit context: Context): Unit = { + Notifier().toNotify( + subject(issue, r), + message(issue.content getOrElse "", r)(content => s""" + |$content
+ |--
+ |View it on GitBucket + """.stripMargin) + )(recipients(issue)) + } + + override def addedComment(commentId: Int, content: String, issue: Issue, r: RepositoryService.RepositoryInfo)(implicit context: Context): Unit = { + Notifier().toNotify( + subject(issue, r), + message(content, r)(content => s""" + |$content
+ |--
+ |View it on GitBucket + """.stripMargin) + )(recipients(issue)) + } + + override def closed(issue: Issue, r: RepositoryService.RepositoryInfo)(implicit context: Context): Unit = { + Notifier().toNotify( + subject(issue, r), + message("close", r)(content => s""" + |$content #${issue.issueId} + """.stripMargin) + )(recipients(issue)) + } + + override def reopened(issue: Issue, r: RepositoryService.RepositoryInfo)(implicit context: Context): Unit = { + Notifier().toNotify( + subject(issue, r), + message("reopen", r)(content => s""" + |$content #${issue.issueId} + """.stripMargin) + )(recipients(issue)) + } + + + protected def subject(issue: Issue, r: RepositoryService.RepositoryInfo): String = + s"[${r.owner}/${r.name}] ${issue.title} (#${issue.issueId})" + + protected def message(content: String, r: RepositoryService.RepositoryInfo)(msg: String => String)(implicit context: Context): String = + msg(Markdown.toHtml( + markdown = content, + repository = r, + enableWikiLink = false, + enableRefsLink = true, + enableAnchor = false, + enableLineBreaks = false + )) + + protected val recipients: Issue => Account => Session => Seq[String] = { + issue => loginAccount => implicit 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 + .flatMap ( + getAccountByUserName(_) + .filterNot (_.isGroupAccount) + .filterNot (LDAPUtil.isDummyMailAddress) + .map (_.mailAddress) + ) + } + } + + // TODO This class is temporary keeping the current feature until Notifications Plugin is available. + class PullRequestHook extends IssueHook with gitbucket.core.plugin.PullRequestHook { + override def created(issue: Issue, r: RepositoryService.RepositoryInfo)(implicit context: Context): Unit = { + val url = s"${context.baseUrl}/${r.owner}/${r.name}/pull/${issue.issueId}" + Notifier().toNotify( + subject(issue, r), + message(issue.content getOrElse "", r)(content => s""" + |$content
+ |View, comment on, or merge it at:
+ |$url + """.stripMargin) + )(recipients(issue)) + } + + override def addedComment(commentId: Int, content: String, issue: Issue, r: RepositoryService.RepositoryInfo)(implicit context: Context): Unit = { + Notifier().toNotify( + subject(issue, r), + message(content, r)(content => s""" + |$content
+ |--
+ |View it on GitBucket + """.stripMargin) + )(recipients(issue)) + } + + override def merged(issue: Issue, r: RepositoryService.RepositoryInfo)(implicit context: Context): Unit = { + Notifier().toNotify( + subject(issue, r), + message("merge", r)(content => s""" + |$content #${issue.issueId} + """.stripMargin) + )(recipients(issue)) + } + } + } class Mailer(private val smtp: Smtp) extends Notifier {