You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

DashboardPage.java 8.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. /*
  2. * Copyright 2013 gitblit.com.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package com.gitblit.wicket.pages;
  17. import java.io.Serializable;
  18. import java.text.MessageFormat;
  19. import java.util.ArrayList;
  20. import java.util.Calendar;
  21. import java.util.Collection;
  22. import java.util.Collections;
  23. import java.util.Date;
  24. import java.util.HashMap;
  25. import java.util.List;
  26. import java.util.Map;
  27. import java.util.Set;
  28. import java.util.TimeZone;
  29. import java.util.TreeSet;
  30. import org.apache.wicket.PageParameters;
  31. import org.apache.wicket.behavior.HeaderContributor;
  32. import org.apache.wicket.markup.html.basic.Label;
  33. import org.apache.wicket.markup.html.panel.Fragment;
  34. import org.eclipse.jgit.lib.Repository;
  35. import com.gitblit.GitBlit;
  36. import com.gitblit.Keys;
  37. import com.gitblit.models.DailyLogEntry;
  38. import com.gitblit.models.Metric;
  39. import com.gitblit.models.RefLogEntry;
  40. import com.gitblit.models.RepositoryCommit;
  41. import com.gitblit.models.RepositoryModel;
  42. import com.gitblit.models.UserModel;
  43. import com.gitblit.utils.ArrayUtils;
  44. import com.gitblit.utils.RefLogUtils;
  45. import com.gitblit.utils.StringUtils;
  46. import com.gitblit.wicket.GitBlitWebApp;
  47. import com.gitblit.wicket.PageRegistration;
  48. import com.gitblit.wicket.PageRegistration.DropDownMenuItem;
  49. import com.gitblit.wicket.PageRegistration.DropDownMenuRegistration;
  50. import com.gitblit.wicket.charting.GoogleChart;
  51. import com.gitblit.wicket.charting.GoogleCharts;
  52. import com.gitblit.wicket.charting.GooglePieChart;
  53. import com.gitblit.wicket.panels.DigestsPanel;
  54. import com.gitblit.wicket.panels.LinkPanel;
  55. public abstract class DashboardPage extends RootPage {
  56. public DashboardPage() {
  57. super();
  58. }
  59. public DashboardPage(PageParameters params) {
  60. super(params);
  61. }
  62. @Override
  63. protected boolean reusePageParameters() {
  64. return true;
  65. }
  66. protected void addActivity(UserModel user, Collection<RepositoryModel> repositories, String feedTitle, int daysBack) {
  67. Calendar c = Calendar.getInstance();
  68. c.add(Calendar.DATE, -1*daysBack);
  69. Date minimumDate = c.getTime();
  70. TimeZone timezone = getTimeZone();
  71. // create daily commit digest feed
  72. List<DailyLogEntry> digests = new ArrayList<DailyLogEntry>();
  73. for (RepositoryModel model : repositories) {
  74. if (model.isCollectingGarbage) {
  75. continue;
  76. }
  77. if (model.hasCommits && model.lastChange.after(minimumDate)) {
  78. Repository repository = GitBlit.self().getRepository(model.name);
  79. List<DailyLogEntry> entries = RefLogUtils.getDailyLogByRef(model.name, repository, minimumDate, timezone);
  80. digests.addAll(entries);
  81. repository.close();
  82. }
  83. }
  84. Fragment activityFragment = new Fragment("activity", "activityFragment", this);
  85. add(activityFragment);
  86. activityFragment.add(new Label("feedTitle", feedTitle));
  87. if (digests.size() == 0) {
  88. // quiet or no starred repositories
  89. if (repositories.size() == 0) {
  90. if (UserModel.ANONYMOUS.equals(user)) {
  91. if (daysBack == 1) {
  92. activityFragment.add(new Label("digests", getString("gb.noActivityToday")));
  93. } else {
  94. activityFragment.add(new Label("digests", MessageFormat.format(getString("gb.noActivity"), daysBack)));
  95. }
  96. } else {
  97. activityFragment.add(new LinkPanel("digests", null, getString("gb.findSomeRepositories"), RepositoriesPage.class));
  98. }
  99. } else {
  100. if (daysBack == 1) {
  101. activityFragment.add(new Label("digests", getString("gb.noActivityToday")));
  102. } else {
  103. activityFragment.add(new Label("digests", MessageFormat.format(getString("gb.noActivity"), daysBack)));
  104. }
  105. }
  106. } else {
  107. // show daily commit digest feed
  108. Collections.sort(digests);
  109. DigestsPanel digestsPanel = new DigestsPanel("digests", digests);
  110. activityFragment.add(digestsPanel);
  111. }
  112. // add the nifty charts
  113. if (!ArrayUtils.isEmpty(digests)) {
  114. // aggregate author exclusions
  115. Set<String> authorExclusions = new TreeSet<String>();
  116. for (String author : GitBlit.getStrings(Keys.web.metricAuthorExclusions)) {
  117. authorExclusions.add(author.toLowerCase());
  118. }
  119. for (RepositoryModel model : repositories) {
  120. if (!ArrayUtils.isEmpty(model.metricAuthorExclusions)) {
  121. for (String author : model.metricAuthorExclusions) {
  122. authorExclusions.add(author.toLowerCase());
  123. }
  124. }
  125. }
  126. addCharts(activityFragment, digests, authorExclusions, daysBack);
  127. } else {
  128. activityFragment.add(new Label("charts").setVisible(false));
  129. activityFragment.add(new Label("feedheader").setVisible(false));
  130. }
  131. }
  132. @Override
  133. protected void addDropDownMenus(List<PageRegistration> pages) {
  134. PageParameters params = getPageParameters();
  135. DropDownMenuRegistration menu = new DropDownMenuRegistration("gb.filters",
  136. GitBlitWebApp.HOME_PAGE_CLASS);
  137. // preserve time filter option on repository choices
  138. menu.menuItems.addAll(getRepositoryFilterItems(params));
  139. // preserve repository filter option on time choices
  140. menu.menuItems.addAll(getTimeFilterItems(params));
  141. if (menu.menuItems.size() > 0) {
  142. // Reset Filter
  143. menu.menuItems.add(new DropDownMenuItem(getString("gb.reset"), null, null));
  144. }
  145. pages.add(menu);
  146. }
  147. /**
  148. * Creates the daily activity line chart, the active repositories pie chart,
  149. * and the active authors pie chart
  150. *
  151. * @param recentChanges
  152. * @param authorExclusions
  153. * @param daysBack
  154. */
  155. protected void addCharts(Fragment frag, List<DailyLogEntry> recentChanges, Set<String> authorExclusions, int daysBack) {
  156. // activity metrics
  157. Map<String, Metric> repositoryMetrics = new HashMap<String, Metric>();
  158. Map<String, Metric> authorMetrics = new HashMap<String, Metric>();
  159. // aggregate repository and author metrics
  160. int totalCommits = 0;
  161. for (RefLogEntry change : recentChanges) {
  162. // aggregate repository metrics
  163. String repository = StringUtils.stripDotGit(change.repository);
  164. if (!repositoryMetrics.containsKey(repository)) {
  165. repositoryMetrics.put(repository, new Metric(repository));
  166. }
  167. repositoryMetrics.get(repository).count += 1;
  168. for (RepositoryCommit commit : change.getCommits()) {
  169. totalCommits++;
  170. String author = StringUtils.removeNewlines(commit.getAuthorIdent().getName());
  171. String authorName = author.toLowerCase();
  172. String authorEmail = StringUtils.removeNewlines(commit.getAuthorIdent().getEmailAddress()).toLowerCase();
  173. if (!authorExclusions.contains(authorName) && !authorExclusions.contains(authorEmail)) {
  174. if (!authorMetrics.containsKey(author)) {
  175. authorMetrics.put(author, new Metric(author));
  176. }
  177. authorMetrics.get(author).count += 1;
  178. }
  179. }
  180. }
  181. String headerPattern;
  182. if (daysBack == 1) {
  183. // today
  184. if (totalCommits == 0) {
  185. headerPattern = getString("gb.todaysActivityNone");
  186. } else {
  187. headerPattern = getString("gb.todaysActivityStats");
  188. }
  189. } else {
  190. // multiple days
  191. if (totalCommits == 0) {
  192. headerPattern = getString("gb.recentActivityNone");
  193. } else {
  194. headerPattern = getString("gb.recentActivityStats");
  195. }
  196. }
  197. frag.add(new Label("feedheader", MessageFormat.format(headerPattern,
  198. daysBack, totalCommits, authorMetrics.size())));
  199. // build google charts
  200. GoogleCharts charts = new GoogleCharts();
  201. // active repositories pie chart
  202. GoogleChart chart = new GooglePieChart("chartRepositories", getString("gb.activeRepositories"),
  203. getString("gb.repository"), getString("gb.commits"));
  204. for (Metric metric : repositoryMetrics.values()) {
  205. chart.addValue(metric.name, metric.count);
  206. }
  207. chart.setShowLegend(false);
  208. charts.addChart(chart);
  209. // active authors pie chart
  210. chart = new GooglePieChart("chartAuthors", getString("gb.activeAuthors"),
  211. getString("gb.author"), getString("gb.commits"));
  212. for (Metric metric : authorMetrics.values()) {
  213. chart.addValue(metric.name, metric.count);
  214. }
  215. chart.setShowLegend(false);
  216. charts.addChart(chart);
  217. add(new HeaderContributor(charts));
  218. frag.add(new Fragment("charts", "chartsFragment", this));
  219. }
  220. }