From 3a2c57e652e5b688261fee02baa3853526e9893a Mon Sep 17 00:00:00 2001
From: James Moger <james.moger@gitblit.com>
Date: Sat, 17 Dec 2011 15:17:46 -0500
Subject: [PATCH] Edit and store per-repository mail recipients in site and RPC

---
 src/com/gitblit/GitBlit.java                         |   14 ++++++-
 src/com/gitblit/wicket/GitBlitWebApp.properties      |    4 +
 src/com/gitblit/wicket/pages/EditRepositoryPage.java |   19 ++++++++-
 src/com/gitblit/models/RepositoryModel.java          |    1 
 src/com/gitblit/MailExecutor.java                    |   11 ++++-
 src/com/gitblit/client/EditRepositoryDialog.java     |    9 ++++
 src/com/gitblit/wicket/pages/EditRepositoryPage.html |    7 ++-
 7 files changed, 52 insertions(+), 13 deletions(-)

diff --git a/src/com/gitblit/GitBlit.java b/src/com/gitblit/GitBlit.java
index 2719734..8afa6df 100644
--- a/src/com/gitblit/GitBlit.java
+++ b/src/com/gitblit/GitBlit.java
@@ -731,6 +731,8 @@
 					"gitblit", null, "preReceiveScript")));
 			model.postReceiveScripts = new ArrayList<String>(Arrays.asList(config.getStringList(
 					"gitblit", null, "postReceiveScript")));
+			model.mailRecipients = new ArrayList<String>(Arrays.asList(config.getStringList(
+					"gitblit", null, "mailRecipient")));
 		}
 		r.close();
 		return model;
@@ -950,8 +952,16 @@
 		config.setString("gitblit", null, "federationStrategy",
 				repository.federationStrategy.name());
 		config.setBoolean("gitblit", null, "isFederated", repository.isFederated);
-		config.setStringList("gitblit", null, "preReceiveScript", repository.preReceiveScripts);
-		config.setStringList("gitblit", null, "postReceiveScript", repository.postReceiveScripts);
+		if (repository.preReceiveScripts != null) {
+			config.setStringList("gitblit", null, "preReceiveScript", repository.preReceiveScripts);
+		}
+		if (repository.postReceiveScripts != null) {
+			config.setStringList("gitblit", null, "postReceiveScript",
+					repository.postReceiveScripts);
+		}
+		if (repository.mailRecipients != null) {
+			config.setStringList("gitblit", null, "mailRecipient", repository.mailRecipients);
+		}
 		try {
 			config.save();
 		} catch (IOException e) {
diff --git a/src/com/gitblit/MailExecutor.java b/src/com/gitblit/MailExecutor.java
index 56a4ab5..77dc80b 100644
--- a/src/com/gitblit/MailExecutor.java
+++ b/src/com/gitblit/MailExecutor.java
@@ -154,7 +154,12 @@
 			InternetAddress from = new InternetAddress(fromAddress, "Gitblit");
 			message.setFrom(from);
 
-			Set<String> uniques = new HashSet<String>(toAddresses);
+			// determine unique set of addresses
+			Set<String> uniques = new HashSet<String>();
+			for (String address : toAddresses) {
+				uniques.add(address.toLowerCase());
+			}
+			
 			Pattern validEmail = Pattern
 					.compile("^([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$");
 			List<InternetAddress> tos = new ArrayList<InternetAddress>();
@@ -168,8 +173,8 @@
 					} catch (Throwable t) {
 					}
 				}
