James Moger
2015-11-22 ed552ba47c02779c270ffd62841d6d1048dade70
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
18 import java.text.DateFormat;
797322 19 import java.text.MessageFormat;
db91a3 20 import java.text.SimpleDateFormat;
JM 21 import java.util.ArrayList;
22 import java.util.Calendar;
23 import java.util.Date;
24 import java.util.HashMap;
25 import java.util.List;
26 import java.util.Map;
cedf13 27 import java.util.Set;
40538c 28 import java.util.TimeZone;
cedf13 29 import java.util.TreeSet;
db91a3 30
JM 31 import org.eclipse.jgit.lib.Constants;
32 import org.eclipse.jgit.lib.Repository;
33
db4f6b 34 import com.gitblit.IStoredSettings;
cedf13 35 import com.gitblit.Keys;
db4f6b 36 import com.gitblit.manager.IRepositoryManager;
db91a3 37 import com.gitblit.models.Activity;
JM 38 import com.gitblit.models.RefModel;
f8bb95 39 import com.gitblit.models.RepositoryCommit;
db91a3 40 import com.gitblit.models.RepositoryModel;
JM 41
42 /**
43  * Utility class for building activity information from repositories.
699e71 44  *
db91a3 45  * @author James Moger
699e71 46  *
db91a3 47  */
JM 48 public class ActivityUtils {
49
50     /**
51      * Gets the recent activity from the repositories for the last daysBack days
52      * on the specified branch.
699e71 53      *
db4f6b 54      * @param settings
JM 55      *            the runtime settings
56      * @param repositoryManager
57      *            the repository manager
db91a3 58      * @param models
JM 59      *            the list of repositories to query
60      * @param daysBack
61      *            the number of days back from Now to collect
62      * @param objectId
9d921f 63      *            the branch to retrieve. If this value is null or empty all
JM 64      *            branches are queried.
40538c 65      * @param timezone
JM 66      *            the timezone for aggregating commits
db91a3 67      * @return
JM 68      */
db4f6b 69     public static List<Activity> getRecentActivity(
JM 70                     IStoredSettings settings,
71                     IRepositoryManager repositoryManager,
72                     List<RepositoryModel> models,
73                     int daysBack,
74                     String objectId,
75                     TimeZone timezone) {
db91a3 76
JM 77         // Activity panel shows last daysBack of activity across all
78         // repositories.
79         Date thresholdDate = new Date(System.currentTimeMillis() - daysBack * TimeUtils.ONEDAY);
80
81         // Build a map of DailyActivity from the available repositories for the
82         // specified threshold date.
83         DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
40538c 84         df.setTimeZone(timezone);
db91a3 85         Calendar cal = Calendar.getInstance();
40538c 86         cal.setTimeZone(timezone);
699e71 87
cedf13 88         // aggregate author exclusions
JM 89         Set<String> authorExclusions = new TreeSet<String>();
db4f6b 90         authorExclusions.addAll(settings.getStrings(Keys.web.metricAuthorExclusions));
cedf13 91         for (RepositoryModel model : models) {
JM 92             if (!ArrayUtils.isEmpty(model.metricAuthorExclusions)) {
93                 authorExclusions.addAll(model.metricAuthorExclusions);
94             }
95         }
db91a3 96
JM 97         Map<String, Activity> activity = new HashMap<String, Activity>();
98         for (RepositoryModel model : models) {
9b26b7 99             if (!model.isShowActivity()) {
dab13a 100                 // skip this repository
JM 101                 continue;
102             }
db91a3 103             if (model.hasCommits && model.lastChange.after(thresholdDate)) {
e92c6d 104                 if (model.isCollectingGarbage) {
JM 105                     continue;
106                 }
db4f6b 107                 Repository repository = repositoryManager.getRepository(model.name);
9d921f 108                 List<String> branches = new ArrayList<String>();
JM 109                 if (StringUtils.isEmpty(objectId)) {
110                     for (RefModel local : JGitUtils.getLocalBranches(
111                             repository, true, -1)) {
3c4ce1 112                         if (!local.getDate().after(thresholdDate)) {
JM 113                             // branch not recently updated
114                             continue;
115                         }
9d921f 116                         branches.add(local.getName());
JM 117                     }
118                 } else {
119                     branches.add(objectId);
120                 }
121
122                 for (String branch : branches) {
123                     String shortName = branch;
124                     if (shortName.startsWith(Constants.R_HEADS)) {
125                         shortName = shortName.substring(Constants.R_HEADS.length());
126                     }
79dd0b 127                     List<RepositoryCommit> commits = CommitCache.instance().getCommits(model.name, repository, branch, thresholdDate);
8295dd 128                     if (model.maxActivityCommits > 0 && commits.size() > model.maxActivityCommits) {
JM 129                         // trim commits to maximum count
130                         commits = commits.subList(0,  model.maxActivityCommits);
131                     }
699e71 132                     for (RepositoryCommit commit : commits) {
79dd0b 133                         Date date = commit.getCommitDate();
9d921f 134                         String dateStr = df.format(date);
JM 135                         if (!activity.containsKey(dateStr)) {
136                             // Normalize the date to midnight
137                             cal.setTime(date);
138                             cal.set(Calendar.HOUR_OF_DAY, 0);
139                             cal.set(Calendar.MINUTE, 0);
140                             cal.set(Calendar.SECOND, 0);
141                             cal.set(Calendar.MILLISECOND, 0);
cedf13 142                             Activity a = new Activity(cal.getTime());
JM 143                             a.excludeAuthors(authorExclusions);
144                             activity.put(dateStr, a);
9d921f 145                         }
79dd0b 146                         activity.get(dateStr).addCommit(commit);
9d921f 147                     }
JM 148                 }
699e71 149
9d921f 150                 // close the repository
db91a3 151                 repository.close();
JM 152             }
153         }
154
155         List<Activity> recentActivity = new ArrayList<Activity>(activity.values());
156         return recentActivity;
157     }
797322 158
JM 159     /**
160      * Creates a Gravatar thumbnail url from the specified email address.
699e71 161      *
797322 162      * @param email
JM 163      *            address to query Gravatar
164      * @param width
62cec2 165      *            size of thumbnail. if width <= 0, the default of 50 is used.
797322 166      * @return
JM 167      */
d551f9 168     public static String getGravatarIdenticonUrl(String email, int width) {
797322 169         if (width <= 0) {
62cec2 170             width = 50;
797322 171         }
f790d5 172         String emailHash = StringUtils.getMD5(email.toLowerCase());
797322 173         String url = MessageFormat.format(
7818bd 174                 "https://www.gravatar.com/avatar/{0}?s={1,number,0}&d=identicon", emailHash, width);
797322 175         return url;
JM 176     }
699e71 177
d551f9 178     /**
JM 179      * Creates a Gravatar thumbnail url from the specified email address.
699e71 180      *
d551f9 181      * @param email
JM 182      *            address to query Gravatar
183      * @param width
184      *            size of thumbnail. if width <= 0, the default of 50 is used.
185      * @return
186      */
187     public static String getGravatarThumbnailUrl(String email, int width) {
188         if (width <= 0) {
189             width = 50;
190         }
f790d5 191         String emailHash = StringUtils.getMD5(email.toLowerCase());
d551f9 192         String url = MessageFormat.format(
JM 193                 "https://www.gravatar.com/avatar/{0}?s={1,number,0}&d=mm", emailHash, width);
194         return url;
797322 195     }
db91a3 196 }