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