From cb57ec6ca96a6da2f5ae697070f3e52d8f940578 Mon Sep 17 00:00:00 2001
From: James Moger <james.moger@gitblit.com>
Date: Thu, 22 Dec 2011 18:10:44 -0500
Subject: [PATCH] Filtering repositories and activity pages via url parameters (issue 27)

---
 src/com/gitblit/wicket/WicketUtils.java              |    8 ++
 src/com/gitblit/wicket/pages/RepositoriesPage.java   |   24 ++++-
 docs/04_releases.mkd                                 |    8 +
 src/com/gitblit/wicket/pages/RootPage.java           |   82 ++++++++++++++++++++
 src/com/gitblit/wicket/panels/RepositoriesPanel.java |   12 --
 src/com/gitblit/wicket/pages/ReviewProposalPage.java |    2 
 src/com/gitblit/wicket/pages/SendProposalPage.java   |    2 
 src/com/gitblit/wicket/pages/ActivityPage.java       |   43 ----------
 8 files changed, 120 insertions(+), 61 deletions(-)

diff --git a/docs/04_releases.mkd b/docs/04_releases.mkd
index 3e49c18..ea8ff72 100644
--- a/docs/04_releases.mkd
+++ b/docs/04_releases.mkd
@@ -29,7 +29,13 @@
 - fixed: several a bugs in FileUserService related to cleaning up old repository permissions on a rename or delete
 - added: optional flash-based 1-step *copy to clipboard* of the primary repository url
 - added: javascript-based 3-step (click, ctrl+c, enter) *copy to clipboard* of the primary repository url  
-   **New:** *web.allowFlashCopyToClipboard = true*  
+   **New:** *web.allowFlashCopyToClipboard = true*
+- added: Name, regex, set, and team filtering of the repositories list and the activity page via url parameters (issue 27)  
+    Here are some url examples:  
+    localhost/gb?r=myrepo.git  *(specific repository)*  
+    localhost/gb?x=my  *(regex matching. encoding may be an issue. YMMV)*  
+    localhost/gb?set=animal,mineral  *(animal and mineral federation sets)*  
+    localhost/qb/activity?team=qa,qa2 *(qa and qa2 teams)*
 - improved: empty repositories now link to a new *empty repository* page which gives some direction to the user for the next step in using Gitblit.  This page displays the primary push/clone url of the repository and gives sample syntax for the git command-line client. (issue 31)
 - improved: unit testing framework has been migrated to JUnit4 syntax and the test suite has been redesigned to run all unit tests, including rpc, federation, and git push/clone tests
 
diff --git a/src/com/gitblit/wicket/WicketUtils.java b/src/com/gitblit/wicket/WicketUtils.java
index dbeb47f..59a9450 100644
--- a/src/com/gitblit/wicket/WicketUtils.java
+++ b/src/com/gitblit/wicket/WicketUtils.java
@@ -369,10 +369,18 @@
 		return params.getInt("pg", 1);
 	}
 
+	public static String getRegEx(PageParameters params) {
+		return params.getString("x", "");
+	}
+
 	public static String getSet(PageParameters params) {
 		return params.getString("set", "");
 	}
 
+	public static String getTeam(PageParameters params) {
+		return params.getString("team", "");
+	}
+
 	public static int getDaysBack(PageParameters params) {
 		return params.getInt("db", 14);
 	}
diff --git a/src/com/gitblit/wicket/pages/ActivityPage.java b/src/com/gitblit/wicket/pages/ActivityPage.java
index 011eef1..e8a172e 100644
--- a/src/com/gitblit/wicket/pages/ActivityPage.java
+++ b/src/com/gitblit/wicket/pages/ActivityPage.java
@@ -17,7 +17,6 @@
 
 import java.text.MessageFormat;
 import java.text.SimpleDateFormat;
-import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -29,14 +28,10 @@
 import org.apache.wicket.behavior.HeaderContributor;
 import org.apache.wicket.markup.html.basic.Label;
 
