
fixes logics splitting and sending notification emails with recipient limit value.
* Issue When `application.notification.bymail.hideAddress` is true, a default recipient is added to `to header`. But previous codes does not consider it so notification mails, `application.notification.bymail.recipientLimit` + 1, are sent. * Solution The changed codes decide amount of notification mails to be sent with `application.notification.bymail.recipientLimit` and recipients in `to header`. Private-issue: 2206
@3781a7369da66b7cf2dece9aec488da31657b6c9
+++ app/models/MailRecipient.java
... | ... | @@ -0,0 +1,40 @@ |
1 | +/** | |
2 | + * Yobi, Project Hosting SW | |
3 | + * | |
4 | + * Copyright 2015 NAVER Corp. | |
5 | + * http://yobi.io | |
6 | + * | |
7 | + * @Author Changsung Kim | |
8 | + * | |
9 | + * Licensed under the Apache License, Version 2.0 (the "License"); | |
10 | + * you may not use this file except in compliance with the License. | |
11 | + * You may obtain a copy of the License at | |
12 | + * | |
13 | + * http://www.apache.org/licenses/LICENSE-2.0 | |
14 | + * | |
15 | + * Unless required by applicable law or agreed to in writing, software | |
16 | + * distributed under the License is distributed on an "AS IS" BASIS, | |
17 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
18 | + * See the License for the specific language governing permissions and | |
19 | + * limitations under the License. | |
20 | + */ | |
21 | +package models; | |
22 | + | |
23 | +import javax.annotation.Nonnull; | |
24 | +import javax.annotation.Nullable; | |
25 | + | |
26 | +/** | |
27 | + * A model for mail recipients of notification mail. | |
28 | + */ | |
29 | +public class MailRecipient { | |
30 | + @Nonnull | |
31 | + final String email; | |
32 | + @Nullable | |
33 | + final String name; | |
34 | + | |
35 | + public MailRecipient(String email, String name) { | |
36 | + this.email = email; | |
37 | + this.name = name; | |
38 | + } | |
39 | + | |
40 | +} |
--- app/models/NotificationMail.java
+++ app/models/NotificationMail.java
... | ... | @@ -20,6 +20,7 @@ |
20 | 20 |
*/ |
21 | 21 |
package models; |
22 | 22 |
|
23 |
+import com.google.common.collect.Lists; |
|
23 | 24 |
import info.schleichardt.play2.mailplugin.Mailer; |
24 | 25 |
import mailbox.EmailAddressWithDetail; |
25 | 26 |
import models.enumeration.ResourceType; |
... | ... | @@ -238,6 +239,12 @@ |
238 | 239 |
return; |
239 | 240 |
} |
240 | 241 |
|
242 |
+ final int partialRecipientSize = getPartialRecipientSize(receivers); |
|
243 |
+ |
|
244 |
+ if (partialRecipientSize <= 0) { |
|
245 |
+ return; |
|
246 |
+ } |
|
247 |
+ |
|
241 | 248 |
HashMap<String, List<User>> usersByLang = new HashMap<>(); |
242 | 249 |
|
243 | 250 |
for (User receiver : receivers) { |
... | ... | @@ -251,24 +258,52 @@ |
251 | 258 |
} |
252 | 259 |
|
253 | 260 |
for (String langCode : usersByLang.keySet()) { |
254 |
- List<User> users = usersByLang.get(langCode); |
|
261 |
+ List<List<User>> subLists = Lists.partition(usersByLang.get(langCode), partialRecipientSize); |
|
255 | 262 |
|
256 |
- if (recipientLimit == RECIPIENT_NO_LIMIT) { |
|
257 |
- sendMail(event, users, langCode); |
|
258 |
- } else { |
|
259 |
- int usersSize = users.size(); |
|
260 |
- int fromIndex, toIndex = 0; |
|
261 |
- while (toIndex < usersSize) { |
|
262 |
- fromIndex = toIndex; |
|
263 |
- toIndex = Math.min(toIndex + recipientLimit, usersSize); |
|
264 |
- sendMail(event, users.subList(fromIndex, toIndex), langCode); |
|
265 |
- } |
|
263 |
+ for (List<User> list : subLists) { |
|
264 |
+ Set<MailRecipient> toList = getToList(list); |
|
265 |
+ Set<MailRecipient> bccList = getBccList(list); |
|
266 |
+ sendMail(event, toList, bccList, langCode); |
|
266 | 267 |
} |
267 | 268 |
} |
268 | 269 |
} |
269 | 270 |
|
270 |
- private static void sendMail(NotificationEvent event, List<User> receivers, String langCode) { |
|
271 |
- if (receivers.isEmpty()) { |
|
271 |
+ private static int getPartialRecipientSize(Set<User> receivers) { |
|
272 |
+ if (recipientLimit == RECIPIENT_NO_LIMIT) { |
|
273 |
+ return receivers.size(); |
|
274 |
+ } |
|
275 |
+ |
|
276 |
+ return (hideAddress) ? recipientLimit - getDefaultToList().size() : recipientLimit; |
|
277 |
+ } |
|
278 |
+ |
|
279 |
+ private static Set<MailRecipient> getToList(List<User> users) { |
|
280 |
+ return (hideAddress) ? getDefaultToList() : getMailRecipientsFromUsers(users); |
|
281 |
+ } |
|
282 |
+ |
|
283 |
+ private static Set<MailRecipient> getBccList(List<User> users) { |
|
284 |
+ return (hideAddress) ? getMailRecipientsFromUsers(users) : new HashSet<MailRecipient>(); |
|
285 |
+ } |
|
286 |
+ |
|
287 |
+ private static Set<MailRecipient> getDefaultToList() { |
|
288 |
+ Set<MailRecipient> list = new HashSet<>(); |
|
289 |
+ |
|
290 |
+ list.add(new MailRecipient(Config.getEmailFromSmtp(), Config.getSiteName())); |
|
291 |
+ |
|
292 |
+ return list; |
|
293 |
+ } |
|
294 |
+ |
|
295 |
+ private static Set<MailRecipient> getMailRecipientsFromUsers(List<User> users) { |
|
296 |
+ Set<MailRecipient> list = new HashSet<>(); |
|
297 |
+ |
|
298 |
+ for (User user : users) { |
|
299 |
+ list.add(new MailRecipient(user.email, user.name)); |
|
300 |
+ } |
|
301 |
+ |
|
302 |
+ return list; |
|
303 |
+ } |
|
304 |
+ |
|
305 |
+ private static void sendMail(NotificationEvent event, Set<MailRecipient> toList, Set<MailRecipient> bccList, String langCode) { |
|
306 |
+ if (toList.isEmpty()) { |
|
272 | 307 |
return; |
273 | 308 |
} |
274 | 309 |
|
... | ... | @@ -284,16 +319,12 @@ |
284 | 319 |
acceptsReply = true; |
285 | 320 |
} |
286 | 321 |
|
287 |
- for (User receiver : receivers) { |
|
288 |
- if (hideAddress) { |
|
289 |
- email.addBcc(receiver.email, receiver.name); |
|
290 |
- } else { |
|
291 |
- email.addTo(receiver.email, receiver.name); |
|
292 |
- } |
|
322 |
+ for (MailRecipient recipient : toList) { |
|
323 |
+ email.addTo(recipient.email, recipient.name); |
|
293 | 324 |
} |
294 | 325 |
|
295 |
- if (email.getToAddresses().isEmpty()) { |
|
296 |
- email.addTo(Config.getEmailFromSmtp(), utils.Config.getSiteName()); |
|
326 |
+ for (MailRecipient recipient : bccList) { |
|
327 |
+ email.addBcc(recipient.email, recipient.name); |
|
297 | 328 |
} |
298 | 329 |
|
299 | 330 |
// FIXME: gmail은 From과 To에 같은 주소가 있으면 reply-to를 무시한다. |
--- build.sbt
+++ build.sbt
... | ... | @@ -41,7 +41,8 @@ |
41 | 41 |
"org.jsoup" % "jsoup" % "1.7.2", |
42 | 42 |
"com.googlecode.juniversalchardet" % "juniversalchardet" % "1.0.3", |
43 | 43 |
"org.mockito" % "mockito-all" % "1.9.0" % "test", |
44 |
- "com.github.zafarkhaja" % "java-semver" % "0.7.2" |
|
44 |
+ "com.github.zafarkhaja" % "java-semver" % "0.7.2", |
|
45 |
+ "com.google.guava" % "guava" % "18.0" |
|
45 | 46 |
) |
46 | 47 |
|
47 | 48 |
val projectSettings = Seq( |
Add a comment
Delete comment
Once you delete this comment, you won't be able to recover it. Are you sure you want to delete this comment?