--- /dev/null
+/*\r
+ * Copyright 2011 gitblit.com.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package com.gitblit.models;\r
+\r
+import java.io.Serializable;\r
+import java.util.ArrayList;\r
+import java.util.Date;\r
+import java.util.HashMap;\r
+import java.util.List;\r
+import java.util.Map;\r
+\r
+import org.eclipse.jgit.lib.PersonIdent;\r
+import org.eclipse.jgit.revwalk.RevCommit;\r
+\r
+import com.gitblit.utils.TimeUtils;\r
+\r
+/**\r
+ * Model class to represent the commit activity across many repositories. This\r
+ * class is used by the Activity page.\r
+ * \r
+ * @author James Moger\r
+ */\r
+public class Activity implements Serializable, Comparable<Activity> {\r
+\r
+ private static final long serialVersionUID = 1L;\r
+\r
+ public final Date startDate;\r
+\r
+ public final Date endDate;\r
+\r
+ public final List<RepositoryCommit> commits;\r
+\r
+ private final Map<String, Metric> authorMetrics;\r
+\r
+ private final Map<String, Metric> repositoryMetrics;\r
+\r
+ /**\r
+ * Constructor for one day of activity.\r
+ * \r
+ * @param date\r
+ */\r
+ public Activity(Date date) {\r
+ this(date, TimeUtils.ONEDAY - 1);\r
+ }\r
+\r
+ /**\r
+ * Constructor for specified duration of activity from start date.\r
+ * \r
+ * @param date\r
+ * the start date of the activity\r
+ * @param duration\r
+ * the duration of the period in milliseconds\r
+ */\r
+ public Activity(Date date, long duration) {\r
+ startDate = date;\r
+ endDate = new Date(date.getTime() + duration);\r
+ commits = new ArrayList<RepositoryCommit>();\r
+ authorMetrics = new HashMap<String, Metric>();\r
+ repositoryMetrics = new HashMap<String, Metric>();\r
+ }\r
+\r
+ public RepositoryCommit addCommit(String repository, String branch, RevCommit commit) {\r
+ RepositoryCommit commitModel = new RepositoryCommit(repository, branch, commit);\r
+ commits.add(commitModel);\r
+\r
+ if (!repositoryMetrics.containsKey(repository)) {\r
+ repositoryMetrics.put(repository, new Metric(repository));\r
+ }\r
+ repositoryMetrics.get(repository).count++;\r
+\r
+ String author = commit.getAuthorIdent().getEmailAddress().toLowerCase();\r
+ if (!authorMetrics.containsKey(author)) {\r
+ authorMetrics.put(author, new Metric(author));\r
+ }\r
+ authorMetrics.get(author).count++;\r
+ return commitModel;\r
+ }\r
+\r
+ public Map<String, Metric> getAuthorMetrics() {\r
+ return authorMetrics;\r
+ }\r
+\r
+ public Map<String, Metric> getRepositoryMetrics() {\r
+ return repositoryMetrics;\r
+ }\r
+\r
+ @Override\r
+ public int compareTo(Activity o) {\r
+ // reverse chronological order\r
+ return o.startDate.compareTo(startDate);\r
+ }\r
+\r
+ /**\r
+ * Model class to represent a RevCommit, it's source repository, and the\r
+ * branch. This class is used by the activity page.\r
+ * \r
+ * @author James Moger\r
+ */\r
+ public static class RepositoryCommit implements Serializable, Comparable<RepositoryCommit> {\r
+\r
+ private static final long serialVersionUID = 1L;\r
+\r
+ public final String repository;\r
+\r
+ public final String branch;\r
+\r
+ private final RevCommit commit;\r
+\r
+ private List<RefModel> refs;\r
+\r
+ public RepositoryCommit(String repository, String branch, RevCommit commit) {\r
+ this.repository = repository;\r
+ this.branch = branch;\r
+ this.commit = commit;\r
+ }\r
+\r
+ public void setRefs(List<RefModel> refs) {\r
+ this.refs = refs;\r
+ }\r
+\r
+ public List<RefModel> getRefs() {\r
+ return refs;\r
+ }\r
+\r
+ public String getName() {\r
+ return commit.getName();\r
+ }\r
+\r
+ public String getShortName() {\r
+ return commit.getName().substring(0, 8);\r
+ }\r
+\r
+ public String getShortMessage() {\r
+ return commit.getShortMessage();\r
+ }\r
+\r
+ public int getParentCount() {\r
+ return commit.getParentCount();\r
+ }\r
+\r
+ public PersonIdent getAuthorIdent() {\r
+ return commit.getAuthorIdent();\r
+ }\r
+\r
+ @Override\r
+ public int compareTo(RepositoryCommit o) {\r
+ // reverse-chronological order\r
+ if (commit.getCommitTime() > o.commit.getCommitTime()) {\r
+ return -1;\r
+ } else if (commit.getCommitTime() < o.commit.getCommitTime()) {\r
+ return 1;\r
+ }\r
+ return 0;\r
+ }\r
+ }\r
+}\r
+++ /dev/null
-/*\r
- * Copyright 2011 gitblit.com.\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package com.gitblit.models;\r
-\r
-import java.io.Serializable;\r
-import java.util.ArrayList;\r
-import java.util.Date;\r
-import java.util.List;\r
-\r
-/**\r
- * Model class to represent the commit activity across many repositories. This\r
- * class is used by the Activity page.\r
- * \r
- * @author James Moger\r
- */\r
-public class DailyActivity implements Serializable, Comparable<DailyActivity> {\r
-\r
- private static final long serialVersionUID = 1L;\r
-\r
- public final Date date;\r
-\r
- public final List<RepositoryCommit> commits;\r
-\r
- public DailyActivity(Date date) {\r
- this.date = date;\r
- commits = new ArrayList<RepositoryCommit>();\r
- }\r
-\r
- @Override\r
- public int compareTo(DailyActivity o) {\r
- // reverse chronological order\r
- return o.date.compareTo(date);\r
- }\r
-}\r
+++ /dev/null
-/*\r
- * Copyright 2011 gitblit.com.\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package com.gitblit.models;\r
-\r
-import java.io.Serializable;\r
-import java.util.List;\r
-\r
-import org.eclipse.jgit.lib.PersonIdent;\r
-import org.eclipse.jgit.revwalk.RevCommit;\r
-\r
-/**\r
- * Model class to represent a RevCommit, it's source repository, and the branch.\r
- * This class is used by the activity page.\r
- * \r
- * @author James Moger\r
- */\r
-public class RepositoryCommit implements Serializable, Comparable<RepositoryCommit> {\r
-\r
- private static final long serialVersionUID = 1L;\r
-\r
- public final String repository;\r
-\r
- public final String branch;\r
-\r
- private final RevCommit commit;\r
-\r
- private List<RefModel> refs;\r
-\r
- public RepositoryCommit(String repository, String branch, RevCommit commit) {\r
- this.repository = repository;\r
- this.branch = branch;\r
- this.commit = commit;\r
- }\r
-\r
- public void setRefs(List<RefModel> refs) {\r
- this.refs = refs;\r
- }\r
-\r
- public List<RefModel> getRefs() {\r
- return refs;\r
- }\r
-\r
- public String getName() {\r
- return commit.getName();\r
- }\r
-\r
- public String getShortName() {\r
- return commit.getName().substring(0, 8);\r
- }\r
-\r
- public String getShortMessage() {\r
- return commit.getShortMessage();\r
- }\r
-\r
- public int getParentCount() {\r
- return commit.getParentCount();\r
- }\r
-\r
- public PersonIdent getAuthorIdent() {\r
- return commit.getAuthorIdent();\r
- }\r
-\r
- @Override\r
- public int compareTo(RepositoryCommit o) {\r
- // reverse-chronological order\r
- if (commit.getCommitTime() > o.commit.getCommitTime()) {\r
- return -1;\r
- } else if (commit.getCommitTime() < o.commit.getCommitTime()) {\r
- return 1;\r
- }\r
- return 0;\r
- }\r
-}
\ No newline at end of file
--- /dev/null
+/*\r
+ * Copyright 2011 gitblit.com.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package com.gitblit.utils;\r
+\r
+import java.text.DateFormat;\r
+import java.text.SimpleDateFormat;\r
+import java.util.ArrayList;\r
+import java.util.Calendar;\r
+import java.util.Collections;\r
+import java.util.Date;\r
+import java.util.HashMap;\r
+import java.util.List;\r
+import java.util.Map;\r
+\r
+import org.eclipse.jgit.lib.Constants;\r
+import org.eclipse.jgit.lib.ObjectId;\r
+import org.eclipse.jgit.lib.Repository;\r
+import org.eclipse.jgit.revwalk.RevCommit;\r
+\r
+import com.gitblit.GitBlit;\r
+import com.gitblit.models.Activity;\r
+import com.gitblit.models.Activity.RepositoryCommit;\r
+import com.gitblit.models.RefModel;\r
+import com.gitblit.models.RepositoryModel;\r
+\r
+/**\r
+ * Utility class for building activity information from repositories.\r
+ * \r
+ * @author James Moger\r
+ * \r
+ */\r
+public class ActivityUtils {\r
+\r
+ /**\r
+ * Gets the recent activity from the repositories for the last daysBack days\r
+ * on the specified branch.\r
+ * \r
+ * @param models\r
+ * the list of repositories to query\r
+ * @param daysBack\r
+ * the number of days back from Now to collect\r
+ * @param objectId\r
+ * the branch to retrieve. If this value is null the default\r
+ * branch of the repository is used.\r
+ * @return\r
+ */\r
+ public static List<Activity> getRecentActivity(List<RepositoryModel> models, int daysBack,\r
+ String objectId) {\r
+\r
+ // Activity panel shows last daysBack of activity across all\r
+ // repositories.\r
+ Date thresholdDate = new Date(System.currentTimeMillis() - daysBack * TimeUtils.ONEDAY);\r
+\r
+ // Build a map of DailyActivity from the available repositories for the\r
+ // specified threshold date.\r
+ DateFormat df = new SimpleDateFormat("yyyy-MM-dd");\r
+ Calendar cal = Calendar.getInstance();\r
+\r
+ Map<String, Activity> activity = new HashMap<String, Activity>();\r
+ for (RepositoryModel model : models) {\r
+ if (model.hasCommits && model.lastChange.after(thresholdDate)) {\r
+ Repository repository = GitBlit.self().getRepository(model.name);\r
+ List<RevCommit> commits = JGitUtils.getRevLog(repository, objectId, thresholdDate);\r
+ Map<ObjectId, List<RefModel>> allRefs = JGitUtils.getAllRefs(repository);\r
+ repository.close();\r
+\r
+ // determine commit branch\r
+ String branch = objectId;\r
+ if (StringUtils.isEmpty(branch)) {\r
+ List<RefModel> headRefs = allRefs.get(commits.get(0).getId());\r
+ List<String> localBranches = new ArrayList<String>();\r
+ for (RefModel ref : headRefs) {\r
+ if (ref.getName().startsWith(Constants.R_HEADS)) {\r
+ localBranches.add(ref.getName().substring(Constants.R_HEADS.length()));\r
+ }\r
+ }\r
+ // determine branch\r
+ if (localBranches.size() == 1) {\r
+ // only one branch, choose it\r
+ branch = localBranches.get(0);\r
+ } else if (localBranches.size() > 1) {\r
+ if (localBranches.contains("master")) {\r
+ // choose master\r
+ branch = "master";\r
+ } else {\r
+ // choose first branch\r
+ branch = localBranches.get(0);\r
+ }\r
+ }\r
+ }\r
+\r
+ for (RevCommit commit : commits) {\r
+ Date date = JGitUtils.getCommitDate(commit);\r
+ String dateStr = df.format(date);\r
+ if (!activity.containsKey(dateStr)) {\r
+ // Normalize the date to midnight\r
+ cal.setTime(date);\r
+ cal.set(Calendar.HOUR_OF_DAY, 0);\r
+ cal.set(Calendar.MINUTE, 0);\r
+ cal.set(Calendar.SECOND, 0);\r
+ cal.set(Calendar.MILLISECOND, 0);\r
+ activity.put(dateStr, new Activity(cal.getTime()));\r
+ }\r
+ RepositoryCommit commitModel = activity.get(dateStr).addCommit(model.name,\r
+ branch, commit);\r
+ commitModel.setRefs(allRefs.get(commit.getId()));\r
+ }\r
+ }\r
+ }\r
+\r
+ List<Activity> recentActivity = new ArrayList<Activity>(activity.values());\r
+ for (Activity daily : recentActivity) {\r
+ Collections.sort(daily.commits);\r
+ }\r
+ return recentActivity;\r
+ }\r
+}\r
gb.branch = branch\r
gb.maxHits = max hits\r
gb.recentActivity = recent activity\r
-gb.recentActivitySubheader = last {0} days / {1} commits by {2} authors\r
+gb.recentActivityStats = last {0} days / {1} commits by {2} authors\r
+gb.recentActivityNone = last {0} days / none\r
gb.dailyActivity = daily activity\r
gb.activeRepositories = active repositories\r
gb.activeAuthors = active authors\r
package com.gitblit.wicket;\r
\r
import java.text.DateFormat;\r
+import java.text.MessageFormat;\r
import java.text.SimpleDateFormat;\r
import java.util.Collection;\r
import java.util.Date;\r
container.add(new SimpleAttributeModifier("style", value));\r
}\r
\r
+ public static void setCssBackground(Component container, String value) {\r
+ String background = MessageFormat.format("background-color:{0};",\r
+ StringUtils.getColor(value));\r
+ container.add(new SimpleAttributeModifier("style", background));\r
+ }\r
+\r
public static void setHtmlTooltip(Component container, String value) {\r
container.add(new SimpleAttributeModifier("title", value));\r
}\r
filename = "bullet_white.png";\r
break;\r
case PENDING:\r
- case NOCHANGE: \r
+ case NOCHANGE:\r
default:\r
filename = "bullet_black.png";\r
}\r
}\r
});\r
}\r
- \r
+\r
public static PageParameters newTokenParameter(String token) {\r
return new PageParameters("t=" + token);\r
}\r
- \r
+\r
public static PageParameters newRegistrationParameter(String url, String name) {\r
return new PageParameters("u=" + url + ",n=" + name);\r
}\r
if (StringUtils.isEmpty(objectId)) {\r
return new PageParameters("r=" + repositoryName + ",f=" + path + ",pg=" + pageNumber);\r
}\r
- return new PageParameters("r=" + repositoryName + ",h=" + objectId + ",f=" + path\r
- + ",pg=" + pageNumber);\r
+ return new PageParameters("r=" + repositoryName + ",h=" + objectId + ",f=" + path + ",pg="\r
+ + pageNumber);\r
}\r
\r
public static PageParameters newBlobDiffParameter(String repositoryName, String baseCommitId,\r
public static String getToken(PageParameters params) {\r
return params.getString("t", "");\r
}\r
- \r
+\r
public static String getUrlParameter(PageParameters params) {\r
return params.getString("u", "");\r
}\r
}\r
return label;\r
}\r
- \r
+\r
public static Label createTimeLabel(String wicketId, Date date, TimeZone timeZone) {\r
String format = GitBlit.getString(Keys.web.timeFormat, "HH:mm");\r
DateFormat df = new SimpleDateFormat(format);\r
}\r
return label;\r
}\r
- \r
+\r
public static Label createDatestampLabel(String wicketId, Date date, TimeZone timeZone) {\r
String format = GitBlit.getString(Keys.web.datestampLongFormat, "EEEE, MMMM d, yyyy");\r
DateFormat df = new SimpleDateFormat(format);\r
/*\r
- Copyright 2011 comSysto GmbH\r
+ Copyright 2011 gitblit.com.\r
\r
Licensed under the Apache License, Version 2.0 (the "License");\r
you may not use this file except in compliance with the License.\r
\r
private static final long serialVersionUID = 1L;\r
\r
- private List<GoogleChart> charts = new ArrayList<GoogleChart>();\r
+ public final List<GoogleChart> charts = new ArrayList<GoogleChart>();\r
\r
public void addChart(GoogleChart chart) {\r
charts.add(chart);\r
import java.text.MessageFormat;\r
import java.util.Collections;\r
\r
+import com.gitblit.utils.StringUtils;\r
+\r
/**\r
* Builds an interactive pie chart using the Visualization API.\r
* \r
\r
Collections.sort(values);\r
\r
+ StringBuilder colors = new StringBuilder("colors:[");\r
for (int i = 0; i < values.size(); i++) {\r
ChartValue value = values.get(i);\r
+ colors.append('\'');\r
+ colors.append(StringUtils.getColor(value.name));\r
+ colors.append('\'');\r
+ if (i < values.size() - 1) {\r
+ colors.append(',');\r
+ }\r
line(sb, MessageFormat.format("{0}.setValue({1,number,0}, 0, ''{2}'');", dName, i,\r
value.name));\r
line(sb, MessageFormat.format("{0}.setValue({1,number,0}, 1, {2,number,0.0});", dName,\r
i, value.value));\r
}\r
+ colors.append(']');\r
\r
// instantiate chart\r
String cName = "chart_" + dataName;\r
cName, tagId));\r
line(sb,\r
MessageFormat\r
- .format("{0}.draw({1}, '{'width: {2,number,0}, height: {3,number,0}, chartArea:'{'left:20,top:20'}', title: ''{4}'' '}');",\r
- cName, dName, width, height, title));\r
+ .format("{0}.draw({1}, '{'width: {2,number,0}, height: {3,number,0}, chartArea:'{'left:20,top:20'}', title: ''{4}'', {5} '}');",\r
+ cName, dName, width, height, title, colors.toString()));\r
line(sb, "");\r
}\r
}
\ No newline at end of file
<div class="page-header">\r
<h2><wicket:message key="gb.recentActivity"></wicket:message><small> / <span wicket:id="subheader">[days back]</span></small></h2>\r
</div>\r
- <div style="text-align: center;">\r
+ <div style="height: 155px;text-align: center;">\r
<span id="chartDaily"></span> \r
<span id="chartRepositories"></span>\r
<span id="chartAuthors"></span>\r
*/\r
package com.gitblit.wicket.pages;\r
\r
-import java.text.DateFormat;\r
import java.text.MessageFormat;\r
import java.text.SimpleDateFormat;\r
import java.util.ArrayList;\r
-import java.util.Calendar;\r
import java.util.Collections;\r
-import java.util.Date;\r
import java.util.HashMap;\r
+import java.util.HashSet;\r
import java.util.List;\r
import java.util.Map;\r
+import java.util.Set;\r
\r
import org.apache.wicket.PageParameters;\r
import org.apache.wicket.behavior.HeaderContributor;\r
import org.apache.wicket.markup.html.basic.Label;\r
-import org.eclipse.jgit.lib.Constants;\r
-import org.eclipse.jgit.lib.ObjectId;\r
-import org.eclipse.jgit.lib.Repository;\r
-import org.eclipse.jgit.revwalk.RevCommit;\r
\r
import com.gitblit.GitBlit;\r
-import com.gitblit.models.DailyActivity;\r
+import com.gitblit.models.Activity;\r
import com.gitblit.models.Metric;\r
-import com.gitblit.models.RefModel;\r
-import com.gitblit.models.RepositoryCommit;\r
import com.gitblit.models.RepositoryModel;\r
import com.gitblit.models.UserModel;\r
-import com.gitblit.utils.JGitUtils;\r
+import com.gitblit.utils.ActivityUtils;\r
import com.gitblit.utils.StringUtils;\r
-import com.gitblit.utils.TimeUtils;\r
import com.gitblit.wicket.GitBlitWebSession;\r
import com.gitblit.wicket.WicketUtils;\r
import com.gitblit.wicket.charting.GoogleChart;\r
public ActivityPage(PageParameters params) {\r
super();\r
setupPage("", "");\r
- final UserModel user = GitBlitWebSession.get().getUser();\r
\r
// parameters\r
int daysBack = WicketUtils.getDaysBack(params);\r
if (daysBack < 1) {\r
daysBack = 14;\r
- } \r
+ }\r
+ String objectId = WicketUtils.getObject(params);\r
+\r
+ // determine repositories to view and retrieve the activity\r
+ List<RepositoryModel> models = getRepositories(params);\r
+ List<Activity> recentActivity = ActivityUtils.getRecentActivity(models, daysBack, objectId);\r
+\r
+ if (recentActivity.size() == 0) {\r
+ // no activity, skip graphs and activity panel\r
+ add(new Label("subheader", MessageFormat.format(getString("gb.recentActivityNone"),\r
+ daysBack)));\r
+ add(new Label("activityPanel"));\r
+ } else {\r
+ // calculate total commits and total authors\r
+ int totalCommits = 0;\r
+ Set<String> uniqueAuthors = new HashSet<String>();\r
+ for (Activity activity : recentActivity) {\r
+ totalCommits += activity.commits.size();\r
+ uniqueAuthors.addAll(activity.getAuthorMetrics().keySet());\r
+ }\r
+ int totalAuthors = uniqueAuthors.size();\r
+\r
+ // add the subheader with stat numbers\r
+ add(new Label("subheader", MessageFormat.format(getString("gb.recentActivityStats"),\r
+ daysBack, totalCommits, totalAuthors)));\r
+\r
+ // create the activity charts\r
+ GoogleCharts charts = createCharts(recentActivity);\r
+ add(new HeaderContributor(charts));\r
+\r
+ // add activity panel\r
+ add(new ActivityPanel("activityPanel", recentActivity));\r
+ }\r
+ }\r
+\r
+ private List<RepositoryModel> getRepositories(PageParameters params) {\r
+ final UserModel user = GitBlitWebSession.get().getUser();\r
String set = WicketUtils.getSet(params);\r
String repositoryName = WicketUtils.getRepositoryName(params);\r
- String objectId = WicketUtils.getObject(params);\r
\r
List<RepositoryModel> models = null;\r
if (!StringUtils.isEmpty(repositoryName)) {\r
}\r
models = setModels;\r
}\r
+ return models;\r
+ }\r
\r
- // Activity panel shows last daysBack of activity across all\r
- // repositories.\r
- Date thresholdDate = new Date(System.currentTimeMillis() - daysBack * TimeUtils.ONEDAY);\r
-\r
- // Build a map of DailyActivity from the available repositories for the\r
- // specified threshold date.\r
- DateFormat df = new SimpleDateFormat("yyyy-MM-dd");\r
- Calendar cal = Calendar.getInstance();\r
-\r
- Map<String, DailyActivity> activity = new HashMap<String, DailyActivity>();\r
- for (RepositoryModel model : models) {\r
- if (model.hasCommits && model.lastChange.after(thresholdDate)) {\r
- Repository repository = GitBlit.self().getRepository(model.name);\r
- List<RevCommit> commits = JGitUtils.getRevLog(repository, objectId, thresholdDate);\r
- Map<ObjectId, List<RefModel>> allRefs = JGitUtils.getAllRefs(repository);\r
- repository.close();\r
-\r
- // determine commit branch\r
- String branch = objectId;\r
- if (StringUtils.isEmpty(branch)) {\r
- List<RefModel> headRefs = allRefs.get(commits.get(0).getId());\r
- List<String> localBranches = new ArrayList<String>();\r
- for (RefModel ref : headRefs) {\r
- if (ref.getName().startsWith(Constants.R_HEADS)) {\r
- localBranches.add(ref.getName().substring(Constants.R_HEADS.length()));\r
- }\r
- }\r
- // determine branch\r
- if (localBranches.size() == 1) {\r
- // only one branch, choose it\r
- branch = localBranches.get(0);\r
- } else if (localBranches.size() > 1) {\r
- if (localBranches.contains("master")) {\r
- // choose master\r
- branch = "master";\r
- } else {\r
- // choose first branch\r
- branch = localBranches.get(0);\r
- }\r
- }\r
- }\r
-\r
- for (RevCommit commit : commits) {\r
- Date date = JGitUtils.getCommitDate(commit);\r
- String dateStr = df.format(date);\r
- if (!activity.containsKey(dateStr)) {\r
- // Normalize the date to midnight\r
- cal.setTime(date);\r
- cal.set(Calendar.HOUR_OF_DAY, 0);\r
- cal.set(Calendar.MINUTE, 0);\r
- cal.set(Calendar.SECOND, 0);\r
- cal.set(Calendar.MILLISECOND, 0);\r
- activity.put(dateStr, new DailyActivity(cal.getTime()));\r
- }\r
- RepositoryCommit commitModel = new RepositoryCommit(model.name, branch, commit);\r
- commitModel.setRefs(allRefs.get(commit.getId()));\r
- activity.get(dateStr).commits.add(commitModel);\r
- }\r
- }\r
- }\r
-\r
+ /**\r
+ * Creates the daily activity line chart, the active repositories pie chart,\r
+ * and the active authors pie chart\r
+ * \r
+ * @param recentActivity\r
+ * @return\r
+ */\r
+ private GoogleCharts createCharts(List<Activity> recentActivity) {\r
// activity metrics\r
- Map<String, Metric> dayMetrics = new HashMap<String, Metric>();\r
Map<String, Metric> repositoryMetrics = new HashMap<String, Metric>();\r
Map<String, Metric> authorMetrics = new HashMap<String, Metric>();\r
\r
- // prepare day metrics\r
- cal.setTimeInMillis(System.currentTimeMillis());\r
- for (int i = 0; i < daysBack; i++) {\r
- cal.add(Calendar.DATE, -1);\r
- String key = df.format(cal.getTime());\r
- dayMetrics.put(key, new Metric(key));\r
- }\r
-\r
- // calculate activity metrics\r
- for (Map.Entry<String, DailyActivity> entry : activity.entrySet()) {\r
- // day metrics\r
- Metric day = dayMetrics.get(entry.getKey());\r
- day.count = entry.getValue().commits.size();\r
+ // aggregate repository and author metrics\r
+ for (Activity activity : recentActivity) {\r
\r
- for (RepositoryCommit commit : entry.getValue().commits) {\r
- // repository metrics\r
- String repository = commit.repository;\r
- if (!repositoryMetrics.containsKey(repository)) {\r
- repositoryMetrics.put(repository, new Metric(repository));\r
- }\r
- repositoryMetrics.get(repository).count++;\r
-\r
- // author metrics\r
- String author = commit.getAuthorIdent().getEmailAddress().toLowerCase();\r
+ // aggregate author metrics\r
+ for (Map.Entry<String, Metric> entry : activity.getAuthorMetrics().entrySet()) {\r
+ String author = entry.getKey();\r
if (!authorMetrics.containsKey(author)) {\r
authorMetrics.put(author, new Metric(author));\r
}\r
- authorMetrics.get(author).count++;\r
+ authorMetrics.get(author).count += entry.getValue().count;\r
}\r
- }\r
\r
- // sort the activity groups and their commit contents\r
- int totalCommits = 0;\r
- List<DailyActivity> recentActivity = new ArrayList<DailyActivity>(activity.values());\r
- for (DailyActivity daily : recentActivity) {\r
- Collections.sort(daily.commits);\r
- totalCommits += daily.commits.size();\r
+ // aggregate repository metrics\r
+ for (Map.Entry<String, Metric> entry : activity.getRepositoryMetrics().entrySet()) {\r
+ String repository = entry.getKey();\r
+ if (!repositoryMetrics.containsKey(repository)) {\r
+ repositoryMetrics.put(repository, new Metric(repository));\r
+ }\r
+ repositoryMetrics.get(repository).count += entry.getValue().count;\r
+ }\r
}\r
\r
// build google charts\r
// daily line chart\r
GoogleChart chart = new GoogleLineChart("chartDaily", getString("gb.dailyActivity"), "day",\r
getString("gb.commits"));\r
- df = new SimpleDateFormat("MMM dd");\r
- for (DailyActivity metric : recentActivity) {\r
- chart.addValue(df.format(metric.date), metric.commits.size());\r
+ SimpleDateFormat df = new SimpleDateFormat("MMM dd");\r
+ for (Activity metric : recentActivity) {\r
+ chart.addValue(df.format(metric.startDate), metric.commits.size());\r
}\r
chart.setWidth(w);\r
chart.setHeight(h);\r
chart.setHeight(h);\r
charts.addChart(chart);\r
\r
- add(new HeaderContributor(charts));\r
-\r
- add(new Label("subheader", MessageFormat.format(getString("gb.recentActivitySubheader"),\r
- daysBack, totalCommits, authorMetrics.size())));\r
-\r
- // add activity panel\r
- add(new ActivityPanel("activityPanel", recentActivity));\r
+ return charts;\r
}\r
}\r
\r
<wicket:fragment wicket:id="commitFragment">\r
<td class="date" style="width:40px; vertical-align: middle;" ><span wicket:id="time">[time of day]</span></td>\r
+ <td style="width:10em;text-align:left;vertical-align: middle;">\r
+ <span wicket:id="repository" class="repositorySwatch">[repository link]</span>\r
+ </td>\r
<td style="width:30px;vertical-align: middle;"><img wicket:id="avatar" style="vertical-align: middle;"></img></td>\r
<td class="author" style="vertical-align: middle;">\r
<img wicket:id="commitIcon" style="vertical-align: middle;"></img>\r
</td>\r
<td style="text-align:right;vertical-align: middle;">\r
<div wicket:id="commitRefs">[commit refs]</div>\r
- <span wicket:id="repository">[repository link]</span>\r
</td>\r
<td class="rightAlign" style="width:7em;vertical-align: middle;">\r
<span class="link">\r
import org.apache.wicket.markup.repeater.data.ListDataProvider;\r
\r
import com.gitblit.Constants;\r
-import com.gitblit.models.DailyActivity;\r
-import com.gitblit.models.RepositoryCommit;\r
+import com.gitblit.models.Activity;\r
+import com.gitblit.models.Activity.RepositoryCommit;\r
+import com.gitblit.utils.StringUtils;\r
import com.gitblit.wicket.GitBlitWebSession;\r
import com.gitblit.wicket.GravatarImage;\r
import com.gitblit.wicket.WicketUtils;\r
\r
private static final long serialVersionUID = 1L;\r
\r
- public ActivityPanel(String wicketId, List<DailyActivity> recentActivity) {\r
+ public ActivityPanel(String wicketId, List<Activity> recentActivity) {\r
super(wicketId);\r
\r
Collections.sort(recentActivity);\r
\r
- DataView<DailyActivity> activityView = new DataView<DailyActivity>("activity",\r
- new ListDataProvider<DailyActivity>(recentActivity)) {\r
+ DataView<Activity> activityView = new DataView<Activity>("activity",\r
+ new ListDataProvider<Activity>(recentActivity)) {\r
private static final long serialVersionUID = 1L;\r
\r
- public void populateItem(final Item<DailyActivity> item) {\r
- final DailyActivity entry = item.getModelObject();\r
- item.add(WicketUtils.createDatestampLabel("title", entry.date, GitBlitWebSession\r
+ public void populateItem(final Item<Activity> item) {\r
+ final Activity entry = item.getModelObject();\r
+ item.add(WicketUtils.createDatestampLabel("title", entry.startDate, GitBlitWebSession\r
.get().getTimezone()));\r
\r
// display the commits in chronological order\r
setPersonSearchTooltip(authorLink, author, Constants.SearchType.AUTHOR);\r
fragment.add(authorLink);\r
\r
- // repository summary page link\r
- LinkPanel repositoryLink = new LinkPanel("repository", "list",\r
+ // repository\r
+ LinkPanel repositoryLink = new LinkPanel("repository", null,\r
commit.repository, SummaryPage.class,\r
WicketUtils.newRepositoryParameter(commit.repository));\r
+ WicketUtils.setCssBackground(repositoryLink, commit.repository);\r
fragment.add(repositoryLink);\r
\r
// repository branch\r
\r
// message/commit link\r
String shortMessage = commit.getShortMessage();\r
- LinkPanel shortlog = new LinkPanel("message", "list subject", shortMessage,\r
- CommitPage.class, WicketUtils.newObjectParameter(commit.repository,\r
- commit.getName()));\r
+ String trimmedMessage = StringUtils.trimShortLog(shortMessage);\r
+ LinkPanel shortlog = new LinkPanel("message", "list subject",\r
+ trimmedMessage, CommitPage.class, WicketUtils.newObjectParameter(\r
+ commit.repository, commit.getName()));\r
+ if (!shortMessage.equals(trimmedMessage)) {\r
+ WicketUtils.setHtmlTooltip(shortlog, shortMessage);\r
+ }\r
fragment.add(shortlog);\r
\r
// refs\r