-import com.gitblit.GitBlit;
 import com.gitblit.models.Activity;
 import com.gitblit.models.Metric;
 import com.gitblit.models.RepositoryModel;
-import com.gitblit.models.UserModel;
 import com.gitblit.utils.ActivityUtils;
-import com.gitblit.utils.StringUtils;
-import com.gitblit.wicket.GitBlitWebSession;
 import com.gitblit.wicket.WicketUtils;
 import com.gitblit.wicket.charting.GoogleChart;
 import com.gitblit.wicket.charting.GoogleCharts;
@@ -54,7 +49,7 @@
 public class ActivityPage extends RootPage {
 
 	public ActivityPage(PageParameters params) {
-		super();
+		super(params);
 		setupPage("", "");
 
 		// parameters
@@ -94,42 +89,6 @@
 			// add activity panel
 			add(new ActivityPanel("activityPanel", recentActivity));
 		}
-	}
-
-	private List<RepositoryModel> getRepositories(PageParameters params) {
-		final UserModel user = GitBlitWebSession.get().getUser();
-		String set = WicketUtils.getSet(params);
-		String repositoryName = WicketUtils.getRepositoryName(params);
-
-		List<RepositoryModel> models = null;
-		if (!StringUtils.isEmpty(repositoryName)) {
-			// named repository
-			models = new ArrayList<RepositoryModel>();
-			RepositoryModel model = GitBlit.self().getRepositoryModel(repositoryName);
-			if (user.canAccessRepository(model)) {
-				models.add(model);
-			}
-		}
-
-		// get all user accessible repositories
-		if (models == null) {
-			models = GitBlit.self().getRepositoryModels(user);
-		}
-
-		// filter the repositories by the specified set
-		if (!StringUtils.isEmpty(set)) {
-			List<String> sets = StringUtils.getStringsFromValue(set, ",");
-			List<RepositoryModel> setModels = new ArrayList<RepositoryModel>();
-			for (RepositoryModel model : models) {
-				for (String curr : sets) {
-					if (model.federationSets.contains(curr)) {
-						setModels.add(model);
-					}
-				}
-			}
-			models = setModels;
-		}
-		return models;
 	}
 
 	/**
diff --git a/src/com/gitblit/wicket/pages/RepositoriesPage.java b/src/com/gitblit/wicket/pages/RepositoriesPage.java
index d5a21a7..a15a7d9 100644
--- a/src/com/gitblit/wicket/pages/RepositoriesPage.java
+++ b/src/com/gitblit/wicket/pages/RepositoriesPage.java
@@ -20,13 +20,16 @@
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.text.MessageFormat;
+import java.util.List;
 
 import org.apache.wicket.Component;
+import org.apache.wicket.PageParameters;
 import org.apache.wicket.markup.html.basic.Label;
 import org.apache.wicket.resource.ContextRelativeResource;
 
 import com.gitblit.GitBlit;
 import com.gitblit.Keys;
+import com.gitblit.models.RepositoryModel;
 import com.gitblit.utils.MarkdownUtils;
 import com.gitblit.utils.StringUtils;
 import com.gitblit.wicket.GitBlitWebSession;
@@ -37,8 +40,16 @@
 
 	public RepositoriesPage() {
 		super();
-		setupPage("", "");
+		setup(null);
+	}
 
+	public RepositoriesPage(PageParameters params) {
+		super(params);
+		setup(params);
+	}
+
+	private void setup(PageParameters params) {
+		setupPage("", "");
 		// check to see if we should display a login message
 		boolean authenticateView = GitBlit.getBoolean(Keys.web.authenticateViewPages, true);
 		if (authenticateView && !GitBlitWebSession.get().isLoggedIn()) {
@@ -56,14 +67,17 @@
 		Component repositoriesMessage = new Label("repositoriesMessage", message)
 				.setEscapeModelStrings(false).setVisible(message.length() > 0);
 		add(repositoriesMessage);
-		RepositoriesPanel repositories = new RepositoriesPanel("repositoriesPanel", showAdmin,
-				null, getAccessRestrictions());
+
+		List<RepositoryModel> repositories = getRepositories(params);
+
+		RepositoriesPanel repositoriesPanel = new RepositoriesPanel("repositoriesPanel", showAdmin,
+				repositories, true, getAccessRestrictions());
 		// push the panel down if we are hiding the admin controls and the
 		// welcome message
 		if (!showAdmin && !repositoriesMessage.isVisible()) {
-			WicketUtils.setCssStyle(repositories, "padding-top:5px;");
+			WicketUtils.setCssStyle(repositoriesPanel, "padding-top:5px;");
 		}
-		add(repositories);
+		add(repositoriesPanel);
 	}
 
 	private String readMarkdown(String messageSource, String resource) {
diff --git a/src/com/gitblit/wicket/pages/ReviewProposalPage.java b/src/com/gitblit/wicket/pages/ReviewProposalPage.java
index 1d9092a..2b095f9 100644
--- a/src/com/gitblit/wicket/pages/ReviewProposalPage.java
+++ b/src/com/gitblit/wicket/pages/ReviewProposalPage.java
@@ -92,7 +92,7 @@
 		List<RepositoryModel> repositories = new ArrayList<RepositoryModel>(
 				proposal.repositories.values());
 		RepositoriesPanel repositoriesPanel = new RepositoriesPanel("repositoriesPanel", false,
-				repositories, getAccessRestrictions());
+				repositories, false, getAccessRestrictions());
 		add(repositoriesPanel);
 	}
 
diff --git a/src/com/gitblit/wicket/pages/RootPage.java b/src/com/gitblit/wicket/pages/RootPage.java
index 06ab298..a907c73 100644
--- a/src/com/gitblit/wicket/pages/RootPage.java
+++ b/src/com/gitblit/wicket/pages/RootPage.java
@@ -18,6 +18,7 @@
 import java.text.MessageFormat;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.regex.Pattern;
 
 import org.apache.wicket.PageParameters;
 import org.apache.wicket.markup.html.form.PasswordTextField;
@@ -30,6 +31,8 @@
 import com.gitblit.Constants;
 import com.gitblit.GitBlit;
 import com.gitblit.Keys;
+import com.gitblit.models.RepositoryModel;
+import com.gitblit.models.TeamModel;
 import com.gitblit.models.UserModel;
 import com.gitblit.utils.StringUtils;
 import com.gitblit.wicket.GitBlitWebSession;
@@ -88,7 +91,7 @@
 		}
 		if (showAdmin || showRegistrations) {
 			pages.add(new PageRegistration("gb.federation", FederationPage.class));
-		}		
+		}
 		NavigationPanel navPanel = new NavigationPanel("navPanel", getClass(), pages);
 		add(navPanel);
 
@@ -163,4 +166,81 @@
 			}
 		}
 	}
+
+	protected List<RepositoryModel> getRepositories(PageParameters params) {
+		final UserModel user = GitBlitWebSession.get().getUser();
+		if (params == null) {
+			return GitBlit.self().getRepositoryModels(user);
+		}
+
+		String repositoryName = WicketUtils.getRepositoryName(params);
+		String set = WicketUtils.getSet(params);
+		String regex = WicketUtils.getRegEx(params);
+		String team = WicketUtils.getTeam(params);
+
+		List<RepositoryModel> models = null;
+
+		if (!StringUtils.isEmpty(repositoryName)) {
+			// try named repository
+			models = new ArrayList<RepositoryModel>();
+			RepositoryModel model = GitBlit.self().getRepositoryModel(repositoryName);
+			if (user.canAccessRepository(model)) {
+				models.add(model);
+			}
+		}
+
+		// get all user accessible repositories
+		if (models == null) {
+			models = GitBlit.self().getRepositoryModels(user);
+		}
+
+		if (!StringUtils.isEmpty(regex)) {
+			// filter the repositories by the regex
+			List<RepositoryModel> accessible = GitBlit.self().getRepositoryModels(user);
+			List<RepositoryModel> matchingModels = new ArrayList<RepositoryModel>();
+			Pattern pattern = Pattern.compile(regex);
+			for (RepositoryModel aModel : accessible) {
+				if (pattern.matcher(aModel.name).find()) {
+					matchingModels.add(aModel);
+				}
+			}
+			models = matchingModels;
+		} else if (!StringUtils.isEmpty(set)) {
+			// filter the repositories by the specified sets
+			List<String> sets = StringUtils.getStringsFromValue(set, ",");
+			List<RepositoryModel> matchingModels = new ArrayList<RepositoryModel>();
+			for (RepositoryModel model : models) {
+				for (String curr : sets) {
+					if (model.federationSets.contains(curr)) {
+						matchingModels.add(model);
+					}
+				}
+			}
+			models = matchingModels;
+		} else if (!StringUtils.isEmpty(team)) {
+			// filter the repositories by the specified teams
+			List<String> teams = StringUtils.getStringsFromValue(team, ",");
+			
+			// need TeamModels first
+			List<TeamModel> teamModels = new ArrayList<TeamModel>();
+			for (String name : teams) {
+				TeamModel model = GitBlit.self().getTeamModel(name);
+				if (model != null) {
+					teamModels.add(model);
+				}
+			}
+			
+			// brute-force our way through finding the matching models
+			List<RepositoryModel> matchingModels = new ArrayList<RepositoryModel>();
+			for (RepositoryModel repositoryModel : models) {
+				for (TeamModel teamModel : teamModels) {
+					if (teamModel.hasRepository(repositoryModel.name)) {
+						matchingModels.add(repositoryModel);
+					}
+				}
+			}
+			models = matchingModels;
+		}
+		return models;
+	}
 }
diff --git a/src/com/gitblit/wicket/pages/SendProposalPage.java b/src/com/gitblit/wicket/pages/SendProposalPage.java
index ed20049..a7fcadc 100644
--- a/src/com/gitblit/wicket/pages/SendProposalPage.java
+++ b/src/com/gitblit/wicket/pages/SendProposalPage.java
@@ -149,7 +149,7 @@
 		List<RepositoryModel> repositories = new ArrayList<RepositoryModel>(
 				proposal.repositories.values());
 		RepositoriesPanel repositoriesPanel = new RepositoriesPanel("repositoriesPanel", false,
-				repositories, getAccessRestrictions());
+				repositories, false, getAccessRestrictions());
 		add(repositoriesPanel);
 	}
 }
diff --git a/src/com/gitblit/wicket/panels/RepositoriesPanel.java b/src/com/gitblit/wicket/panels/RepositoriesPanel.java
index 118ad6d..3a876bd 100644
--- a/src/com/gitblit/wicket/panels/RepositoriesPanel.java
+++ b/src/com/gitblit/wicket/panels/RepositoriesPanel.java
@@ -62,22 +62,14 @@
 	private static final long serialVersionUID = 1L;
 
 	public RepositoriesPanel(String wicketId, final boolean showAdmin,
-			List<RepositoryModel> models,
+			List<RepositoryModel> models, boolean enableLinks,
 			final Map<AccessRestrictionType, String> accessRestrictionTranslations) {
 		super(wicketId);
 
-		final boolean linksActive;
+		final boolean linksActive = enableLinks;
 		final boolean showSize = GitBlit.getBoolean(Keys.web.showRepositorySizes, true);
 
 		final UserModel user = GitBlitWebSession.get().getUser();
-		if (models == null) {
-			linksActive = true;
-			models = GitBlit.self().getRepositoryModels(user);
-		} else {
-			// disable links if the repositories are already provided
-			// the repositories are most likely from a proposal
-			linksActive = false;
-		}
 
 		final IDataProvider<RepositoryModel> dp;
 

--
Gitblit v1.9.1