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.

ActivityUtils.java 6.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. /*
  2. * Copyright 2011 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.utils;
  17. import java.io.FileNotFoundException;
  18. import java.io.IOException;
  19. import java.lang.reflect.Type;
  20. import java.text.DateFormat;
  21. import java.text.MessageFormat;
  22. import java.text.SimpleDateFormat;
  23. import java.util.ArrayList;
  24. import java.util.Calendar;
  25. import java.util.Date;
  26. import java.util.HashMap;
  27. import java.util.List;
  28. import java.util.Map;
  29. import java.util.TimeZone;
  30. import org.eclipse.jgit.lib.Constants;
  31. import org.eclipse.jgit.lib.ObjectId;
  32. import org.eclipse.jgit.lib.Repository;
  33. import org.eclipse.jgit.revwalk.RevCommit;
  34. import com.gitblit.GitBlit;
  35. import com.gitblit.models.Activity;
  36. import com.gitblit.models.Activity.RepositoryCommit;
  37. import com.gitblit.models.GravatarProfile;
  38. import com.gitblit.models.RefModel;
  39. import com.gitblit.models.RepositoryModel;
  40. import com.google.gson.reflect.TypeToken;
  41. /**
  42. * Utility class for building activity information from repositories.
  43. *
  44. * @author James Moger
  45. *
  46. */
  47. public class ActivityUtils {
  48. /**
  49. * Gets the recent activity from the repositories for the last daysBack days
  50. * on the specified branch.
  51. *
  52. * @param models
  53. * the list of repositories to query
  54. * @param daysBack
  55. * the number of days back from Now to collect
  56. * @param objectId
  57. * the branch to retrieve. If this value is null or empty all
  58. * branches are queried.
  59. * @param timezone
  60. * the timezone for aggregating commits
  61. * @return
  62. */
  63. public static List<Activity> getRecentActivity(List<RepositoryModel> models, int daysBack,
  64. String objectId, TimeZone timezone) {
  65. // Activity panel shows last daysBack of activity across all
  66. // repositories.
  67. Date thresholdDate = new Date(System.currentTimeMillis() - daysBack * TimeUtils.ONEDAY);
  68. // Build a map of DailyActivity from the available repositories for the
  69. // specified threshold date.
  70. DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
  71. df.setTimeZone(timezone);
  72. Calendar cal = Calendar.getInstance();
  73. cal.setTimeZone(timezone);
  74. Map<String, Activity> activity = new HashMap<String, Activity>();
  75. for (RepositoryModel model : models) {
  76. if (model.hasCommits && model.lastChange.after(thresholdDate)) {
  77. Repository repository = GitBlit.self()
  78. .getRepository(model.name);
  79. List<String> branches = new ArrayList<String>();
  80. if (StringUtils.isEmpty(objectId)) {
  81. for (RefModel local : JGitUtils.getLocalBranches(
  82. repository, true, -1)) {
  83. branches.add(local.getName());
  84. }
  85. } else {
  86. branches.add(objectId);
  87. }
  88. Map<ObjectId, List<RefModel>> allRefs = JGitUtils
  89. .getAllRefs(repository, model.showRemoteBranches);
  90. for (String branch : branches) {
  91. String shortName = branch;
  92. if (shortName.startsWith(Constants.R_HEADS)) {
  93. shortName = shortName.substring(Constants.R_HEADS.length());
  94. }
  95. List<RevCommit> commits = JGitUtils.getRevLog(repository,
  96. branch, thresholdDate);
  97. for (RevCommit commit : commits) {
  98. Date date = JGitUtils.getCommitDate(commit);
  99. String dateStr = df.format(date);
  100. if (!activity.containsKey(dateStr)) {
  101. // Normalize the date to midnight
  102. cal.setTime(date);
  103. cal.set(Calendar.HOUR_OF_DAY, 0);
  104. cal.set(Calendar.MINUTE, 0);
  105. cal.set(Calendar.SECOND, 0);
  106. cal.set(Calendar.MILLISECOND, 0);
  107. activity.put(dateStr, new Activity(cal.getTime()));
  108. }
  109. RepositoryCommit commitModel = activity.get(dateStr)
  110. .addCommit(model.name, shortName, commit);
  111. if (commitModel != null) {
  112. commitModel.setRefs(allRefs.get(commit.getId()));
  113. }
  114. }
  115. }
  116. // close the repository
  117. repository.close();
  118. }
  119. }
  120. List<Activity> recentActivity = new ArrayList<Activity>(activity.values());
  121. return recentActivity;
  122. }
  123. /**
  124. * Returns the Gravatar profile, if available, for the specified email
  125. * address.
  126. *
  127. * @param emailaddress
  128. * @return a Gravatar Profile
  129. * @throws IOException
  130. */
  131. public static GravatarProfile getGravatarProfileFromAddress(String emailaddress)
  132. throws IOException {
  133. return getGravatarProfile(StringUtils.getMD5(emailaddress.toLowerCase()));
  134. }
  135. /**
  136. * Creates a Gravatar thumbnail url from the specified email address.
  137. *
  138. * @param email
  139. * address to query Gravatar
  140. * @param width
  141. * size of thumbnail. if width <= 0, the default of 50 is used.
  142. * @return
  143. */
  144. public static String getGravatarThumbnailUrl(String email, int width) {
  145. if (width <= 0) {
  146. width = 50;
  147. }
  148. String emailHash = StringUtils.getMD5(email);
  149. String url = MessageFormat.format(
  150. "https://www.gravatar.com/avatar/{0}?s={1,number,0}&d=identicon", emailHash, width);
  151. return url;
  152. }
  153. /**
  154. * Returns the Gravatar profile, if available, for the specified hashcode.
  155. * address.
  156. *
  157. * @param hash
  158. * the hash of the email address
  159. * @return a Gravatar Profile
  160. * @throws IOException
  161. */
  162. public static GravatarProfile getGravatarProfile(String hash) throws IOException {
  163. String url = MessageFormat.format("https://www.gravatar.com/{0}.json", hash);
  164. // Gravatar has a complex json structure
  165. Type profileType = new TypeToken<Map<String, List<GravatarProfile>>>() {
  166. }.getType();
  167. Map<String, List<GravatarProfile>> profiles = null;
  168. try {
  169. profiles = JsonUtils.retrieveJson(url, profileType);
  170. } catch (FileNotFoundException e) {
  171. }
  172. if (profiles == null || profiles.size() == 0) {
  173. return null;
  174. }
  175. // due to the complex json structure we need to pull out the profile
  176. // from a list 2 levels deep
  177. GravatarProfile profile = profiles.values().iterator().next().get(0);
  178. return profile;
  179. }
  180. }