-			}
-			message.setRecipients(Message.RecipientType.TO,
+			}			
+			message.setRecipients(Message.RecipientType.BCC,
 					tos.toArray(new InternetAddress[tos.size()]));
 			message.setSentDate(new Date());
 		} catch (Exception e) {
diff --git a/src/com/gitblit/client/EditRepositoryDialog.java b/src/com/gitblit/client/EditRepositoryDialog.java
index 0b6ef59..a70a617 100644
--- a/src/com/gitblit/client/EditRepositoryDialog.java
+++ b/src/com/gitblit/client/EditRepositoryDialog.java
@@ -52,7 +52,6 @@
 import com.gitblit.Constants.AccessRestrictionType;
 import com.gitblit.Constants.FederationStrategy;
 import com.gitblit.models.RepositoryModel;
-import com.gitblit.models.TeamModel;
 import com.gitblit.utils.StringUtils;
 
 /**
@@ -89,6 +88,8 @@
 	private JCheckBox skipSummaryMetrics;
 
 	private JCheckBox isFrozen;
+	
+	private JTextField mailRecipientsField;
 
 	private JComboBox accessRestriction;
 
@@ -159,6 +160,9 @@
 				anRepository.skipSummaryMetrics);
 		isFrozen = new JCheckBox(Translation.get("gb.isFrozenDescription"), anRepository.isFrozen);
 
+		mailRecipientsField = new JTextField(anRepository.mailRecipients == null ? ""
+				: StringUtils.flattenStrings(anRepository.mailRecipients, " "), 50);
+		
 		accessRestriction = new JComboBox(AccessRestrictionType.values());
 		accessRestriction.setRenderer(new AccessRestrictionRenderer());
 		accessRestriction.setSelectedItem(anRepository.accessRestriction);
@@ -190,6 +194,7 @@
 		fieldsPanel
 				.add(newFieldPanel(Translation.get("gb.skipSummaryMetrics"), skipSummaryMetrics));
 		fieldsPanel.add(newFieldPanel(Translation.get("gb.isFrozen"), isFrozen));
+		fieldsPanel.add(newFieldPanel(Translation.get("gb.mailRecipients"), mailRecipientsField));
 
 		usersPalette = new JPalette<String>();
 		JPanel accessPanel = new JPanel(new BorderLayout(5, 5));
@@ -347,6 +352,8 @@
 		repository.skipSizeCalculation = skipSizeCalculation.isSelected();
 		repository.skipSummaryMetrics = skipSummaryMetrics.isSelected();
 		repository.isFrozen = isFrozen.isSelected();
+		
+		repository.mailRecipients = StringUtils.getStringsFromValue(mailRecipientsField.getText().trim(), " ");
 
 		repository.accessRestriction = (AccessRestrictionType) accessRestriction.getSelectedItem();
 		repository.federationStrategy = (FederationStrategy) federationStrategy.getSelectedItem();
diff --git a/src/com/gitblit/models/RepositoryModel.java b/src/com/gitblit/models/RepositoryModel.java
index c5423f0..fc1de8a 100644
--- a/src/com/gitblit/models/RepositoryModel.java
+++ b/src/com/gitblit/models/RepositoryModel.java
@@ -57,6 +57,7 @@
 	public String size;
 	public List<String> preReceiveScripts;
 	public List<String> postReceiveScripts;
+	public List<String> mailRecipients;
 
 	public RepositoryModel() {
 		this("", "", "", new Date(0));
diff --git a/src/com/gitblit/wicket/GitBlitWebApp.properties b/src/com/gitblit/wicket/GitBlitWebApp.properties
index c9afbc9..181aed9 100644
--- a/src/com/gitblit/wicket/GitBlitWebApp.properties
+++ b/src/com/gitblit/wicket/GitBlitWebApp.properties
@@ -195,4 +195,6 @@
 gb.newTeam = new team
 gb.permittedTeams = permitted teams
 gb.emptyRepository = empty repository
-gb.repositoryUrl = repository url
\ No newline at end of file
+gb.repositoryUrl = repository url
+gb.mailRecipients = mail recipients
+gb.mailRecipientsDescription = space-delimited, used by sendemail Groovy hook
\ No newline at end of file
diff --git a/src/com/gitblit/wicket/pages/EditRepositoryPage.html b/src/com/gitblit/wicket/pages/EditRepositoryPage.html
index 9e22189..43e42ac 100644
--- a/src/com/gitblit/wicket/pages/EditRepositoryPage.html
+++ b/src/com/gitblit/wicket/pages/EditRepositoryPage.html
@@ -21,14 +21,15 @@
 				<tr><th><wicket:message key="gb.skipSizeCalculation"></wicket:message></th><td class="edit"><input type="checkbox" wicket:id="skipSizeCalculation" tabindex="9" /> &nbsp;<i><wicket:message key="gb.skipSizeCalculationDescription"></wicket:message></i></td></tr>
 				<tr><th><wicket:message key="gb.skipSummaryMetrics"></wicket:message></th><td class="edit"><input type="checkbox" wicket:id="skipSummaryMetrics" tabindex="10" /> &nbsp;<i><wicket:message key="gb.skipSummaryMetricsDescription"></wicket:message></i></td></tr>
 				<tr><th><wicket:message key="gb.isFrozen"></wicket:message></th><td class="edit"><input type="checkbox" wicket:id="isFrozen" tabindex="11" /> &nbsp;<i><wicket:message key="gb.isFrozenDescription"></wicket:message></i></td></tr>
+				<tr><th><wicket:message key="gb.mailRecipients"></wicket:message></th><td class="edit"><input class="span9" type="text" wicket:id="mailRecipients" size="40" tabindex="12" /> &nbsp;<i><wicket:message key="gb.mailRecipientsDescription"></wicket:message></i></td></tr>
 				<tr><td colspan="2"><hr></hr></td></tr>
-				<tr><th><wicket:message key="gb.accessRestriction"></wicket:message></th><td class="edit"><select class="span6" wicket:id="accessRestriction" tabindex="12" /></td></tr>				
+				<tr><th><wicket:message key="gb.accessRestriction"></wicket:message></th><td class="edit"><select class="span6" wicket:id="accessRestriction" tabindex="13" /></td></tr>				
 				<tr><th style="vertical-align: top;"><wicket:message key="gb.permittedUsers"></wicket:message></th><td style="padding:2px;"><span wicket:id="users"></span></td></tr>
 				<tr><th style="vertical-align: top;"><wicket:message key="gb.permittedTeams"></wicket:message></th><td style="padding:2px;"><span wicket:id="teams"></span></td></tr>
 				<tr><td colspan="2"><hr></hr></td></tr>		
-				<tr><th><wicket:message key="gb.federationStrategy"></wicket:message></th><td class="edit"><select class="span6" wicket:id="federationStrategy" tabindex="13" /></td></tr>
+				<tr><th><wicket:message key="gb.federationStrategy"></wicket:message></th><td class="edit"><select class="span6" wicket:id="federationStrategy" tabindex="14" /></td></tr>
 				<tr><th style="vertical-align: top;"><wicket:message key="gb.federationSets"></wicket:message></th><td style="padding:2px;"><span wicket:id="federationSets"></span></td></tr>
-				<tr><th></th><td class="editButton"><input class="btn" type="submit" value="Cancel" wicket:message="value:gb.cancel" wicket:id="cancel" tabindex="14" /> &nbsp; <input class="btn primary" type="submit" value="Save" wicket:message="value:gb.save" wicket:id="save" tabindex="15" /> </td></tr>
+				<tr><th></th><td class="editButton"><input class="btn" type="submit" value="Cancel" wicket:message="value:gb.cancel" wicket:id="cancel" tabindex="15" /> &nbsp; <input class="btn primary" type="submit" value="Save" wicket:message="value:gb.save" wicket:id="save" tabindex="16" /> </td></tr>
 			</tbody>
 		</table>
 	</form>	
diff --git a/src/com/gitblit/wicket/pages/EditRepositoryPage.java b/src/com/gitblit/wicket/pages/EditRepositoryPage.java
index 1a5ec3d..56e44f8 100644
--- a/src/com/gitblit/wicket/pages/EditRepositoryPage.java
+++ b/src/com/gitblit/wicket/pages/EditRepositoryPage.java
@@ -33,6 +33,8 @@
 import org.apache.wicket.markup.html.form.IChoiceRenderer;
 import org.apache.wicket.markup.html.form.TextField;
 import org.apache.wicket.model.CompoundPropertyModel;
+import org.apache.wicket.model.IModel;
+import org.apache.wicket.model.Model;
 import org.apache.wicket.model.util.CollectionModel;
 import org.apache.wicket.model.util.ListModel;
 
@@ -52,6 +54,8 @@
 	private final boolean isCreate;
 
 	private boolean isAdmin;
+
+	private IModel<String> mailRecipients;
 
 	public EditRepositoryPage() {
 		// create constructor
@@ -86,8 +90,7 @@
 				Collections.sort(repositoryUsers);
 			}
 			federationSets.addAll(repositoryModel.federationSets);
-		}		
-		
+		}
 
 		final String oldName = repositoryModel.name;
 		// users palette
@@ -169,6 +172,13 @@
 						}
 					}
 
+					// set mail recipients
+					String ml = mailRecipients.getObject();
+					if (!StringUtils.isEmpty(ml)) {
+						List<String> list = StringUtils.getStringsFromValue(ml.trim(), " ");
+						repositoryModel.mailRecipients = list;
+					}
+
 					// save the repository
 					GitBlit.self().updateRepositoryModel(oldName, repositoryModel, isCreate);
 
@@ -186,7 +196,7 @@
 							repositoryUsers.add(repositoryModel.owner);
 						}
 						GitBlit.self().setRepositoryUsers(repositoryModel, repositoryUsers);
-						
+
 						// save the team access list
 						Iterator<String> teams = teamsPalette.getSelectedChoices();
 						List<String> repositoryTeams = new ArrayList<String>();
@@ -230,6 +240,9 @@
 		form.add(new CheckBox("showReadme"));
 		form.add(new CheckBox("skipSizeCalculation"));
 		form.add(new CheckBox("skipSummaryMetrics"));
+		mailRecipients = new Model<String>(repositoryModel.mailRecipients == null ? ""
+				: StringUtils.flattenStrings(repositoryModel.mailRecipients, " "));
+		form.add(new TextField<String>("mailRecipients", mailRecipients));
 		form.add(usersPalette);
 		form.add(teamsPalette);
 		form.add(federationSetsPalette);

--
Gitblit v1.9.1