Tighter Gravatar integration. New window/tab on most activity links.
Each Gravatar thumbnail is now a link to the Gitblit Gravatar profile
page. This page displays some of the profile information and contains a
link to the full Gravatar profile.
Activity page links now launch a new window/tab instead of targeting
"self" since it can be expensive to requery the activity information.
1 files deleted
6 files added
7 files modified
New file |
| | |
| | | /*
|
| | | * Copyright 2011 gitblit.com.
|
| | | *
|
| | | * Licensed under the Apache License, Version 2.0 (the "License");
|
| | | * you may not use this file except in compliance with the License.
|
| | | * You may obtain a copy of the License at
|
| | | *
|
| | | * http://www.apache.org/licenses/LICENSE-2.0
|
| | | *
|
| | | * Unless required by applicable law or agreed to in writing, software
|
| | | * distributed under the License is distributed on an "AS IS" BASIS,
|
| | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| | | * See the License for the specific language governing permissions and
|
| | | * limitations under the License.
|
| | | */
|
| | | package com.gitblit.models;
|
| | |
|
| | | import java.io.Serializable;
|
| | | import java.util.List;
|
| | |
|
| | | /**
|
| | | * Represents a Gravatar profile.
|
| | | * |
| | | * @author James Moger
|
| | | * |
| | | */
|
| | | public class GravatarProfile implements Serializable {
|
| | |
|
| | | private static final long serialVersionUID = 1L;
|
| | |
|
| | | public String id;
|
| | | public String hash;
|
| | | public String requestHash;
|
| | | public String displayName;
|
| | | public String preferredUsername;
|
| | | public String currentLocation;
|
| | | public String aboutMe;
|
| | | |
| | | public String profileUrl;
|
| | | public String thumbnailUrl;
|
| | | public List<ProfileObject> photos;
|
| | | // public Map<String, String> profileBackground;
|
| | | // public Map<String, String> name;
|
| | |
|
| | | public List<ProfileObject> phoneNumbers;
|
| | | public List<ProfileObject> emails;
|
| | | public List<ProfileObject> ims;
|
| | | public List<Account> accounts;
|
| | | public List<ProfileObject> urls;
|
| | |
|
| | | public static class ProfileObject implements Serializable {
|
| | |
|
| | | private static final long serialVersionUID = 1L;
|
| | |
|
| | | public String title;
|
| | | public String type;
|
| | | public String value;
|
| | | public boolean primary;
|
| | |
|
| | | @Override
|
| | | public String toString() {
|
| | | return value;
|
| | | }
|
| | | }
|
| | |
|
| | | public static class Account implements Serializable {
|
| | |
|
| | | private static final long serialVersionUID = 1L;
|
| | |
|
| | | public String domain;
|
| | | public String display;
|
| | | public String url;
|
| | | public String username;
|
| | | public String userid;
|
| | | public boolean verified;
|
| | | public String shortname;
|
| | |
|
| | | @Override
|
| | | public String toString() {
|
| | | return display;
|
| | | }
|
| | | }
|
| | | }
|
| | |
| | | */
|
| | | package com.gitblit.utils;
|
| | |
|
| | | import java.io.FileNotFoundException;
|
| | | import java.io.IOException;
|
| | | import java.lang.reflect.Type;
|
| | | import java.text.DateFormat;
|
| | | import java.text.MessageFormat;
|
| | | import java.text.SimpleDateFormat;
|
| | | import java.util.ArrayList;
|
| | | import java.util.Calendar;
|
| | |
| | | import com.gitblit.GitBlit;
|
| | | import com.gitblit.models.Activity;
|
| | | import com.gitblit.models.Activity.RepositoryCommit;
|
| | | import com.gitblit.models.GravatarProfile;
|
| | | import com.gitblit.models.RefModel;
|
| | | import com.gitblit.models.RepositoryModel;
|
| | | import com.google.gson.reflect.TypeToken;
|
| | |
|
| | | /**
|
| | | * Utility class for building activity information from repositories.
|
| | |
| | | }
|
| | | return recentActivity;
|
| | | }
|
| | |
|
| | | /**
|
| | | * Returns the Gravatar profile, if available, for the specified email
|
| | | * address.
|
| | | * |
| | | * @param emailaddress
|
| | | * @return a Gravatar Profile
|
| | | * @throws IOException
|
| | | */
|
| | | public static GravatarProfile getGravatarProfileFromAddress(String emailaddress)
|
| | | throws IOException {
|
| | | return getGravatarProfile(StringUtils.getMD5(emailaddress.toLowerCase()));
|
| | | }
|
| | |
|
| | | /**
|
| | | * Creates a Gravatar thumbnail url from the specified email address.
|
| | | * |
| | | * @param email
|
| | | * address to query Gravatar
|
| | | * @param width
|
| | | * size of thumbnail. if width <= 0, the defalt of 60 is used.
|
| | | * @return
|
| | | */
|
| | | public static String getGravatarThumbnailUrl(String email, int width) {
|
| | | if (width <= 0) {
|
| | | width = 60;
|
| | | }
|
| | | String emailHash = StringUtils.getMD5(email);
|
| | | String url = MessageFormat.format(
|
| | | "http://www.gravatar.com/avatar/{0}?s={1,number,0}&d=identicon", emailHash, width);
|
| | | return url;
|
| | | }
|
| | |
|
| | | /**
|
| | | * Returns the Gravatar profile, if available, for the specified hashcode.
|
| | | * address.
|
| | | * |
| | | * @param hash
|
| | | * the hash of the email address
|
| | | * @return a Gravatar Profile
|
| | | * @throws IOException
|
| | | */
|
| | | public static GravatarProfile getGravatarProfile(String hash) throws IOException {
|
| | | String url = MessageFormat.format("http://www.gravatar.com/{0}.json", hash);
|
| | | // Gravatar has a complex json structure
|
| | | Type profileType = new TypeToken<Map<String, List<GravatarProfile>>>() {
|
| | | }.getType();
|
| | | Map<String, List<GravatarProfile>> profiles = null;
|
| | | try {
|
| | | profiles = JsonUtils.retrieveJson(url, profileType);
|
| | | } catch (FileNotFoundException e) {
|
| | | }
|
| | | if (profiles == null || profiles.size() == 0) {
|
| | | return null;
|
| | | }
|
| | | // due to the complex json structure we need to pull out the profile
|
| | | // from a list 2 levels deep
|
| | | GravatarProfile profile = profiles.values().iterator().next().get(0);
|
| | | return profile;
|
| | | }
|
| | | }
|
| | |
| | | import com.gitblit.wicket.pages.CommitPage;
|
| | | import com.gitblit.wicket.pages.DocsPage;
|
| | | import com.gitblit.wicket.pages.FederationRegistrationPage;
|
| | | import com.gitblit.wicket.pages.GravatarProfilePage;
|
| | | import com.gitblit.wicket.pages.HistoryPage;
|
| | | import com.gitblit.wicket.pages.LogPage;
|
| | | import com.gitblit.wicket.pages.MarkdownPage;
|
| | |
| | | mount("/registration", FederationRegistrationPage.class, "u", "n");
|
| | |
|
| | | mount("/activity", ActivityPage.class, "r", "h");
|
| | | mount("/gravatar", GravatarProfilePage.class, "h");
|
| | | }
|
| | |
|
| | | private void mount(String location, Class<? extends WebPage> clazz, String... parameters) {
|
| | |
| | | <div wicket:id="commitHeader">[commit header]</div>
|
| | |
|
| | | <!-- Author Gravatar -->
|
| | | <img style="float:right;vertical-align: top;" wicket:id="authorAvatar" />
|
| | | <span style="float:right;vertical-align: top;" wicket:id="authorAvatar" />
|
| | |
|
| | | <!-- commit info -->
|
| | | <table class="plain">
|
| | |
| | | <tr><td><span class="sha1" wicket:id="authorDate"></span></td></tr>
|
| | | </table>
|
| | | <!-- Note Author Gravatar -->
|
| | | <img style="vertical-align: top;" wicket:id="noteAuthorAvatar" /> |
| | | <span style="vertical-align: top;" wicket:id="noteAuthorAvatar" /> |
| | | </td>
|
| | | <td class="message"><span class="sha1" wicket:id="noteContent"></span></td>
|
| | | </tr>
|
| | |
| | | import com.gitblit.models.GitNote;
|
| | | import com.gitblit.models.PathModel.PathChangeModel;
|
| | | import com.gitblit.utils.JGitUtils;
|
| | | import com.gitblit.wicket.GravatarImage;
|
| | | import com.gitblit.wicket.WicketUtils;
|
| | | import com.gitblit.wicket.panels.CommitHeaderPanel;
|
| | | import com.gitblit.wicket.panels.CommitLegendPanel;
|
| | | import com.gitblit.wicket.panels.GravatarImage;
|
| | | import com.gitblit.wicket.panels.LinkPanel;
|
| | | import com.gitblit.wicket.panels.RefsPanel;
|
| | |
|
New file |
| | |
| | | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
| | | <html xmlns="http://www.w3.org/1999/xhtml" |
| | | xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.3-strict.dtd" |
| | | xml:lang="en" |
| | | lang="en"> |
| | | <body>
|
| | | <wicket:extend>
|
| | | <div class="page-header">
|
| | | <h2>Gravatar<small> / <span wicket:id="username">[username]</span></small></h2>
|
| | | </div>
|
| | | <img class="gravatar" wicket:id="profileImage"></img>
|
| | | <h2 wicket:id="displayName"></h2>
|
| | | <div style="color:#888;"wicket:id="location"></div>
|
| | | <div style="padding-top:5px;" wicket:id="aboutMe"></div>
|
| | | <p></p>
|
| | | <a wicket:id="profileLink">Complete profile on Gravatar.com</a>
|
| | | <p></p>
|
| | | </wicket:extend>
|
| | | </body>
|
| | | </html> |
New file |
| | |
| | | /*
|
| | | * Copyright 2011 gitblit.com.
|
| | | *
|
| | | * Licensed under the Apache License, Version 2.0 (the "License");
|
| | | * you may not use this file except in compliance with the License.
|
| | | * You may obtain a copy of the License at
|
| | | *
|
| | | * http://www.apache.org/licenses/LICENSE-2.0
|
| | | *
|
| | | * Unless required by applicable law or agreed to in writing, software
|
| | | * distributed under the License is distributed on an "AS IS" BASIS,
|
| | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| | | * See the License for the specific language governing permissions and
|
| | | * limitations under the License.
|
| | | */
|
| | | package com.gitblit.wicket.pages;
|
| | |
|
| | | import java.io.IOException;
|
| | | import java.text.MessageFormat;
|
| | |
|
| | | import org.apache.wicket.AttributeModifier;
|
| | | import org.apache.wicket.PageParameters;
|
| | | import org.apache.wicket.markup.html.basic.Label;
|
| | | import org.apache.wicket.markup.html.image.Image;
|
| | | import org.apache.wicket.markup.html.link.ExternalLink;
|
| | | import org.apache.wicket.model.Model;
|
| | |
|
| | | import com.gitblit.models.GravatarProfile;
|
| | | import com.gitblit.utils.ActivityUtils;
|
| | | import com.gitblit.wicket.WicketUtils;
|
| | |
|
| | | /**
|
| | | * Gravatar Profile Page shows the Gravatar information, if available.
|
| | | * |
| | | * @author James Moger
|
| | | * |
| | | */
|
| | | public class GravatarProfilePage extends RootPage {
|
| | |
|
| | | public GravatarProfilePage(PageParameters params) {
|
| | | super();
|
| | | setupPage("", "");
|
| | | String object = WicketUtils.getObject(params);
|
| | | GravatarProfile profile = null;
|
| | | try {
|
| | | if (object.indexOf('@') > -1) {
|
| | | profile = ActivityUtils.getGravatarProfileFromAddress(object);
|
| | | } else {
|
| | | profile = ActivityUtils.getGravatarProfile(object);
|
| | | }
|
| | | } catch (IOException e) {
|
| | | error(MessageFormat.format("Failed to find Gravatar profile for {0}", object), e, true);
|
| | | }
|
| | |
|
| | | add(new Label("displayName", profile.displayName));
|
| | | add(new Label("username", profile.preferredUsername));
|
| | | add(new Label("location", profile.currentLocation));
|
| | | add(new Label("aboutMe", profile.aboutMe));
|
| | | Image image = new Image("profileImage");
|
| | | image.add(new AttributeModifier("src", true, new Model<String>(profile.thumbnailUrl + "?s=256&d=identicon")));
|
| | | add(image);
|
| | | add(new ExternalLink("profileLink", profile.profileUrl));
|
| | | }
|
| | | }
|
| | |
| | | <td style="width:10em;text-align:left;vertical-align: middle;">
|
| | | <span wicket:id="repository" class="repositorySwatch">[repository link]</span>
|
| | | </td>
|
| | | <td style="width:30px;vertical-align: middle;"><img wicket:id="avatar" style="vertical-align: middle;"></img></td>
|
| | | <td style="width:30px;vertical-align: middle;"><span wicket:id="avatar" style="vertical-align: middle;"></span></td>
|
| | | <td class="author" style="vertical-align: middle;">
|
| | | <img wicket:id="commitIcon" style="vertical-align: middle;"></img>
|
| | | <span wicket:id="message">[shortlog commit link]</span><br/>
|
| | |
| | | </td>
|
| | | <td class="rightAlign" style="width:7em;vertical-align: middle;">
|
| | | <span class="link">
|
| | | <a wicket:id="view"><wicket:message key="gb.view"></wicket:message></a> | <a wicket:id="diff"><wicket:message key="gb.diff"></wicket:message></a> | <a wicket:id="tree"><wicket:message key="gb.tree"></wicket:message></a>
|
| | | <a wicket:id="view" target="_blank"><wicket:message key="gb.view"></wicket:message></a> | <a wicket:id="diff" target="_blank"><wicket:message key="gb.diff"></wicket:message></a> | <a wicket:id="tree" target="_blank"><wicket:message key="gb.tree"></wicket:message></a>
|
| | | </span>
|
| | | </td>
|
| | | </wicket:fragment>
|
| | |
| | | import com.gitblit.models.Activity.RepositoryCommit;
|
| | | import com.gitblit.utils.StringUtils;
|
| | | import com.gitblit.wicket.GitBlitWebSession;
|
| | | import com.gitblit.wicket.GravatarImage;
|
| | | import com.gitblit.wicket.WicketUtils;
|
| | | import com.gitblit.wicket.pages.CommitDiffPage;
|
| | | import com.gitblit.wicket.pages.CommitPage;
|
| | |
| | | String author = commit.getAuthorIdent().getName();
|
| | | LinkPanel authorLink = new LinkPanel("author", "list", author,
|
| | | SearchPage.class, WicketUtils.newSearchParameter(commit.repository,
|
| | | commit.getName(), author, Constants.SearchType.AUTHOR));
|
| | | commit.getName(), author, Constants.SearchType.AUTHOR), true);
|
| | | setPersonSearchTooltip(authorLink, author, Constants.SearchType.AUTHOR);
|
| | | fragment.add(authorLink);
|
| | |
|
| | | // repository
|
| | | LinkPanel repositoryLink = new LinkPanel("repository", null,
|
| | | commit.repository, SummaryPage.class,
|
| | | WicketUtils.newRepositoryParameter(commit.repository));
|
| | | WicketUtils.newRepositoryParameter(commit.repository), true);
|
| | | WicketUtils.setCssBackground(repositoryLink, commit.repository);
|
| | | fragment.add(repositoryLink);
|
| | |
|
| | | // repository branch
|
| | | LinkPanel branchLink = new LinkPanel("branch", "list", commit.branch,
|
| | | LogPage.class, WicketUtils.newObjectParameter(commit.repository,
|
| | | commit.branch));
|
| | | commit.branch), true);
|
| | | WicketUtils.setCssStyle(branchLink, "color: #008000;");
|
| | | fragment.add(branchLink);
|
| | |
|
| | | LinkPanel commitid = new LinkPanel("commitid", "list subject",
|
| | | commit.getShortName(), CommitPage.class,
|
| | | WicketUtils.newObjectParameter(commit.repository, commit.getName()));
|
| | | WicketUtils.newObjectParameter(commit.repository, commit.getName()), true);
|
| | | fragment.add(commitid);
|
| | |
|
| | | // message/commit link
|
| | |
| | | String trimmedMessage = StringUtils.trimShortLog(shortMessage);
|
| | | LinkPanel shortlog = new LinkPanel("message", "list subject",
|
| | | trimmedMessage, CommitPage.class, WicketUtils.newObjectParameter(
|
| | | commit.repository, commit.getName()));
|
| | | commit.repository, commit.getName()), true);
|
| | | if (!shortMessage.equals(trimmedMessage)) {
|
| | | WicketUtils.setHtmlTooltip(shortlog, shortMessage);
|
| | | }
|
New file |
| | |
| | | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
| | | <html xmlns="http://www.w3.org/1999/xhtml" |
| | | xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.3-strict.dtd" |
| | | xml:lang="en" |
| | | lang="en">
|
| | | <wicket:panel>
|
| | | <a href="#" wicket:id="link"><img wicket:id="image"></img></a>
|
| | | </wicket:panel>
|
| | | </html> |
New file |
| | |
| | | /*
|
| | | * Copyright 2011 gitblit.com.
|
| | | *
|
| | | * Licensed under the Apache License, Version 2.0 (the "License");
|
| | | * you may not use this file except in compliance with the License.
|
| | | * You may obtain a copy of the License at
|
| | | *
|
| | | * http://www.apache.org/licenses/LICENSE-2.0
|
| | | *
|
| | | * Unless required by applicable law or agreed to in writing, software
|
| | | * distributed under the License is distributed on an "AS IS" BASIS,
|
| | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| | | * See the License for the specific language governing permissions and
|
| | | * limitations under the License.
|
| | | */
|
| | | package com.gitblit.wicket.panels;
|
| | |
|
| | | import java.text.MessageFormat;
|
| | |
|
| | | import org.apache.wicket.AttributeModifier;
|
| | | import org.apache.wicket.behavior.SimpleAttributeModifier;
|
| | | import org.apache.wicket.markup.html.image.Image;
|
| | | import org.apache.wicket.markup.html.link.BookmarkablePageLink;
|
| | | import org.apache.wicket.markup.html.link.Link;
|
| | | import org.apache.wicket.markup.html.panel.Panel;
|
| | | import org.apache.wicket.model.Model;
|
| | | import org.eclipse.jgit.lib.PersonIdent;
|
| | |
|
| | | import com.gitblit.GitBlit;
|
| | | import com.gitblit.Keys;
|
| | | import com.gitblit.utils.ActivityUtils;
|
| | | import com.gitblit.utils.StringUtils;
|
| | | import com.gitblit.wicket.WicketUtils;
|
| | | import com.gitblit.wicket.pages.GravatarProfilePage;
|
| | |
|
| | | /**
|
| | | * Represents a Gravatar image and links to the Gravatar profile page.
|
| | | * |
| | | * @author James Moger
|
| | | * |
| | | */
|
| | | public class GravatarImage extends Panel {
|
| | |
|
| | | private static final long serialVersionUID = 1L;
|
| | |
|
| | | public GravatarImage(String id, PersonIdent person) {
|
| | | this(id, person, 0);
|
| | | }
|
| | |
|
| | | public GravatarImage(String id, PersonIdent person, int width) {
|
| | | super(id);
|
| | |
|
| | | String email = person.getEmailAddress().toLowerCase();
|
| | | String hash = StringUtils.getMD5(email);
|
| | | Link<Void> link = new BookmarkablePageLink<Void>("link", GravatarProfilePage.class,
|
| | | WicketUtils.newObjectParameter(hash));
|
| | | link.add(new SimpleAttributeModifier("target", "_blank"));
|
| | | String url = ActivityUtils.getGravatarThumbnailUrl(email, width);
|
| | | Image image = new Image("image");
|
| | | image.add(new AttributeModifier("src", true, new Model<String>(url)));
|
| | | WicketUtils.setCssClass(image, "gravatar");
|
| | | link.add(image);
|
| | | WicketUtils.setHtmlTooltip(link,
|
| | | MessageFormat.format("View Gravatar profile for {0}", person.getName()));
|
| | | add(link);
|
| | | setVisible(GitBlit.getBoolean(Keys.web.allowGravatar, true));
|
| | | }
|
| | | } |
| | |
| | |
|
| | | public LinkPanel(String wicketId, String linkCssClass, String label,
|
| | | Class<? extends WebPage> clazz) {
|
| | | this(wicketId, linkCssClass, new Model<String>(label), clazz, null);
|
| | | this(wicketId, linkCssClass, new Model<String>(label), clazz, null, false);
|
| | | }
|
| | |
|
| | | public LinkPanel(String wicketId, String linkCssClass, String label,
|
| | | Class<? extends WebPage> clazz, PageParameters parameters) {
|
| | | this(wicketId, linkCssClass, new Model<String>(label), clazz, parameters);
|
| | | this(wicketId, linkCssClass, new Model<String>(label), clazz, parameters, false);
|
| | | }
|
| | |
|
| | | public LinkPanel(String wicketId, String linkCssClass, String label,
|
| | | Class<? extends WebPage> clazz, PageParameters parameters, boolean newWindow) {
|
| | | this(wicketId, linkCssClass, new Model<String>(label), clazz, parameters, newWindow);
|
| | | }
|
| | |
|
| | | public LinkPanel(String wicketId, String linkCssClass, IModel<String> model,
|
| | | Class<? extends WebPage> clazz, PageParameters parameters) {
|
| | | this(wicketId, linkCssClass, model, clazz, parameters, false);
|
| | | }
|
| | |
|
| | | public LinkPanel(String wicketId, String linkCssClass, IModel<String> model,
|
| | | Class<? extends WebPage> clazz, PageParameters parameters, boolean newWindow) {
|
| | | super(wicketId);
|
| | | this.labelModel = model;
|
| | | Link<Void> link = null;
|
| | |
| | | } else {
|
| | | link = new BookmarkablePageLink<Void>("link", clazz, parameters);
|
| | | }
|
| | | if (newWindow) {
|
| | | link.add(new SimpleAttributeModifier("target", "_blank"));
|
| | | }
|
| | | if (linkCssClass != null) {
|
| | | link.add(new SimpleAttributeModifier("class", linkCssClass));
|
| | | }
|
New file |
| | |
| | | /*
|
| | | * Copyright 2011 gitblit.com.
|
| | | *
|
| | | * Licensed under the Apache License, Version 2.0 (the "License");
|
| | | * you may not use this file except in compliance with the License.
|
| | | * You may obtain a copy of the License at
|
| | | *
|
| | | * http://www.apache.org/licenses/LICENSE-2.0
|
| | | *
|
| | | * Unless required by applicable law or agreed to in writing, software
|
| | | * distributed under the License is distributed on an "AS IS" BASIS,
|
| | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| | | * See the License for the specific language governing permissions and
|
| | | * limitations under the License.
|
| | | */
|
| | | package com.gitblit.tests;
|
| | |
|
| | | import java.io.IOException;
|
| | |
|
| | | import junit.framework.TestCase;
|
| | |
|
| | | import com.gitblit.models.GravatarProfile;
|
| | | import com.gitblit.utils.ActivityUtils;
|
| | |
|
| | | public class ActivityTest extends TestCase {
|
| | |
|
| | | public void testGravatarProfile() throws IOException { |
| | | GravatarProfile profile = ActivityUtils.getGravatarProfile("beau@dentedreality.com.au");
|
| | | assertEquals("beau", profile.preferredUsername);
|
| | | }
|
| | | } |