Browse Source

RSS syndication feature. Documentation. CSS tweaks.

tags/v0.5.0
James Moger 13 years ago
parent
commit
c2272275ca

+ 16
- 0
NOTICE View File

@@ -95,6 +95,22 @@ JSch
http://www.jcraft.com/jsch
---------------------------------------------------------------------------
Rome
---------------------------------------------------------------------------
Rome RSS and Atom Java Utilities, released under the
Apache Software License, Version 1.1.
http://rome.dev.java.net
---------------------------------------------------------------------------
jdom
---------------------------------------------------------------------------
jdom xml library, released under the
Apache-style Software License.
http://www.jdom.org
---------------------------------------------------------------------------
JUnit
---------------------------------------------------------------------------

+ 3
- 0
distrib/gitblit.properties View File

@@ -64,6 +64,9 @@ web.allowAdministration = true
# Allow dyanamic zip downloads.
web.allowZipDownloads = true
# Default number of entries to include in RSS/Atom Syndication links
web.syndicationEntries = 25
# This is the message display above the repositories table.
# This can point to a file with Markdown content.
# Specifying "gitblit" uses the internal welcome message.

+ 4
- 0
docs/00_index.mkd View File

@@ -32,6 +32,7 @@ sources @ [Github][gitbltsrc]
- Automatically generates a self-signed certificate for https communications
- Git-notes support
- Branch metrics (uses Google Charts)
- HEAD and branch RSS feeds
- Blame annotations view
- Dates can optionally be displayed using the browser's reported timezone
- Display of Author and Committer email addresses can be disabled
@@ -60,6 +61,7 @@ sources @ [Github][gitbltsrc]
- Gitblit may have security holes. Patches welcome. :)
### Todo List
- Custom BASIC authentication servlet or servlet filter
- Code documentation
- Unit testing
- Update Build.java to JGit 1.0.0, when its released
@@ -110,6 +112,8 @@ The following dependencies are automatically downloaded from the Apache Maven re
- [JCommander](http://jcommander.org) (Apache 2.0)
- [BouncyCastle](http://www.bouncycastle.org) (MIT/X11)
- [JSch - Java Secure Channel](http://www.jcraft.com/jsch) (BSD)
- [Rome](http://rome.dev.java.net) (Apache 1.1)
- [jdom](http://www.jdom.org) (Apache-style JDOM license)
### Other Build Dependencies
- [Fancybox image viewer](http://fancybox.net) (MIT and GPL dual-licensed)

+ 1
- 1
docs/00_setup.mkd View File

@@ -91,7 +91,7 @@ You must tell Git not to verify the self-signed certificate in order to perform
3. <pre>Key = *http.sslVerify*
Value = *false*</pre>
- Command-line Git ([Git-Config Manual Page](http://www.kernel.org/pub/software/scm/git/docs/git-config.html))
<pre>git-config --global --bool --add http.sslVerify false</pre>
<pre>git config --global --bool --add http.sslVerify false</pre>
### Cloning an Access Restricted Repository
- Eclipse/Egit<br/>Nothing special to configure, EGit figures out everything.

+ 1
- 2
docs/01_faq.mkd View File

@@ -100,5 +100,4 @@ Yes. Most messages are localized to a standard Java properties file.
[jgit]: http://eclipse.org/jgit "Eclipse JGit Site"
[git]: http://git-scm.com "Official Git Site"
[mina]: http://mina.apache.org "Apache Mina"
[bouncycastle]: http://bouncycastle.org "The Legion of the Bouncy Castle"
[hg4j]: http://code.google.com/p/hg4j/ "hg4j"
[bouncycastle]: http://bouncycastle.org "The Legion of the Bouncy Castle"

+ 15
- 1
src/com/gitblit/Build.java View File

@@ -61,6 +61,8 @@ public class Build {
downloadFromApache(MavenObject.BOUNCYCASTLE, BuildType.RUNTIME);
downloadFromApache(MavenObject.BOUNCYCASTLE_MAIL, BuildType.RUNTIME);
downloadFromApache(MavenObject.JSCH, BuildType.RUNTIME);
downloadFromApache(MavenObject.ROME, BuildType.RUNTIME);
downloadFromApache(MavenObject.JDOM, BuildType.RUNTIME);
downloadFromEclipse(MavenObject.JGIT, BuildType.RUNTIME);
downloadFromEclipse(MavenObject.JGIT_HTTP, BuildType.RUNTIME);
@@ -82,7 +84,9 @@ public class Build {
downloadFromApache(MavenObject.BOUNCYCASTLE, BuildType.COMPILETIME);
downloadFromApache(MavenObject.BOUNCYCASTLE_MAIL, BuildType.COMPILETIME);
downloadFromApache(MavenObject.JSCH, BuildType.COMPILETIME);
downloadFromApache(MavenObject.ROME, BuildType.COMPILETIME);
downloadFromApache(MavenObject.JDOM, BuildType.COMPILETIME);
downloadFromEclipse(MavenObject.JGIT, BuildType.COMPILETIME);
downloadFromEclipse(MavenObject.JGIT_HTTP, BuildType.COMPILETIME);
@@ -401,6 +405,16 @@ public class Build {
"1.4.0", 181000, 0, 0, "eb47e8cad2dd7f92fd7e77df1d1529cae87361f7",
"",
"");
public static final MavenObject ROME = new MavenObject("rome", "rome", "rome",
"0.9", 208000, 196000, 407000, "dee2705dd01e79a5a96a17225f5a1ae30470bb18",
"226f851dc44fd94fe70b9c471881b71f88949cbf",
"8d7d867b97eeb3a9196c3926da550ad042941c1b");
public static final MavenObject JDOM = new MavenObject("jdom", "org/jdom", "jdom",
"1.1", 153000, 235000, 445000, "1d04c0f321ea337f3661cf7ede8f4c6f653a8fdd",
"a7ed425c4c46605b8f2bf2ee118c1609682f4f2c",
"f3df91edccba2f07a0fced70887c2f7b7836cb75");
public final String name;
public final String group;

+ 2
- 0
src/com/gitblit/Constants.java View File

@@ -36,6 +36,8 @@ public class Constants {
public static final String GIT_SERVLET_PATH = "/git/";
public static final String ZIP_SERVLET_PATH = "/zip/";
public static final String SYNDICATION_SERVLET_PATH = "/feed/";
public static final String BORDER = "***********************************************************";

+ 4
- 1
src/com/gitblit/DownloadZipServlet.java View File

@@ -41,7 +41,10 @@ public class DownloadZipServlet extends HttpServlet {
}
public static String asLink(String baseURL, String repository, String objectId, String path) {
return baseURL + (baseURL.endsWith("/") ? "" : "/") + "zip?r=" + repository
if (baseURL.charAt(baseURL.length() - 1) == '/') {
baseURL = baseURL.substring(0, baseURL.length() - 1);
}
return baseURL + Constants.ZIP_SERVLET_PATH + "?r=" + repository
+ (path == null ? "" : ("&p=" + path))
+ (objectId == null ? "" : ("&h=" + objectId));
}

+ 3
- 0
src/com/gitblit/GitBlitServer.java View File

@@ -240,6 +240,9 @@ public class GitBlitServer {
// Zip Servlet
rootContext.addServlet(DownloadZipServlet.class, Constants.ZIP_SERVLET_PATH + "*");
// Syndication Servlet
rootContext.addServlet(SyndicationServlet.class, Constants.SYNDICATION_SERVLET_PATH + "*");
// Git Servlet
ServletHolder gitServlet = null;
String gitServletPathSpec = Constants.GIT_SERVLET_PATH + "*";

+ 1
- 1
src/com/gitblit/JettyLoginService.java View File

@@ -412,7 +412,7 @@ public class JettyLoginService extends MappedLoginService implements ILoginServi
FileWriter writer = new FileWriter(realmFileCopy);
properties
.store(writer,
"# Git:Blit realm file format: username=password,\\#permission,repository1,repository2...");
"# Gitblit realm file format: username=password,\\#permission,repository1,repository2...");
writer.close();
if (realmFileCopy.exists() && realmFileCopy.length() > 0) {
if (realmFile.delete()) {

+ 91
- 0
src/com/gitblit/SyndicationServlet.java View File

@@ -0,0 +1,91 @@
/*
* 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;
import java.util.List;
import javax.servlet.http.HttpServlet;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.gitblit.models.RepositoryModel;
import com.gitblit.utils.JGitUtils;
import com.gitblit.utils.StringUtils;
import com.gitblit.utils.SyndicationUtils;
public class SyndicationServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private transient Logger logger = LoggerFactory.getLogger(SyndicationServlet.class);
public static String asLink(String baseURL, String repository, String objectId, int length) {
if (baseURL.charAt(baseURL.length() - 1) == '/') {
baseURL = baseURL.substring(0, baseURL.length() - 1);
}
return baseURL + Constants.SYNDICATION_SERVLET_PATH + "?r=" + repository
+ (objectId == null ? "" : ("&h=" + objectId)) + (length > 0 ? "&l=" + length : "");
}
private void processRequest(javax.servlet.http.HttpServletRequest request,
javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException,
java.io.IOException {
String hostUrl = request.getRequestURL().toString();
String servlet = request.getServletPath();
hostUrl = hostUrl.substring(0, hostUrl.indexOf(servlet));
String repositoryName = request.getParameter("r");
String objectId = request.getParameter("h");
String l = request.getParameter("l");
int length = GitBlit.getInteger(Keys.web.syndicationEntries, 25);
if (StringUtils.isEmpty(objectId)) {
objectId = org.eclipse.jgit.lib.Constants.HEAD;
}
if (!StringUtils.isEmpty(l)) {
try {
length = Integer.parseInt(l);
} catch (NumberFormatException x) {
}
}
// TODO confirm repository is accessible!!
Repository repository = GitBlit.self().getRepository(repositoryName);
RepositoryModel model = GitBlit.self().getRepositoryModel(repositoryName);
List<RevCommit> commits = JGitUtils.getRevLog(repository, objectId, 0, length);
try {
SyndicationUtils.toRSS(hostUrl, model.name + " " + objectId, model.description, model.name, commits, response.getOutputStream());
} catch (Exception e) {
logger.error("An error occurred during feed generation", e);
}
}
@Override
protected void doPost(javax.servlet.http.HttpServletRequest request,
javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException,
java.io.IOException {
processRequest(request, response);
}
@Override
protected void doGet(javax.servlet.http.HttpServletRequest request,
javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException,
java.io.IOException {
processRequest(request, response);
}
}

+ 69
- 0
src/com/gitblit/utils/SyndicationUtils.java View File

@@ -0,0 +1,69 @@
/*
* 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.utils;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jgit.revwalk.RevCommit;
import com.sun.syndication.feed.synd.SyndContent;
import com.sun.syndication.feed.synd.SyndContentImpl;
import com.sun.syndication.feed.synd.SyndEntry;
import com.sun.syndication.feed.synd.SyndEntryImpl;
import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.feed.synd.SyndFeedImpl;
import com.sun.syndication.io.FeedException;
import com.sun.syndication.io.SyndFeedOutput;
public class SyndicationUtils {
public static void toRSS(String hostUrl, String title, String description, String repository, List<RevCommit> commits, OutputStream os)
throws IOException, FeedException {
SyndFeed feed = new SyndFeedImpl();
feed.setFeedType("rss_1.0");
feed.setTitle(title);
feed.setLink(MessageFormat.format("{0}/summary/{1}", hostUrl, repository));
feed.setDescription(description);
List<SyndEntry> entries = new ArrayList<SyndEntry>();
for (RevCommit commit : commits) {
SyndEntry entry = new SyndEntryImpl();
entry.setTitle(commit.getShortMessage());
entry.setAuthor(commit.getAuthorIdent().getName());
entry.setLink(MessageFormat.format("{0}/commit/{1}/{2}", hostUrl, repository, commit.getName()));
entry.setPublishedDate(commit.getCommitterIdent().getWhen());
SyndContent content = new SyndContentImpl();
content.setType("text/html");
String html = StringUtils.escapeForHtml(commit.getFullMessage(), false);
content.setValue(StringUtils.breakLinesForHtml(html));
entry.setDescription(content);
entries.add(entry);
}
feed.setEntries(entries);
OutputStreamWriter writer = new OutputStreamWriter(os);
SyndFeedOutput output = new SyndFeedOutput();
output.output(feed, writer);
writer.close();
}
}

+ 2
- 1
src/com/gitblit/wicket/GitBlitWebApp.properties View File

@@ -98,4 +98,5 @@ gb.ownerDescription = the owner may edit repository settings
gb.blob = blob
gb.commitActivityTrend = commit activity trend
gb.commitActivityDOW = commit activity by day of week
gb.commitActivityAuthors = primary authors by commit activity
gb.commitActivityAuthors = primary authors by commit activity
gb.feed = feed

+ 2
- 2
src/com/gitblit/wicket/pages/MetricsPage.java View File

@@ -134,7 +134,7 @@ public class MetricsPage extends RepositoryPage {
SimpleDateFormat sdf = new SimpleDateFormat("E");
Calendar cal = Calendar.getInstance();
List<Metric> sorted = new ArrayList<Metric>(7);
List<Metric> sorted = new ArrayList<Metric>();
int firstDayOfWeek = cal.getFirstDayOfWeek();
int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
@@ -144,7 +144,7 @@ public class MetricsPage extends RepositoryPage {
String day = sdf.format(cal.getTime());
for (Metric metric : list) {
if (metric.name.equals(day)) {
sorted.add(i, metric);
sorted.add(metric);
list.remove(metric);
break;
}

+ 8
- 5
src/com/gitblit/wicket/pages/RepositoryPage.html View File

@@ -9,15 +9,18 @@
<!-- page header bar -->
<div>
<!-- floating search form on right -->
<form wicket:id="searchForm">
<div class="search">
<div class="search">
<form wicket:id="searchForm">
<select wicket:id="searchType"/>
<input type="text" id="searchBox" wicket:id="searchBox" size="25" value=""/>
</div>
</form>
</form>
</div>
<!-- page nav links -->
<div class="page_nav">
<div class="page_nav">
<a style="text-decoration: none;" wicket:id="syndication">
<img style="border:0px;vertical-align:middle;" src="/com/gitblit/wicket/resources/feed_16x16.png"></img>
</a>
<a wicket:id="summary"><wicket:message key="gb.summary"></wicket:message></a> | <a wicket:id="log"><wicket:message key="gb.log"></wicket:message></a> | <a wicket:id="branches"><wicket:message key="gb.branches"></wicket:message></a> | <a wicket:id="tags"><wicket:message key="gb.tags"></wicket:message></a> | <a wicket:id="tree"><wicket:message key="gb.tree"></wicket:message></a> <span wicket:id="extra"><span wicket:id="extraSeparator"></span><span wicket:id="extraLink"></span></span>
</div>
</div>

+ 5
- 0
src/com/gitblit/wicket/pages/RepositoryPage.java View File

@@ -30,6 +30,7 @@ import org.apache.wicket.markup.html.form.DropDownChoice;
import org.apache.wicket.markup.html.form.StatelessForm;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
import org.apache.wicket.markup.html.link.ExternalLink;
import org.apache.wicket.markup.html.panel.Fragment;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.markup.repeater.data.DataView;
@@ -45,6 +46,7 @@ import org.slf4j.LoggerFactory;
import com.gitblit.GitBlit;
import com.gitblit.Keys;
import com.gitblit.SyndicationServlet;
import com.gitblit.models.RepositoryModel;
import com.gitblit.utils.JGitUtils;
import com.gitblit.utils.JGitUtils.SearchType;
@@ -157,6 +159,9 @@ public abstract class RepositoryPage extends BasePage {
}
};
add(extrasView);
add(new ExternalLink("syndication", SyndicationServlet.asLink(getRequest()
.getRelativePathPrefixToContextRoot(), repositoryName, null, 0)));
// disable current page
disablePageLink(getPageName());

+ 1
- 1
src/com/gitblit/wicket/panels/BranchesPanel.html View File

@@ -28,7 +28,7 @@
<!-- branch page links -->
<wicket:fragment wicket:id="branchPageLinks">
<span class="link">
<a wicket:id="log"><wicket:message key="gb.log"></wicket:message></a> | <a wicket:id="tree"><wicket:message key="gb.tree"></wicket:message></a> | <a wicket:id="metrics"><wicket:message key="gb.metrics"></wicket:message></a>
<a wicket:id="log"><wicket:message key="gb.log"></wicket:message></a> | <a wicket:id="tree"><wicket:message key="gb.tree"></wicket:message></a> | <a wicket:id="metrics"><wicket:message key="gb.metrics"></wicket:message></a> | <a wicket:id="syndication"><wicket:message key="gb.feed"></wicket:message></a>
</span>
</wicket:fragment>

+ 4
- 0
src/com/gitblit/wicket/panels/BranchesPanel.java View File

@@ -21,6 +21,7 @@ import java.util.List;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
import org.apache.wicket.markup.html.link.ExternalLink;
import org.apache.wicket.markup.html.panel.Fragment;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.markup.repeater.data.DataView;
@@ -29,6 +30,7 @@ import org.apache.wicket.model.StringResourceModel;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.Repository;
import com.gitblit.SyndicationServlet;
import com.gitblit.models.RefModel;
import com.gitblit.models.RepositoryModel;
import com.gitblit.utils.JGitUtils;
@@ -101,6 +103,8 @@ public class BranchesPanel extends BasePanel {
.newObjectParameter(model.name, entry.getName())));
fragment.add(new BookmarkablePageLink<Void>("metrics", MetricsPage.class,
WicketUtils.newObjectParameter(model.name, entry.getName())));
fragment.add(new ExternalLink("syndication", SyndicationServlet.asLink(getRequest()
.getRelativePathPrefixToContextRoot(), model.name, entry.getName(), 0)));
item.add(fragment);
} else {
Fragment fragment = new Fragment("branchLinks", "branchPanelLinks", this);

BIN
src/com/gitblit/wicket/resources/feed_16x16.png View File


+ 4
- 0
src/com/gitblit/wicket/resources/gitblit.css View File

@@ -486,6 +486,10 @@ table.plain {
padding: 8px;
}
table.plain td {
white-space: nowrap;
}
table.plain td.edit {
padding: 3px;
}

Loading…
Cancel
Save