diff --git a/android/README.txt b/android/README.txt
index e8886a579..eeb48885b 100644
--- a/android/README.txt
+++ b/android/README.txt
@@ -1,9 +1,13 @@
-These instructions are for the 1.5 SDK.
+These instructions are for the 1.5 Android SDK.
The build file is not compatible with the 1.1 SDK any more.
+1.6 and 2.0 SDKs are untested.
#Unzip the android SDK in ../../
#So then the android tools will be in ../../android-sdk-linux_x86-1.5_r2/tools/
+# create a file local.properties with the following line:
+# sdk-location=/path/to/your/android-sdk-linux_x86-1.5_r2
+
#then build the android apk file:
ant debug
diff --git a/apps/routerconsole/java/bmsg.sh b/apps/routerconsole/java/bmsg.sh
index e66bcc317..989bc1a30 100644
--- a/apps/routerconsole/java/bmsg.sh
+++ b/apps/routerconsole/java/bmsg.sh
@@ -19,6 +19,20 @@ CLASS=net.i2p.router.web.messages
TMPFILE=build/javafiles.txt
export TZ=UTC
+#
+# generate strings/Countries.java from ../../../installer/resources/countries.txt
+#
+CFILE=../../../installer/resources/countries.txt
+JFILE=build/Countries.java
+if [ $CFILE -nt $JFILE -o ! -s $JFILE ]
+then
+ mkdir -p build
+ echo '// Automatically generated pseudo-java for xgettext - do not edit' > $JFILE
+ echo '// Translators may wish to translate a few of these, do not bother to translate all of them!!' >> $JFILE
+ sed 's/..,\(..*\)/_("\1");/' $CFILE >> $JFILE
+fi
+
+JPATHS="src ../jsp/WEB-INF strings $JFILE"
for i in ../locale/messages_*.po
do
# get language
@@ -26,7 +40,7 @@ do
LG=${LG%.po}
# make list of java files newer than the .po file
- find src ../jsp/WEB-INF strings -name *.java -newer $i > $TMPFILE
+ find $JPATHS -name *.java -newer $i > $TMPFILE
if [ -s build/obj/net/i2p/router/web/messages_$LG.class -a \
build/obj/net/i2p/router/web/messages_$LG.class -nt $i -a \
! -s $TMPFILE ]
@@ -48,7 +62,7 @@ do
# In a jsp, you must use a helper or handler that has the context set.
# To start a new translation, copy the header from an old translation to the new .po file,
# then ant distclean updater.
- find src ../jsp/WEB-INF strings -name *.java > $TMPFILE
+ find $JPATHS -name *.java > $TMPFILE
xgettext -f $TMPFILE -F -L java --from-code=UTF-8 \
--keyword=_ --keyword=_x --keyword=intl._ --keyword=intl.title \
--keyword=handler._ --keyword=formhandler._ \
diff --git a/apps/routerconsole/java/bundle-messages.sh b/apps/routerconsole/java/bundle-messages.sh
index 82071200b..cb08afe2d 100755
--- a/apps/routerconsole/java/bundle-messages.sh
+++ b/apps/routerconsole/java/bundle-messages.sh
@@ -8,6 +8,20 @@ CLASS=net.i2p.router.web.messages
TMPFILE=build/javafiles.txt
export TZ=UTC
+#
+# generate strings/Countries.java from ../../../installer/resources/countries.txt
+#
+CFILE=../../../installer/resources/countries.txt
+JFILE=build/Countries.java
+if [ $CFILE -nt $JFILE -o ! -s $JFILE ]
+then
+ mkdir -p build
+ echo '// Automatically generated pseudo-java for xgettext - do not edit' > $JFILE
+ echo '// Translators may wish to translate a few of these, do not bother to translate all of them!!' >> $JFILE
+ sed 's/..,\(..*\)/_("\1");/' $CFILE >> $JFILE
+fi
+
+JPATHS="src ../jsp/WEB-INF strings $JFILE"
for i in ../locale/messages_*.po
do
# get language
@@ -15,7 +29,7 @@ do
LG=${LG%.po}
# make list of java files newer than the .po file
- find src ../jsp/WEB-INF strings -name *.java -newer $i > $TMPFILE
+ find $JPATHS -name *.java -newer $i > $TMPFILE
if [ -s build/obj/net/i2p/router/web/messages_$LG.class -a \
build/obj/net/i2p/router/web/messages_$LG.class -nt $i -a \
! -s $TMPFILE ]
@@ -37,7 +51,7 @@ do
# In a jsp, you must use a helper or handler that has the context set.
# To start a new translation, copy the header from an old translation to the new .po file,
# then ant distclean updater.
- find src ../jsp/WEB-INF strings -name *.java > $TMPFILE
+ find $JPATHS -name *.java > $TMPFILE
xgettext -f $TMPFILE -F -L java --from-code=UTF-8 \
--keyword=_ --keyword=_x --keyword=intl._ --keyword=intl.title \
--keyword=handler._ --keyword=formhandler._ \
diff --git a/apps/routerconsole/java/src/net/i2p/router/web/NetDbHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/NetDbHelper.java
index fd49aa7ad..ef61f0663 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/NetDbHelper.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/NetDbHelper.java
@@ -7,13 +7,17 @@ import java.io.OutputStreamWriter;
public class NetDbHelper extends HelperBase {
private String _routerPrefix;
- private boolean _full = false;
+ private int _full;
private boolean _lease = false;
public NetDbHelper() {}
public void setRouter(String r) { _routerPrefix = r; }
- public void setFull(String f) { _full = "1".equals(f); }
+ public void setFull(String f) {
+ try {
+ _full = Integer.parseInt(f);
+ } catch (NumberFormatException nfe) {}
+ }
public void setLease(String l) { _lease = "1".equals(l); }
public String getNetDbSummary() {
diff --git a/apps/routerconsole/java/src/net/i2p/router/web/NetDbRenderer.java b/apps/routerconsole/java/src/net/i2p/router/web/NetDbRenderer.java
index e551b15f0..4ef42c008 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/NetDbRenderer.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/NetDbRenderer.java
@@ -77,10 +77,6 @@ public class NetDbRenderer {
out.flush();
}
- public void renderStatusHTML(Writer out) throws IOException {
- renderStatusHTML(out, true);
- }
-
public void renderLeaseSetHTML(Writer out) throws IOException {
StringBuilder buf = new StringBuilder(4*1024);
buf.append("
" + _("Network Database Contents") + "
\n");
@@ -131,7 +127,10 @@ public class NetDbRenderer {
out.flush();
}
- public void renderStatusHTML(Writer out, boolean full) throws IOException {
+ /**
+ * @param mode 0: our info and charts only; 1: full routerinfos and charts; 2: abbreviated routerinfos and charts
+ */
+ public void renderStatusHTML(Writer out, int mode) throws IOException {
out.write("\n");
if (!_context.netDb().isInitialized()) {
out.write(_("Not initialized"));
@@ -139,13 +138,16 @@ public class NetDbRenderer {
return;
}
+ boolean full = mode == 1;
+ boolean shortStats = mode == 2;
+ boolean showStats = full || shortStats;
Hash us = _context.routerHash();
out.write("\n");
+ out.write("?f=1#routers\" >" + _("Show all routers with full stats"));
+ out.write(")\n");
StringBuilder buf = new StringBuilder(8192);
RouterInfo ourInfo = _context.router().getRouterInfo();
@@ -163,9 +165,11 @@ public class NetDbRenderer {
Hash key = ri.getIdentity().getHash();
boolean isUs = key.equals(us);
if (!isUs) {
- renderRouterInfo(buf, ri, false, full);
- out.write(buf.toString());
- buf.setLength(0);
+ if (showStats) {
+ renderRouterInfo(buf, ri, false, full);
+ out.write(buf.toString());
+ buf.setLength(0);
+ }
String routerVersion = ri.getOption("router.version");
if (routerVersion != null)
versions.increment(routerVersion);
@@ -194,14 +198,14 @@ public class NetDbRenderer {
List countryList = new ArrayList(countries.objects());
if (countryList.size() > 0) {
- Collections.sort(countryList);
+ Collections.sort(countryList, new CountryComparator());
buf.append("\n");
buf.append("" + _("Country") + " | " + _("Count") + " |
\n");
for (String country : countryList) {
int num = countries.count(country);
buf.append(" ");
- buf.append(_context.commSystem().getCountryName(country));
+ buf.append(_(_context.commSystem().getCountryName(country)));
buf.append(" | ").append(num).append(" |
\n");
}
buf.append("
\n");
@@ -211,6 +215,14 @@ public class NetDbRenderer {
out.flush();
}
+ /** sort by translated country name */
+ private class CountryComparator implements Comparator {
+ public int compare(Object l, Object r) {
+ return _(_context.commSystem().getCountryName((String)l))
+ .compareTo(_(_context.commSystem().getCountryName((String)r)));
+ }
+ }
+
/**
* Be careful to use stripHTML for any displayed routerInfo data
* to prevent vulnerabilities
diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ProfileOrganizerRenderer.java b/apps/routerconsole/java/src/net/i2p/router/web/ProfileOrganizerRenderer.java
index f7cb64a0a..fe8a823b2 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/ProfileOrganizerRenderer.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/ProfileOrganizerRenderer.java
@@ -171,28 +171,24 @@ class ProfileOrganizerRenderer {
buf.append("").append(_("Floodfill and Integrated Peers")).append("
\n");
buf.append("");
- buf.append("");
- buf.append("Peer | ");
- buf.append("Caps | ");
- buf.append("Integ. Value | ");
- buf.append("Last Heard About | ");
- buf.append("Last Heard From | ");
-// "Last Successful Send | " +
- buf.append("Last Good Send | ");
-// "Last Failed Send | " +
- buf.append("Last Bad Send | ");
- buf.append("10m Resp. Time | ");
- buf.append("1h Resp. Time | ");
- buf.append("1d Resp. Time | ");
-// "Successful Lookups | " +
- buf.append("Good Lookups | ");
-// "Failed Lookups | " +
- buf.append("Bad Lookups | ");
- buf.append("New Stores | ");
- buf.append("Old Stores | ");
- buf.append("1h Fail Rate | ");
- buf.append("1d Fail Rate | ");
- buf.append("
");
+ buf.append("");
+ buf.append("").append(_("Peer")).append(" | ");
+ buf.append("").append(_("Caps")).append(" | ");
+ buf.append("").append(_("Integ. Value")).append(" | ");
+ buf.append("").append(_("Last Heard About")).append(" | ");
+ buf.append("").append(_("Last Heard From")).append(" | ");
+ buf.append("").append(_("Last Good Send")).append(" | ");
+ buf.append("").append(_("Last Bad Send")).append(" | ");
+ buf.append("").append(_("10m Resp. Time")).append(" | ");
+ buf.append("").append(_("1h Resp. Time")).append(" | ");
+ buf.append("").append(_("1d Resp. Time")).append(" | ");
+ buf.append("").append(_("Last Good Lookup")).append(" | ");
+ buf.append("").append(_("Last Bad Lookup")).append(" | ");
+ buf.append("").append(_("Last Good Store")).append(" | ");
+ buf.append("").append(_("Last Bad Store")).append(" | ");
+ buf.append("").append(_("1h Fail Rate")).append(" | ");
+ buf.append("").append(_("1d Fail Rate")).append(" | ");
+ buf.append("
");
for (Iterator iter = integratedPeers.iterator(); iter.hasNext();) {
PeerProfile prof = (PeerProfile)iter.next();
Hash peer = prof.getPeer();
@@ -221,10 +217,14 @@ class ProfileOrganizerRenderer {
buf.append("").append(avg(prof, 24*60*60*1000l)).append(" | ");
DBHistory dbh = prof.getDBHistory();
if (dbh != null) {
- buf.append("").append(dbh.getSuccessfulLookups()).append(" | ");
- buf.append("").append(dbh.getFailedLookups()).append(" | ");
- buf.append("").append(dbh.getUnpromptedDbStoreNew()).append(" | ");
- buf.append("").append(dbh.getUnpromptedDbStoreOld()).append(" | ");
+ time = now - dbh.getLastLookupSuccessful();
+ buf.append("").append(DataHelper.formatDuration(time)).append(" | ");
+ time = now - dbh.getLastLookupFailed();
+ buf.append("").append(DataHelper.formatDuration(time)).append(" | ");
+ time = now - dbh.getLastStoreSuccessful();
+ buf.append("").append(DataHelper.formatDuration(time)).append(" | ");
+ time = now - dbh.getLastStoreFailed();
+ buf.append("").append(DataHelper.formatDuration(time)).append(" | ");
buf.append("").append(davg(dbh, 60*60*1000l)).append(" | ");
buf.append("").append(davg(dbh, 24*60*60*1000l)).append(" | ");
} else {
@@ -242,13 +242,13 @@ class ProfileOrganizerRenderer {
buf.append("").append(_("Integration")).append(": ").append(num(_organizer.getIntegrationThreshold()))
.append(" (").append(integrated).append(' ').append(_(" well integrated peers")).append(")");
buf.append("").append(_("Definitions")).append(":
");
- buf.append("- ").append(_("groups")).append(": ").append(_("as determined by the profile organizer")).append("
");
- buf.append("- ").append(_("caps")).append(": ").append(_("capabilities in the netDb, not used to determine profiles")).append("
");
- buf.append("- ").append(_("speed")).append(": ").append(_("peak throughput (bytes per second) over a 1 minute period that the peer has sustained in a single tunnel")).append("
");
- buf.append("- ").append(_("capacity")).append(": ").append(_("how many tunnels can we ask them to join in an hour?")).append("
");
- buf.append("- ").append(_("integration")).append(": ").append(_("how many new peers have they told us about lately?")).append("
");
- buf.append("- ").append(_("status")).append(": ").append(_("is the peer banned, or unreachable, or failing tunnel tests?")).append("
");
- buf.append("
");
+ buf.append("").append(_("groups")).append(": ").append(_("as determined by the profile organizer")).append("");
+ buf.append("").append(_("caps")).append(": ").append(_("capabilities in the netDb, not used to determine profiles")).append("");
+ buf.append("").append(_("speed")).append(": ").append(_("peak throughput (bytes per second) over a 1 minute period that the peer has sustained in a single tunnel")).append("");
+ buf.append("").append(_("capacity")).append(": ").append(_("how many tunnels can we ask them to join in an hour?")).append("");
+ buf.append("").append(_("integration")).append(": ").append(_("how many new peers have they told us about lately?")).append("");
+ buf.append("").append(_("status")).append(": ").append(_("is the peer banned, or unreachable, or failing tunnel tests?")).append("");
+ buf.append("");
out.write(buf.toString());
out.flush();
}
diff --git a/apps/routerconsole/java/src/net/i2p/router/web/StatsGenerator.java b/apps/routerconsole/java/src/net/i2p/router/web/StatsGenerator.java
index 0faa74542..2228f6078 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/StatsGenerator.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/StatsGenerator.java
@@ -29,7 +29,7 @@ public class StatsGenerator {
public void generateStatsPage(Writer out) throws IOException {
StringBuilder buf = new StringBuilder(16*1024);
- buf.append("