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