Skip to content

Commit 8d40d69

Browse files
committed
Merge branch 'master' into disable-email
# Conflicts: # build.sbt # src/main/scala/Plugin.scala # src/main/scala/gitbucket/notifications/service/NotificationsHook.scala
2 parents 067e8c1 + cbb74f1 commit 8d40d69

File tree

7 files changed

+141
-83
lines changed

7 files changed

+141
-83
lines changed

.travis.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
sudo: false
2+
language: scala
3+
jdk:
4+
- oraclejdk8
5+
script:
6+
- ./build-gitbucket-plugin.sh

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1-
# gitbucket-notifications-plugin
1+
# gitbucket-notifications-plugin [![Build Status](https://travis-ci.org/gitbucket/gitbucket-notifications-plugin.svg)](https://travis-ci.org/gitbucket/gitbucket-notifications-plugin)
22

33
This plug-in provides notifications feature on GitBucket.
44

55
Plugin version | GitBucket version
66
:--------------|:--------------------
7+
1.2.x | 4.17.x
8+
1.1.x | 4.16.x
79
1.0.x | 4.15.x
810

911
## Features

build-gitbucket-plugin.sh

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#!/bin/sh
2+
rm -rf gitbucket
3+
git clone https://github.com/gitbucket/gitbucket.git
4+
cd gitbucket
5+
6+
GITBUCKET_VERSION=`cat build.sbt | grep "GitBucketVersion =" | sed 's/^.*"\(.*\)".*$/\1/'`
7+
echo "GITBUCKET_VERSION: $GITBUCKET_VERSION"
8+
sbt publish-local
9+
10+
cd ..
11+
sbt -Dgitbucket.version=$GITBUCKET_VERSION test

build.sbt

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
1-
name := "gitbucket-notifications-plugin"
1+
val Organization = "io.github.gitbucket"
2+
val ProjectName = "gitbucket-notifications-plugin"
3+
val ProjectVersion = "1.2.0"
4+
val GitBucketVersion = Option(System.getProperty("gitbucket.version")).getOrElse("4.17.0")
25

3-
organization := "io.github.gitbucket"
4-
version := "1.1.0"
6+
name := ProjectName
7+
organization := Organization
8+
version := ProjectVersion
59
scalaVersion := "2.12.3"
610

711
lazy val root = (project in file(".")).enablePlugins(SbtTwirl)
812

913
libraryDependencies ++= Seq(
10-
"io.github.gitbucket" %% "gitbucket" % "4.15.0" % "provided",
11-
"javax.servlet" % "javax.servlet-api" % "3.1.0" % "provided"
14+
"io.github.gitbucket" %% "gitbucket" % GitBucketVersion % "provided",
15+
"javax.servlet" % "javax.servlet-api" % "3.1.0" % "provided"
1216
)
1317

1418
scalacOptions ++= Seq("-feature", "-deprecation")
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<changeSet>
3+
<dropForeignKeyConstraint constraintName="IDX_ISSUE_NOTIFICATION_FK0" baseTableName="ISSUE_NOTIFICATION" />
4+
<dropForeignKeyConstraint constraintName="IDX_ISSUE_NOTIFICATION_FK1" baseTableName="ISSUE_NOTIFICATION" />
5+
<dropForeignKeyConstraint constraintName="IDX_WATCH_FK0" baseTableName="WATCH" />
6+
<dropForeignKeyConstraint constraintName="IDX_WATCH_FK1" baseTableName="WATCH" />
7+
</changeSet>

