diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/IndexBean.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/IndexBean.java index 8deb1ac99..a1a8490b2 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/IndexBean.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/IndexBean.java @@ -1339,10 +1339,10 @@ public class IndexBean { // as of 0.9.17, add a random key if not previously present byte[] rk = new byte[32]; _context.random().nextBytes(rk); - config.setProperty(OPT + p, Base64.encode(rk)); + config.setProperty(p, Base64.encode(rk)); p = OPT + "outbound.randomKey"; _context.random().nextBytes(rk); - config.setProperty(OPT + p, Base64.encode(rk)); + config.setProperty(p, Base64.encode(rk)); } } diff --git a/apps/routerconsole/java/src/net/i2p/router/news/NewsMetadata.java b/apps/routerconsole/java/src/net/i2p/router/news/NewsMetadata.java index 732b814a7..15adf5955 100644 --- a/apps/routerconsole/java/src/net/i2p/router/news/NewsMetadata.java +++ b/apps/routerconsole/java/src/net/i2p/router/news/NewsMetadata.java @@ -1,6 +1,7 @@ package net.i2p.router.news; import java.util.List; +import net.i2p.util.VersionComparator; /** * The update metadata. @@ -15,14 +16,41 @@ public class NewsMetadata { public String feedID; public long feedUpdated; - // I2P update metadata - public long date; - public String minVersion; - public String minJavaVersion; - public String i2pVersion; - public String sudTorrent; - public String su2Torrent; - public String su3Torrent; - public List su3Clearnet; - public List su3SSL; + // I2P metadata + public List releases; + + public static class Release implements Comparable { + public long date; + public String minVersion; + public String minJavaVersion; + public String i2pVersion; + public List updates; + + @Override + public int compareTo(Release other) { + // Sort latest version first. + return VersionComparator.comp(other.i2pVersion, i2pVersion); + } + } + + public static class Update implements Comparable { + public String type; + public String torrent; + public List clearnet; + public List ssl; + + @Override + public int compareTo(Update other) { + return getTypeOrder() - other.getTypeOrder(); + } + + protected int getTypeOrder() { + if ("su3".equalsIgnoreCase(type)) + return 1; + else if ("su2".equalsIgnoreCase(type)) + return 2; + else + return 3; + } + } } diff --git a/apps/routerconsole/java/src/net/i2p/router/news/NewsXMLParser.java b/apps/routerconsole/java/src/net/i2p/router/news/NewsXMLParser.java index f3b01bdd9..cb2a01c0f 100644 --- a/apps/routerconsole/java/src/net/i2p/router/news/NewsXMLParser.java +++ b/apps/routerconsole/java/src/net/i2p/router/news/NewsXMLParser.java @@ -15,6 +15,7 @@ import java.util.Set; import net.i2p.I2PAppContext; import net.i2p.util.Log; + import org.cybergarage.util.Debug; import org.cybergarage.xml.Attribute; import org.cybergarage.xml.Node; @@ -34,7 +35,7 @@ public class NewsXMLParser { private NewsMetadata _metadata; private XHTMLMode _mode; - private static final Set xhtmlWhitelist = new HashSet(Arrays.asList(new String[] { + private static final Set xhtmlWhitelist = new HashSet(Arrays.asList(new String[] { "a", "b", "br", "div", "i", "p", "span", "font", "blockquote", "hr", "del", "ins", "em", "strong", "mark", "sub", "sup", "tt", "code", "strike", "s", "u", "h4", "h5", "h6", @@ -45,7 +46,7 @@ public class NewsXMLParser { })); // http://www.w3.org/TR/html-markup/global-attributes.html#common.attrs.event-handler - private static final Set attributeBlacklist = new HashSet(Arrays.asList(new String[] { + private static final Set attributeBlacklist = new HashSet(Arrays.asList(new String[] { "onabort", "onblur", "oncanplay", "oncanplaythrough", "onchange", "onclick", "oncontextmenu", "ondblclick", "ondrag", "ondragend", "ondragenter", "ondragleave", "ondragover", "ondragstart", "ondrop", "ondurationchange", "onemptied", @@ -169,38 +170,67 @@ public class NewsXMLParser { } } - Node r = feed.getNode("i2p:release"); - if (r == null) + List releases = new ArrayList(); + List releaseNodes = getNodes(feed, "i2p:release"); + if (releaseNodes.size() == 0) throw new I2PParserException("no release data in XML"); - // release attributes - String a = r.getAttributeValue("date"); - if (a.length() > 0) { - long time = RFC3339Date.parse3339Date(a); - if (time > 0) - rv.date = time; - } - a = r.getAttributeValue("minVersion"); - if (a.length() > 0) - rv.minVersion = a; - a = r.getAttributeValue("minJavaVersion"); - if (a.length() > 0) - rv.minJavaVersion = a; - // release nodes - n = r.getNode("i2p:version"); - if (n != null) - rv.i2pVersion = n.getValue(); - List urls = getNodes(r, "i2p:torrent"); - for (Node t : urls) { - // returns "" for none - String href = t.getAttributeValue("href"); - if (href.length() > 0) { - String type = t.getAttributeValue("type"); - if (type.equals("su2")) - rv.su2Torrent = href; - else if (type.equals("su3")) - rv.su3Torrent = href; + for (Node r : releaseNodes) { + NewsMetadata.Release release = new NewsMetadata.Release(); + // release attributes + String a = r.getAttributeValue("date"); + if (a.length() > 0) { + long time = RFC3339Date.parse3339Date(a); + if (time > 0) + release.date = time; } + a = r.getAttributeValue("minVersion"); + if (a.length() > 0) + release.minVersion = a; + a = r.getAttributeValue("minJavaVersion"); + if (a.length() > 0) + release.minJavaVersion = a; + // release nodes + n = r.getNode("i2p:version"); + if (n != null) + release.i2pVersion = n.getValue(); + + List updates = new ArrayList(); + List updateNodes = getNodes(r, "i2p:update"); + if (updateNodes.size() == 0) + throw new I2PParserException("no updates in release"); + Set types = new HashSet(); + for (Node u : updateNodes) { + // returns "" for none + String type = u.getAttributeValue("type"); + if (type.isEmpty()) + throw new I2PParserException("update with no type"); + if (types.contains(type)) + throw new I2PParserException("update with duplicate type"); + NewsMetadata.Update update = new NewsMetadata.Update(); + update.type = type; + types.add(type); + int totalSources = 0; + + Node t = u.getNode("i2p:torrent"); + if (t != null) { + // returns "" for none + String href = t.getAttributeValue("href"); + if (href.length() > 0) { + update.torrent = href; + totalSources += 1; + } + } + + if (totalSources == 0) + throw new I2PParserException("no sources for update type " + type); + updates.add(update); + } + Collections.sort(updates); + release.updates = updates; + releases.add(release); } + Collections.sort(releases); + rv.releases = releases; return rv; } @@ -388,8 +418,9 @@ public class NewsXMLParser { parser.parse(new File(args[0])); NewsMetadata ud = parser.getMetadata(); List entries = parser.getEntries(); - System.out.println("Latest version is " + ud.i2pVersion); - System.out.println("Release timestamp: " + ud.date); + NewsMetadata.Release latestRelease = ud.releases.get(0); + System.out.println("Latest version is " + latestRelease.i2pVersion); + System.out.println("Release timestamp: " + latestRelease.date); System.out.println("Feed timestamp: " + ud.feedUpdated); System.out.println("Found " + entries.size() + " news entries"); for (int i = 0; i < entries.size(); i++) { diff --git a/apps/routerconsole/java/src/net/i2p/router/update/NewsFetcher.java b/apps/routerconsole/java/src/net/i2p/router/update/NewsFetcher.java index a17926ed3..f8b6fd140 100644 --- a/apps/routerconsole/java/src/net/i2p/router/update/NewsFetcher.java +++ b/apps/routerconsole/java/src/net/i2p/router/update/NewsFetcher.java @@ -1,12 +1,9 @@ package net.i2p.router.update; import java.io.BufferedWriter; -import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; -import java.io.FilterInputStream; import java.io.FileOutputStream; -import java.io.InputStream; import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; @@ -14,15 +11,12 @@ import java.io.Writer; import java.net.URI; import java.net.URISyntaxException; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.Date; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Map; -import java.util.Set; import java.util.StringTokenizer; import net.i2p.crypto.SU3File; @@ -459,22 +453,33 @@ class NewsFetcher extends UpdateRunner { */ private void outputOldNewsXML(NewsMetadata data, List entries, String sudVersion, String signingKeyName, File to) throws IOException { + NewsMetadata.Release latestRelease = data.releases.get(0); Writer out = null; try { out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(to), "UTF-8")); out.write("