commit 556fa300319e5cce3e224df1b79684c473e6be77 Author: Iain R. Learmonth irl@fsfe.org Date: Tue Mar 20 18:37:17 2018 +0000
Adds an ATOM feed for the News (Fixes: #23854)
This extends NewsServlet to have an ATOM output format, as well as the existing HTML output. A new JSP is used to serialize the output.
The feed has been tested to be compatible with both Firefox and Thunderbird. --- .../org/torproject/metrics/web/NewsServlet.java | 16 +++++ .../org/torproject/metrics/web/UpdateNews.java | 2 +- src/main/resources/web.xml | 1 + src/main/resources/web/jsps/news-atom.jsp | 76 ++++++++++++++++++++++ 4 files changed, 94 insertions(+), 1 deletion(-)
diff --git a/src/main/java/org/torproject/metrics/web/NewsServlet.java b/src/main/java/org/torproject/metrics/web/NewsServlet.java index 3bfb1b7..a5775dd 100644 --- a/src/main/java/org/torproject/metrics/web/NewsServlet.java +++ b/src/main/java/org/torproject/metrics/web/NewsServlet.java @@ -53,7 +53,15 @@ public class NewsServlet extends AnyServlet { @Override public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { + if (request.getRequestURI().endsWith("news.atom")) { + doGetAtom(request, response); + } else { + doGetHtml(request, response); + } + }
+ private void doGetHtml(HttpServletRequest request, + HttpServletResponse response) throws IOException, ServletException { /* Create categories based on current system time. */ Map<String, String[]> cutOffDates = new LinkedHashMap<>(); Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"), Locale.US); @@ -107,5 +115,13 @@ public class NewsServlet extends AnyServlet { request.getRequestDispatcher("WEB-INF/news.jsp").forward(request, response); } + + private void doGetAtom(HttpServletRequest request, + HttpServletResponse response) throws IOException, ServletException { + request.setAttribute("news", this.sortedNews); + request.setAttribute("updated", this.sortedNews.get(0).getStart()); + request.getRequestDispatcher("WEB-INF/news-atom.jsp").forward(request, + response); + } }
diff --git a/src/main/java/org/torproject/metrics/web/UpdateNews.java b/src/main/java/org/torproject/metrics/web/UpdateNews.java index 3705d4a..b8c95d6 100644 --- a/src/main/java/org/torproject/metrics/web/UpdateNews.java +++ b/src/main/java/org/torproject/metrics/web/UpdateNews.java @@ -116,7 +116,7 @@ public class UpdateNews { continue; } entry.addLink(link.substring(link.indexOf(" ") + 1), - link.substring(0, link.indexOf(" "))); + link.substring(0, link.indexOf(" "))); } } entry.unknown = unknown; diff --git a/src/main/resources/web.xml b/src/main/resources/web.xml index a5c3212..9c83591 100644 --- a/src/main/resources/web.xml +++ b/src/main/resources/web.xml @@ -238,6 +238,7 @@ </servlet> <servlet-mapping> <servlet-name>NewsServlet</servlet-name> + <url-pattern>/news.atom</url-pattern> <url-pattern>/news.html</url-pattern> </servlet-mapping>
diff --git a/src/main/resources/web/jsps/news-atom.jsp b/src/main/resources/web/jsps/news-atom.jsp new file mode 100644 index 0000000..0c25b72 --- /dev/null +++ b/src/main/resources/web/jsps/news-atom.jsp @@ -0,0 +1,76 @@ +<%@ page contentType="text/xml" %><?xml version="1.0"?> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> +<feed xmlns="http://www.w3.org/2005/Atom"> + <title>Tor Project</title> + <subtitle>Metrics Timeline</subtitle> + <updated><c:out value="${updated}"/>T12:00:00Z</updated> + <link href="https://metrics.torproject.org/news.atom" rel="self" /> + <link href="https://metrics.torproject.org/news.html" /> + <id>https://metrics.torproject.org/news.atom</id> + <c:forEach var="entry" items="${news}"> + <entry> + <title><c:out value="${entry.shortDescription}"/></title> + <updated><c:out value="${entry.start}"/>T12:00:00Z</updated> + <id>https://metrics.torproject.org/news.atom#<c:out value="${entry.start}"/><c:out value="${fn:substringBefore(entry.shortDescription, ' ')}"/>${fn:length(entry.shortDescription)}</id> + <content type="xhtml"> + <div xmlns="http://www.w3.org/1999/xhtml"> + <dl> + <dt>Dates</dt> + <dd> + <c:choose> + <c:when test="${empty entry.start}"> + N/A + </c:when> + <c:when test="${entry.ongoing}"> + <c:out value="${entry.start}"/> to present + </c:when> + <c:when test="${empty entry.end}"> + <c:out value="${entry.start}"/> + </c:when> + <c:otherwise> + <c:out value="${entry.start}"/> to + <c:out value="${entry.end}"/> + </c:otherwise> + </c:choose> + </dd> + <c:if test="${not empty entry.placeNames}"> + <dt>Places</dt> + <dd> + <c:forEach var="placeName" items="${entry.placeNames}"> + <c:out value="${placeName}"/> + </c:forEach> + </dd> + </c:if> + <c:if test="${not empty entry.protocols}"> + <dt>Protocols</dt> + <dd> + <c:forEach var="protocol" items="${entry.protocols}"> + <c:out value="${protocol}"/> + </c:forEach> + </dd> + </c:if> + <c:if test="${entry.unknown}"> + <dt>Unknown</dt> + <dd>Yes</dd> + </c:if> + </dl> + <c:if test="${not empty entry.links}"> + <ul> + <c:forEach var="link" items="${entry.links}"> + <li> + <a href="<c:out value='${link.target}'/>"> + <c:out value="${link.label}"/> + </a> + </li> + </c:forEach> + </ul> + </c:if> + </div> + </content> + <author> + <name>Tor Metrics</name> + </author> + </entry> + </c:forEach> +</feed>