src/main/scala/Plugin.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ class Plugin extends gitbucket.core.plugin.Plugin {
2020
new Version("1.0.0",
2121
new LiquibaseMigration("update/gitbucket-notifications_1.0.xml")
2222
),
23+
new Version("1.1.0",
24+
new LiquibaseMigration("update/gitbucket-notifications_1.1.xml")
25+
),
26+
new Version("1.2.0"),
2327
new Version("1.3.0",
2428
new LiquibaseMigration("update/gitbucket-notifications_1.3.xml")
2529
)

src/main/scala/gitbucket/notifications/service/NotificationsHook.scala

Lines changed: 101 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,18 @@ package gitbucket.notifications.service
22

33
import gitbucket.core.controller.Context
44
import gitbucket.core.model.{Account, Issue}
5-
import gitbucket.core.service._, RepositoryService.RepositoryInfo
6-
import gitbucket.core.util.{LDAPUtil, Notifier}
5+
import gitbucket.core.service._
6+
import RepositoryService.RepositoryInfo
7+
import gitbucket.core.util.{LDAPUtil, Mailer}
78
import gitbucket.core.view.Markdown
89
import gitbucket.notifications.model.Profile._
10+
import org.slf4j.LoggerFactory
911
import profile.blockingApi._
1012

13+
import scala.concurrent.Future
14+
import scala.concurrent.ExecutionContext.Implicits.global
15+
import scala.util.{Success, Failure}
16+
1117

1218
class AccountHook extends gitbucket.core.plugin.AccountHook {
1319

@@ -52,106 +58,124 @@ class IssueHook extends gitbucket.core.plugin.IssueHook
5258
with AccountService
5359
with IssuesService {
5460

55-
override def created(issue: Issue, r: RepositoryInfo)(implicit context: Context): Unit = {
56-
Notifier().toNotify(
57-
subject(issue, r),
58-
message(issue.content getOrElse "", r)(content => s"""
59-
|$content<br/>
60-
|--<br/>
61-
|<a href="${s"${context.baseUrl}/${r.owner}/${r.name}/issues/${issue.issueId}"}">View it on GitBucket</a>
62-
""".stripMargin)
63-
)(recipients(issue))
61+
private val logger = LoggerFactory.getLogger(classOf[IssueHook])
62+
63+
override def created(issue: Issue, r: RepositoryInfo)(implicit session: Session, context: Context): Unit = {
64+
val markdown =
65+
s"""|${issue.content getOrElse ""}
66+
|
67+
|----
68+
|[View it on GitBucket](${s"${context.baseUrl}/${r.owner}/${r.name}/issues/${issue.issueId}"})
69+
|""".stripMargin
70+
71+
sendAsync(issue, r, subject(issue, r), markdown)
6472
}
6573

66-
override def addedComment(commentId: Int, content: String, issue: Issue, r: RepositoryInfo)(implicit context: Context): Unit = {
67-
Notifier().toNotify(
68-
subject(issue, r),
69-
message(content, r)(content => s"""
70-
|$content<br/>
71-
|--<br/>
72-
|<a href="${s"${context.baseUrl}/${r.owner}/${r.name}/issues/${issue.issueId}#comment-$commentId"}">View it on GitBucket</a>
73-
""".stripMargin)
74-
)(recipients(issue))
74+
override def addedComment(commentId: Int, content: String, issue: Issue, r: RepositoryInfo)
75+
(implicit session: Session, context: Context): Unit = {
76+
val markdown =
77+
s"""|${content}
78+
|
79+
|----
80+
|[View it on GitBucket](${s"${context.baseUrl}/${r.owner}/${r.name}/issues/${issue.issueId}#comment-$commentId"})
81+
|""".stripMargin
82+
83+
sendAsync(issue, r, subject(issue, r), markdown)
7584
}
7685

77-
override def closed(issue: Issue, r: RepositoryInfo)(implicit context: Context): Unit = {
78-
Notifier().toNotify(
79-
subject(issue, r),
80-
message("close", r)(content => s"""
81-
|$content <a href="${s"${context.baseUrl}/${r.owner}/${r.name}/issues/${issue.issueId}"}">#${issue.issueId}</a>
82-
""".stripMargin)
83-
)(recipients(issue))
86+
override def closed(issue: Issue, r: RepositoryInfo)(implicit session: Session, context: Context): Unit = {
87+
val markdown =
88+
s"""|close #[${issue.issueId}](${s"${context.baseUrl}/${r.owner}/${r.name}/issues/${issue.issueId}"})
89+
|""".stripMargin
90+
91+
sendAsync(issue, r, subject(issue, r), markdown)
8492
}
8593

86-
override def reopened(issue: Issue, r: RepositoryInfo)(implicit context: Context): Unit = {
87-
Notifier().toNotify(
88-
subject(issue, r),
89-
message("reopen", r)(content => s"""
90-
|$content <a href="${s"${context.baseUrl}/${r.owner}/${r.name}/issues/${issue.issueId}"}">#${issue.issueId}</a>
91-
""".stripMargin)
92-
)(recipients(issue))
94+
override def reopened(issue: Issue, r: RepositoryInfo)(implicit session: Session, context: Context): Unit = {
95+
val markdown =
96+
s"""|reopen #[${issue.issueId}](${s"${context.baseUrl}/${r.owner}/${r.name}/issues/${issue.issueId}"})
97+
|""".stripMargin
98+
99+
sendAsync(issue, r, subject(issue, r), markdown)
93100
}
94101

95102

96-
protected def subject(issue: Issue, r: RepositoryInfo): String = s"[${r.owner}/${r.name}] ${issue.title} (#${issue.issueId})"
103+
protected def subject(issue: Issue, r: RepositoryInfo): String = {
104+
s"[${r.owner}/${r.name}] ${issue.title} (#${issue.issueId})"
105+
}
97106

98-
protected def message(content: String, r: RepositoryInfo)(msg: String => String)(implicit context: Context): String =
99-
msg(Markdown.toHtml(
100-
markdown = content,
107+
protected def toHtml(markdown: String, r: RepositoryInfo)(implicit context: Context): String =
108+
Markdown.toHtml(
109+
markdown = markdown,
101110
repository = r,
102111
enableWikiLink = false,
103112
enableRefsLink = true,
104113
enableAnchor = false,
105114
enableLineBreaks = false
106-
))
107-
108-
protected val recipients: Issue => Account => Session => Seq[String] = {
109-
issue => loginAccount => implicit session =>
110-
getNotificationUsers(issue)
111-
.withFilter ( _ != loginAccount.userName ) // the operation in person is excluded
112-
.flatMap (
113-
getAccountByUserName(_)
114-
.filterNot (_.isGroupAccount)
115-
.filterNot (LDAPUtil.isDummyMailAddress)
116-
.filterNot (isDisableEmailNotification)
117-
.map (_.mailAddress)
118-
)
115+
)
116+
117+
protected def sendAsync(issue: Issue, repository: RepositoryInfo, subject: String, markdown: String)
118+
(implicit session: Session, context: Context): Unit = {
119+
val recipients = getRecipients(issue, context.loginAccount.get)
120+
val mailer = new Mailer(context.settings)
121+
val f = Future {
122+
recipients.foreach { address =>
123+
mailer.send(address, subject, markdown, Some(toHtml(markdown, repository)), context.loginAccount)
124+
}
125+
"Notifications Successful."
126+
}
127+
f.onComplete {
128+
case Success(s) => logger.debug(s)
129+
case Failure(t) => logger.error("Notifications Failed.", t)
130+
}
131+
}
132+
133+
protected def getRecipients(issue: Issue, loginAccount: Account)(implicit session: Session): Seq[String] = {
134+
getNotificationUsers(issue)
135+
.withFilter ( _ != loginAccount.userName ) // the operation in person is excluded
136+
.flatMap (
137+
getAccountByUserName(_)
138+
.filterNot (_.isGroupAccount)
139+
.filterNot (LDAPUtil.isDummyMailAddress)
140+
.filterNot (isDisableEmailNotification)
141+
.map (_.mailAddress)
142+
)
119143
}
120144

121145
}
122146

123147
class PullRequestHook extends IssueHook with gitbucket.core.plugin.PullRequestHook {
124148

125-
override def created(issue: Issue, r: RepositoryInfo)(implicit context: Context): Unit = {
126-
val url = s"${context.baseUrl}/${r.owner}/${r.name}/pull/${issue.issueId}"
127-
Notifier().toNotify(
128-
subject(issue, r),
129-
message(issue.content getOrElse "", r)(content => s"""
130-
|$content<hr/>
131-
|View, comment on, or merge it at:<br/>
132-
|<a href="$url">$url</a>
133-
""".stripMargin)
134-
)(recipients(issue))
149+
override def created(issue: Issue, r: RepositoryInfo)(implicit session: Session, context: Context): Unit = {
150+
val markdown =
151+
s"""|${issue.content getOrElse ""}
152+
|
153+
|----
154+
|View, comment on, or merge it at:
155+
|${context.baseUrl}/${r.owner}/${r.name}/pull/${issue.issueId}
156+
|""".stripMargin
157+
158+
sendAsync(issue, r, subject(issue, r), markdown)
135159
}
136160

137-
override def addedComment(commentId: Int, content: String, issue: Issue, r: RepositoryInfo)(implicit context: Context): Unit = {
138-
Notifier().toNotify(
139-
subject(issue, r),
140-
message(content, r)(content => s"""
141-
|$content<br/>
142-
|--<br/>
143-
|<a href="${s"${context.baseUrl}/${r.owner}/${r.name}/pull/${issue.issueId}#comment-$commentId"}">View it on GitBucket</a>
144-
""".stripMargin)
145-
)(recipients(issue))
161+
override def addedComment(commentId: Int, content: String, issue: Issue, r: RepositoryInfo)
162+
(implicit session: Session, context: Context): Unit = {
163+
val markdown =
164+
s"""|$content
165+
|
166+
|----
167+
|[View it on GitBucket](${s"${context.baseUrl}/${r.owner}/${r.name}/pull/${issue.issueId}#comment-$commentId"})
168+
|""".stripMargin
169+
170+
sendAsync(issue, r, subject(issue, r), markdown)
146171
}
147172

148-
override def merged(issue: Issue, r: RepositoryInfo)(implicit context: Context): Unit = {
149-
Notifier().toNotify(
150-
subject(issue, r),
151-
message("merge", r)(content => s"""
152-
|$content <a href="${s"${context.baseUrl}/${r.owner}/${r.name}/pull/${issue.issueId}"}">#${issue.issueId}</a>
153-
""".stripMargin)
154-
)(recipients(issue))
173+
override def merged(issue: Issue, r: RepositoryInfo)(implicit session: Session, context: Context): Unit = {
174+
val markdown =
175+
s"""|merge #[${issue.issueId}](${s"${context.baseUrl}/${r.owner}/${r.name}/pull/${issue.issueId}"})
176+
|""".stripMargin
177+
178+
sendAsync(issue, r, subject(issue, r), markdown)
155179
}
156180

157181
}

0 commit comments

Comments
 (0)