diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ConfigHomeHandler.java b/apps/routerconsole/java/src/net/i2p/router/web/ConfigHomeHandler.java
new file mode 100644
index 0000000000..8ab8c0de44
--- /dev/null
+++ b/apps/routerconsole/java/src/net/i2p/router/web/ConfigHomeHandler.java
@@ -0,0 +1,113 @@
+package net.i2p.router.web;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.Map;
+
+import net.i2p.data.DataHelper;
+
+/**
+ * Simple home page configuration.
+ *
+ * @since 0.9
+ */
+public class ConfigHomeHandler extends FormHandler {
+
+ private Map _settings;
+
+ @Override
+ protected void processForm() {
+ if (_action == null) return;
+ String group = getJettyString("group");
+ boolean deleting = _action.equals(_("Delete selected"));
+ boolean adding = _action.equals(_("Add item"));
+ boolean restoring = _action.equals(_("Restore defaults"));
+ if (_action.equals(_("Save")) && "0".equals(group)) {
+ boolean old = _context.getBooleanProperty(HomeHelper.PROP_OLDHOME);
+ boolean nnew = getJettyString("oldHome") != null;
+ if (old != nnew) {
+ _context.router().saveConfig(HomeHelper.PROP_OLDHOME, "" + nnew);
+ addFormNotice(_("Home page changed"));
+ }
+ } else if (adding || deleting || restoring) {
+ String prop;
+ String dflt;
+ if ("1".equals(group)) {
+ prop = HomeHelper.PROP_FAVORITES;
+ dflt = HomeHelper.DEFAULT_FAVORITES;
+ } else if ("2".equals(group)) {
+ prop = HomeHelper.PROP_SERVICES;
+ dflt = HomeHelper.DEFAULT_SERVICES;
+ } else if ("3".equals(group)) {
+ prop = SearchHelper.PROP_ENGINES;
+ dflt = SearchHelper.ENGINES_DEFAULT;
+ } else {
+ addFormError("Bad group");
+ return;
+ }
+ if (restoring) {
+ _context.router().saveConfig(prop, dflt);
+ addFormNotice(_("Restored default settings"));
+ return;
+ }
+ String config = _context.getProperty(prop, dflt);
+ Collection apps;
+ if ("3".equals(group))
+ apps = HomeHelper.buildSearchApps(config);
+ else
+ apps = HomeHelper.buildApps(_context, config);
+ if (adding) {
+ String name = getJettyString("name");
+ if (name == null || name.length() <= 0) {
+ addFormError(_("No name entered"));
+ return;
+ }
+ String url = getJettyString("url");
+ if (url == null || url.length() <= 0) {
+ addFormError(_("No URL entered"));
+ return;
+ }
+ name = DataHelper.escapeHTML(name).replace(",", ","); // HomeHelper.S
+ url = DataHelper.escapeHTML(url).replace(",", ",");
+ HomeHelper.App app = new HomeHelper.App(name, "", url, "/themes/console/images/itoopie_sm.png");
+ apps.add(app);
+ addFormNotice(_("Added") + ": " + app.name);
+ } else {
+ // deleting
+ Set toDelete = new HashSet();
+ for (Object o : _settings.keySet()) {
+ if (!(o instanceof String))
+ continue;
+ String k = (String) o;
+ if (!k.startsWith("delete_"))
+ continue;
+ k = k.substring(7);
+ toDelete.add(k);
+ }
+ for (Iterator iter = apps.iterator(); iter.hasNext(); ) {
+ HomeHelper.App app = iter.next();
+ if (toDelete.contains(app.name)) {
+ iter.remove();
+ addFormNotice(_("Removed") + ": " + app.name);
+ }
+ }
+ }
+ HomeHelper.saveApps(_context, prop, apps, !("3".equals(group)));
+ } else {
+ addFormError(_("Unsupported"));
+ }
+ }
+
+ public void setSettings(Map settings) { _settings = new HashMap(settings); }
+
+ /** curses Jetty for returning arrays */
+ private String getJettyString(String key) {
+ String[] arr = (String[]) _settings.get(key);
+ if (arr == null)
+ return null;
+ return arr[0].trim();
+ }
+}
diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ConfigNavHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/ConfigNavHelper.java
index 5b6fecb8e6..eb8d504bb5 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/ConfigNavHelper.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/ConfigNavHelper.java
@@ -11,12 +11,13 @@ public class ConfigNavHelper extends HelperBase {
/** configX.jsp */
private static final String pages[] =
- {"", "net", "ui", "service", "update", "tunnels",
+ {"", "net", "ui", "home", "service", "update", "tunnels",
"clients", "peer", "keyring", "logging", "stats",
"reseed", "advanced" };
private static final String titles[] =
- {_x("Bandwidth"), _x("Network"), _x("UI"), _x("Service"), _x("Update"), _x("Tunnels"),
+ {_x("Bandwidth"), _x("Network"), _x("UI"), _x("Home Page"),
+ _x("Service"), _x("Update"), _x("Tunnels"),
_x("Clients"), _x("Peers"), _x("Keyring"), _x("Logging"), _x("Stats"),
_x("Reseeding"), _x("Advanced") };
diff --git a/apps/routerconsole/java/src/net/i2p/router/web/HomeHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/HomeHelper.java
new file mode 100644
index 0000000000..d0ab6dc759
--- /dev/null
+++ b/apps/routerconsole/java/src/net/i2p/router/web/HomeHelper.java
@@ -0,0 +1,224 @@
+package net.i2p.router.web;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+import net.i2p.router.RouterContext;
+import net.i2p.util.PortMapper;
+
+/**
+ * For /home and /confighome
+ *
+ * @since 0.9
+ */
+public class HomeHelper extends HelperBase {
+
+ private static final char S = ',';
+ private static final String I = "/themes/console/images/";
+ static final String PROP_SERVICES = "routerconsole.services";
+ static final String PROP_FAVORITES = "routerconsole.favorites";
+ static final String PROP_OLDHOME = "routerconsole.oldHomePage";
+
+ static final String DEFAULT_SERVICES =
+ _x("Addressbook") + S + _x("Manage your I2P hosts file here (I2P domain name resolution)") + S + "/susidns/index" + S + I + "book_addresses.png" + S +
+ _x("Configure Bandwidth") + S + _x("I2P Bandwidth Configuration") + S + "/config" + S + I + "wrench_orange.png" + S +
+ _x("Customize Home Page") + S + _x("I2P Home Page Configuration") + S + "/confighome" + S + I + "wrench_orange.png" + S +
+ _x("Email") + S + _x("Anonymous webmail client") + S + "/susimail/susimail" + S + I + "email.png" + S +
+ _x("Help") + S + _x("I2P Router Help") + S + "/help" + S + I + "help.png" + S +
+ _x("Router Console") + S + _x("I2P Router Console") + S + "/console" + S + I + "wrench_orange.png" + S +
+ _x("Torrents") + S + _x("Built-in anonymous BitTorrent Client") + S + "/i2psnark/" + S + I + "film.png" + S +
+ _x("Website") + S + _x("Local web server") + S + "http://127.0.0.1:7658/" + S + I + "server.png" + S +
+ "";
+
+ static final String DEFAULT_FAVORITES =
+ _x("Bug Reports") + S + _x("Bug tracker") + S + "http://trac.i2p2.i2p/report/1" + S + I + "bug.png" + S +
+ _x("Dev Forum") + S + _x("Development forum") + S + "http://zzz.i2p/" + S + I + "itoopie_sm.png" + S +
+ _x("diftracker") + S + _x("Bittorrent tracker") + S + "http://diftracker.i2p/" + S + I + "itoopie_sm.png" + S +
+ "echelon.i2p" + S + _x("I2P Applications") + S + "http://echelon.i2p/" + S + I + "itoopie_sm.png" + S +
+ _x("FAQ") + S + _x("Frequently Asked Questions") + S + "http://www.i2p2.i2p/faq" + S + I + "help.png" + S +
+ _x("Forum") + S + _x("Community forum") + S + "http://forum.i2p/" + S + I + "itoopie_sm.png" + S +
+ "i2plugins.i2p" + S + _x("I2P Plugins") + S + "http://i2plugins.i2p/" + S + I + "itoopie_sm.png" + S +
+ "ident.i2p" + S + _x("Short message service") + S + "http://ident.i2p/" + S + I + "itoopie_sm.png" + S +
+ _x("Javadocs") + S + _x("Technical documentation") + S + "http://docs.i2p-projekt.i2p/javadoc/" + S + I + "book.png" + S +
+ _x("Pastebin") + S + _x("I2P Pastebin") + S + "http://pastethis.i2p/" + S + I + "itoopie_sm.png" + S +
+ "Planet I2P" + S + _x("I2P News") + S + "http://planet.i2p/" + S + I + "itoopie_sm.png" + S +
+ _x("Postman's Tracker") + S + _x("Bittorrent tracker") + S + "http://tracker2.postman.i2p/" + S + I + "itoopie_sm.png" + S +
+ _x("Project Website") + S + _x("I2P home page") + S + "http://www.i2p2.i2p/" + S + I + "help.png" + S +
+ "stats.i2p" + S + _x("I2P Netowrk Statistics") + S + "http://stats.i2p/cgi-bin/dashboard.cgi" + S + I + "itoopie_sm.png" + S +
+ _x("Technical Docs") + S + _x("Technical documentation") + S + "http://www.i2p2.i2p/how" + S + I + "book.png" + S +
+ "";
+
+
+ public String getServices() {
+ List plugins = NavHelper.getClientApps(_context);
+ return homeTable(PROP_SERVICES, DEFAULT_SERVICES, plugins);
+ }
+
+ public String getFavorites() {
+ return homeTable(PROP_FAVORITES, DEFAULT_FAVORITES, null);
+ }
+
+ public String getConfigServices() {
+ return configTable(PROP_SERVICES, DEFAULT_SERVICES);
+ }
+
+ public String getConfigFavorites() {
+ return configTable(PROP_FAVORITES, DEFAULT_FAVORITES);
+ }
+
+ public String getConfigSearch() {
+ return configTable(SearchHelper.PROP_ENGINES, SearchHelper.ENGINES_DEFAULT);
+ }
+
+ public String getConfigHome() {
+ boolean oldHome = _context.getBooleanProperty(PROP_OLDHOME);
+ return oldHome ? "checked=\"true\"" : "";
+ }
+
+ public String getProxyStatus() {
+ int port = _context.portMapper().getPort(PortMapper.SVC_HTTP_PROXY);
+ if (port <= 0)
+ return _("The HTTP proxy is not up");
+ return "
";
+ }
+
+ private String homeTable(String prop, String dflt, Collection toAdd) {
+ String config = _context.getProperty(prop, dflt);
+ Collection apps = buildApps(_context, config);
+ if (toAdd != null)
+ apps.addAll(toAdd);
+ return renderApps(apps);
+ }
+
+ private String configTable(String prop, String dflt) {
+ String config = _context.getProperty(prop, dflt);
+ Collection apps;
+ if (prop.equals(SearchHelper.PROP_ENGINES))
+ apps = buildSearchApps(config);
+ else
+ apps = buildApps(_context, config);
+ return renderConfig(apps);
+ }
+
+ static Collection buildApps(RouterContext ctx, String config) {
+ String[] args = config.split("" + S);
+ Set apps = new TreeSet(new AppComparator());
+ for (int i = 0; i < args.length - 3; i += 4) {
+ String name = Messages.getString(args[i], ctx);
+ String desc = Messages.getString(args[i+1], ctx);
+ String url = args[i+2];
+ String icon = args[i+3];
+ apps.add(new App(name, desc, url, icon));
+ }
+ return apps;
+ }
+
+ static Collection buildSearchApps(String config) {
+ String[] args = config.split("" + S);
+ Set apps = new TreeSet(new AppComparator());
+ for (int i = 0; i < args.length - 1; i += 2) {
+ String name = args[i];
+ String url = args[i+1];
+ apps.add(new App(name, null, url, null));
+ }
+ return apps;
+ }
+
+ static void saveApps(RouterContext ctx, String prop, Collection apps, boolean full) {
+ StringBuilder buf = new StringBuilder(1024);
+ for (App app : apps) {
+ buf.append(app.name).append(S);
+ if (full)
+ buf.append(app.desc).append(S);
+ buf.append(app.url).append(S);
+ if (full)
+ buf.append(app.icon).append(S);
+ }
+ ctx.router().saveConfig(prop, buf.toString());
+ }
+
+ private static String renderApps(Collection apps) {
+ StringBuilder buf = new StringBuilder(1024);
+ buf.append("");
+ for (App app : apps) {
+ buf.append("
\n");
+ }
+ buf.append("
\n");
+ return buf.toString();
+ }
+
+ private String renderConfig(Collection apps) {
+ StringBuilder buf = new StringBuilder(1024);
+ buf.append("\n");
+ return buf.toString();
+ }
+
+ static class App {
+ public final String name;
+ public final String desc;
+ public final String url;
+ public final String icon;
+
+ public App(String name, String desc, String url, String icon) {
+ this.name = name;
+ this.desc = desc;
+ this.url = url;
+ this.icon = icon;
+ }
+ }
+
+ /** ignore case, current locale */
+ private static class AppComparator implements Comparator {
+ public int compare(App l, App r) {
+ return l.name.toLowerCase().compareTo(r.name.toLowerCase());
+ }
+ }
+}
diff --git a/apps/routerconsole/java/src/net/i2p/router/web/NavHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/NavHelper.java
index f34b1614d8..989d501303 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/NavHelper.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/NavHelper.java
@@ -36,6 +36,7 @@ public class NavHelper {
/**
* Translated string is loaded by PluginStarter
+ * @param ctx unused
*/
public static String getClientAppLinks(I2PAppContext ctx) {
if (_apps.isEmpty())
@@ -55,4 +56,34 @@ public class NavHelper {
}
return buf.toString();
}
+
+ /**
+ * For HomeHelper
+ * @param ctx unused
+ * @return non-null, possibly empty
+ * @since 0.9
+ */
+ static List getClientApps(I2PAppContext ctx) {
+ if (_apps.isEmpty())
+ return Collections.EMPTY_LIST;
+ List rv = new ArrayList(_apps.size());
+ for (Map.Entry e : _apps.entrySet()) {
+ String name = e.getKey();
+ String path = e.getValue();
+ if (path == null)
+ continue;
+ String tip = _tooltips.get(name);
+ if (tip == null)
+ tip = "";
+ // hardcoded hack
+ String icon;
+ if (path.equals("/i2pbote/index.jsp"))
+ icon = "/themes/console/images/email.png";
+ else
+ icon = "/themes/console/images/plugin.png";
+ HomeHelper.App app = new HomeHelper.App(name, tip, path, icon);
+ rv.add(app);
+ }
+ return rv;
+ }
}
diff --git a/apps/routerconsole/java/src/net/i2p/router/web/SearchHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/SearchHelper.java
new file mode 100644
index 0000000000..ff07680162
--- /dev/null
+++ b/apps/routerconsole/java/src/net/i2p/router/web/SearchHelper.java
@@ -0,0 +1,101 @@
+package net.i2p.router.web;
+
+import java.util.Map;
+import java.util.TreeMap;
+
+import net.i2p.data.DataHelper;
+import net.i2p.util.PortMapper;
+
+/**
+ * Helper for searches.
+ *
+ * @since 0.9
+ */
+public class SearchHelper extends HelperBase {
+
+ private String _engine;
+ private String _query;
+ private Map _engines = new TreeMap();
+
+ private static final char S = ',';
+ static final String PROP_ENGINES = "routerconsole.searchEngines";
+ private static final String PROP_DEFAULT = "routerconsole.searchEngine";
+
+ static final String ENGINES_DEFAULT =
+ "eepsites.i2p" + S + "http://eepsites.i2p/Content/Search/SearchResults.aspx?inpQuery=%s" + S +
+ "epsilon.i2p" + S + "http://epsilon.i2p/search.jsp?q=%s" + S +
+ "sprongle.i2p" + S + "http://sprongle.i2p/sprongle.php?q=%s" + S +
+ "";
+
+ public void setEngine(String s) {
+ _engine = s;
+ if (s != null) {
+ String dflt = _context.getProperty(PROP_DEFAULT);
+ if (!s.equals(dflt))
+ _context.router().saveConfig(PROP_DEFAULT, s);
+ }
+ }
+
+ public void setQuery(String s) {
+ _query = s;
+ }
+
+ private void buildEngineMap() {
+ String config = _context.getProperty(PROP_ENGINES, ENGINES_DEFAULT);
+ String[] args = config.split("" + S);
+ for (int i = 0; i < args.length - 1; i += 2) {
+ String name = args[i];
+ String url = args[i+1];
+ _engines.put(name, url);
+ }
+ }
+
+ public String getSelector() {
+ buildEngineMap();
+ if (_engines.isEmpty())
+ return "No search engines specified";
+ String dflt = _context.getProperty(PROP_DEFAULT);
+ if (dflt == null || !_engines.containsKey(dflt)) {
+ // pick a randome one as default and save it
+ int idx = _context.random().nextInt(_engines.size());
+ int i = 0;
+ for (String name : _engines.keySet()) {
+ dflt = name;
+ if (i++ >= idx) {
+ _context.router().saveConfig(PROP_DEFAULT, dflt);
+ break;
+ }
+ }
+ }
+ StringBuilder buf = new StringBuilder(1024);
+ buf.append("\n");
+ return buf.toString();
+ }
+
+ /**
+ * @return null on error
+ */
+ public String getURL() {
+ if (_engine == null || _query == null)
+ return null;
+ _query = DataHelper.escapeHTML(_query).trim();
+ if (_query.length() <= 0)
+ return null;
+ buildEngineMap();
+ String url = _engines.get(_engine);
+ if (url == null)
+ return null;
+ if (url.contains("%s"))
+ url = url.replace("%s", _query);
+ else
+ url += _query;
+ return url;
+ }
+}
diff --git a/apps/routerconsole/java/src/net/i2p/router/web/SummaryBarRenderer.java b/apps/routerconsole/java/src/net/i2p/router/web/SummaryBarRenderer.java
index 0c1fb11743..5e22c1edcd 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/SummaryBarRenderer.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/SummaryBarRenderer.java
@@ -266,47 +266,7 @@ public class SummaryBarRenderer {
out.write(buf.toString());
buf.setLength(0);
-
- boolean anotherLine = false;
- if (_helper.showFirewallWarning()) {
- buf.append("");
- anotherLine = true;
- }
-
- boolean reseedInProgress = Boolean.valueOf(System.getProperty("net.i2p.router.web.ReseedHandler.reseedInProgress")).booleanValue();
- // If showing the reseed link is allowed
- if (_helper.allowReseed()) {
- if (reseedInProgress) {
- // While reseed occurring, show status message instead
- buf.append("").append(System.getProperty("net.i2p.router.web.ReseedHandler.statusMessage","")).append("
");
- } else {
- // While no reseed occurring, show reseed link
- long nonce = _context.random().nextLong();
- String prev = System.getProperty("net.i2p.router.web.ReseedHandler.nonce");
- if (prev != null) System.setProperty("net.i2p.router.web.ReseedHandler.noncePrev", prev);
- System.setProperty("net.i2p.router.web.ReseedHandler.nonce", nonce+"");
- String uri = _helper.getRequestURI();
- buf.append("
\n");
- }
- anotherLine = true;
- }
- // If a new reseed ain't running, and the last reseed had errors, show error message
- if (!reseedInProgress) {
- String reseedErrorMessage = System.getProperty("net.i2p.router.web.ReseedHandler.errorMessage","");
- if (reseedErrorMessage.length() > 0) {
- buf.append("").append(reseedErrorMessage).append("
");
- anotherLine = true;
- }
- }
- if (anotherLine)
- buf.append("
");
-
+ buf.append(_helper.getFirewallAndReseedStatus());
buf.append("")
+ .append(_("Check network connection and NAT/firewall"))
+ .append("");
+ }
+
+ boolean reseedInProgress = Boolean.valueOf(System.getProperty("net.i2p.router.web.ReseedHandler.reseedInProgress")).booleanValue();
+ // If showing the reseed link is allowed
+ if (allowReseed()) {
+ if (reseedInProgress) {
+ // While reseed occurring, show status message instead
+ buf.append("").append(System.getProperty("net.i2p.router.web.ReseedHandler.statusMessage","")).append("
");
+ } else {
+ // While no reseed occurring, show reseed link
+ long nonce = _context.random().nextLong();
+ String prev = System.getProperty("net.i2p.router.web.ReseedHandler.nonce");
+ if (prev != null) System.setProperty("net.i2p.router.web.ReseedHandler.noncePrev", prev);
+ System.setProperty("net.i2p.router.web.ReseedHandler.nonce", nonce+"");
+ String uri = getRequestURI();
+ buf.append("
\n");
+ }
+ }
+ // If a new reseed ain't running, and the last reseed had errors, show error message
+ if (!reseedInProgress) {
+ String reseedErrorMessage = System.getProperty("net.i2p.router.web.ReseedHandler.errorMessage","");
+ if (reseedErrorMessage.length() > 0) {
+ buf.append("").append(reseedErrorMessage).append("
");
+ }
+ }
+ if (buf.length() <= 0)
+ return "";
+ buf.append("
");
+ return buf.toString();
+ }
+
/** output the summary bar to _out */
public void renderSummaryBar() throws IOException {
SummaryBarRenderer renderer = new SummaryBarRenderer(_context, this);
diff --git a/apps/routerconsole/jsp/confighome.jsp b/apps/routerconsole/jsp/confighome.jsp
new file mode 100644
index 0000000000..728527b854
--- /dev/null
+++ b/apps/routerconsole/jsp/confighome.jsp
@@ -0,0 +1,84 @@
+<%@page contentType="text/html"%>
+<%@page pageEncoding="UTF-8"%>
+
+
+
+<%@include file="css.jsi" %>
+<%=intl.title("config home")%>
+
+
+
+<%@include file="summary.jsi" %>
+<%=intl._("I2P Home Page Configuration")%>
+
+<%@include file="confignav.jsi" %>
+
+
+<% formhandler.storeMethod(request.getMethod()); %>
+
+
" />
+
+
+<%
+ String pageNonce = formhandler.getNewNonce();
+%>
+
+" />
+
+<%=intl._("Default Home Page")%>
+
+
+<%=intl._("Search Engines")%>
+
+
+<%=intl._("Recommended Eepsites")%>
+
+
+<%=intl._("Local Services")%>
+
+
diff --git a/apps/routerconsole/jsp/console.jsp b/apps/routerconsole/jsp/console.jsp
new file mode 100644
index 0000000000..d9adf1c001
--- /dev/null
+++ b/apps/routerconsole/jsp/console.jsp
@@ -0,0 +1,65 @@
+<%@page contentType="text/html"%>
+<%@page pageEncoding="UTF-8"%>
+
+
+
+<%@include file="css.jsi" %>
+<%=intl.title("home")%>
+
+<%
+ String consoleNonce = System.getProperty("router.consoleNonce");
+ if (consoleNonce == null) {
+ consoleNonce = Long.toString(new java.util.Random().nextLong());
+ System.setProperty("router.consoleNonce", consoleNonce);
+ }
+%>
+
+<%@include file="summary.jsi" %><%=intl._("I2P Router Console")%>
+
+
+ " />
+<%
+ if (newshelper.shouldShowNews()) {
+ java.io.File fpath = new java.io.File(net.i2p.I2PAppContext.getGlobalContext().getRouterDir(), "docs/news.xml");
+%>
+
+
+
+
+<%
+ } // shouldShowNews()
+%>
+
+ " />
+
+
+
+
+
+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+
+
+
<%=intl._("Welcome to I2P")%>
+
+ <% java.io.File fpath = new java.io.File(net.i2p.I2PAppContext.getGlobalContext().getBaseDir(), "docs/readme.html"); %>
+
+
+
" />
+
+
diff --git a/apps/routerconsole/jsp/home.jsp b/apps/routerconsole/jsp/home.jsp
new file mode 100644
index 0000000000..382a73aeed
--- /dev/null
+++ b/apps/routerconsole/jsp/home.jsp
@@ -0,0 +1,149 @@
+<%@page contentType="text/html"%>
+<%@page pageEncoding="UTF-8"%>
+
+
+
+<%@include file="css.jsi" %>
+<%=intl.title("home")%>
+
+
+
+
+
+
+
+
+<%
+ String consoleNonce = System.getProperty("router.consoleNonce");
+ if (consoleNonce == null) {
+ consoleNonce = Long.toString(new java.util.Random().nextLong());
+ System.setProperty("router.consoleNonce", consoleNonce);
+ }
+%>
+
+
+
+
+
+

+
+
+
+
+<%@include file="xhr1.jsi" %>
+
+
+
+
+
+
+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+
+
<%=intl._("Welcome to I2P")%>
+
+
+
+
+ " />
+<%
+ if (newshelper.shouldShowNews()) {
+ java.io.File fpath = new java.io.File(net.i2p.I2PAppContext.getGlobalContext().getRouterDir(), "docs/news.xml");
+%>
+ <%=intl._("Latest I2P News")%>
+
+
+
+
+<%
+ } // shouldShowNews()
+%>
+
+ " />
+
+
+
+
+
+
+
" />
+
+
<%=intl._("Recommended Eepsites")%>
+
+
+
+
<%=intl._("Local Services")%>
+
+
+
+
diff --git a/apps/routerconsole/jsp/index.jsp b/apps/routerconsole/jsp/index.jsp
index d9adf1c001..b87cf0a1e1 100644
--- a/apps/routerconsole/jsp/index.jsp
+++ b/apps/routerconsole/jsp/index.jsp
@@ -1,65 +1,18 @@
-<%@page contentType="text/html"%>
+<%@page contentType="text/plain"%>
<%@page pageEncoding="UTF-8"%>
-
-
-
-<%@include file="css.jsi" %>
-<%=intl.title("home")%>
-
<%
- String consoleNonce = System.getProperty("router.consoleNonce");
- if (consoleNonce == null) {
- consoleNonce = Long.toString(new java.util.Random().nextLong());
- System.setProperty("router.consoleNonce", consoleNonce);
- }
+ response.setStatus(302, "Moved");
+ String req = request.getRequestURI();
+ if (req.endsWith("index"))
+ req = req.substring(0, req.length() - 5);
+ else if (req.endsWith("index.jsp"))
+ req = req.substring(0, req.length() - 9);
+ if (!req.endsWith("/"))
+ req += '/';
+ boolean oldHome = net.i2p.I2PAppContext.getGlobalContext().getBooleanProperty("routerconsole.oldHomePage");
+ if (oldHome)
+ req += "console";
+ else
+ req += "home";
+ response.setHeader("Location", req);
%>
-
-<%@include file="summary.jsi" %><%=intl._("I2P Router Console")%>
-
-
- " />
-<%
- if (newshelper.shouldShowNews()) {
- java.io.File fpath = new java.io.File(net.i2p.I2PAppContext.getGlobalContext().getRouterDir(), "docs/news.xml");
-%>
-
-
-
-
-<%
- } // shouldShowNews()
-%>
-
- " />
-
-
-
-
-
-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-
-
-
<%=intl._("Welcome to I2P")%>
-
- <% java.io.File fpath = new java.io.File(net.i2p.I2PAppContext.getGlobalContext().getBaseDir(), "docs/readme.html"); %>
-
-
-
" />
-
-
diff --git a/apps/routerconsole/jsp/search.jsp b/apps/routerconsole/jsp/search.jsp
new file mode 100644
index 0000000000..6e8ddf9b4b
--- /dev/null
+++ b/apps/routerconsole/jsp/search.jsp
@@ -0,0 +1,34 @@
+<%@page contentType="text/html"%>
+<%@page pageEncoding="UTF-8"%>
+
+" />
+" />
+" />
+
+<%
+ String url = searchhelper.getURL();
+ if (url != null) {
+ response.setStatus(303, "Redirecting");
+ response.setHeader("Location", url);
+%>
+Searching...
+<%
+ } else {
+ response.setStatus(403, "Bad");
+ String query = request.getParameter("query");
+ if (query == null || query.trim().length() <= 0) {
+%>
+No search string specified!
+<%
+ } else if (request.getParameter("engine") == null) {
+%>
+No search engine specified!
+<%
+ } else {
+%>
+No search engines found!
+<%
+ }
+ }
+%>
+
diff --git a/apps/routerconsole/jsp/xhr1.jsi b/apps/routerconsole/jsp/xhr1.jsi
new file mode 100644
index 0000000000..c9722c69b5
--- /dev/null
+++ b/apps/routerconsole/jsp/xhr1.jsi
@@ -0,0 +1,24 @@
+
+" />
+" />
+<%=intl._("Version")%>: |
+
+ |
<%=intl._("Uptime")%>: |
+
+ |
+" />
+" />
+<%
+ String reqURI = request.getRequestURI();
+ if (reqURI != null)
+ reqURI = reqURI.replace("/xhr1.jsp", "/home");
+ helper.setRequestURI(reqURI);
+%>
+
+
+
+
+
+
+
diff --git a/apps/routerconsole/jsp/xhr1.jsp b/apps/routerconsole/jsp/xhr1.jsp
new file mode 100644
index 0000000000..effeccbbea
--- /dev/null
+++ b/apps/routerconsole/jsp/xhr1.jsp
@@ -0,0 +1,14 @@
+<%@page contentType="text/html"%>
+<%@page pageEncoding="UTF-8"%>
+<%
+ // http://www.crazysquirrel.com/computing/general/form-encoding.jspx
+ if (request.getCharacterEncoding() == null)
+ request.setCharacterEncoding("UTF-8");
+
+ if (request.getParameter("i2p.contextId") != null) {
+ session.setAttribute("i2p.contextId", request.getParameter("i2p.contextId"));
+ }
+%>
+
+" />
+<%@include file="xhr1.jsi" %>
diff --git a/installer/resources/themes/console/light/console.css b/installer/resources/themes/console/light/console.css
index 0b795718f5..6db7c481ea 100644
--- a/installer/resources/themes/console/light/console.css
+++ b/installer/resources/themes/console/light/console.css
@@ -635,10 +635,22 @@ div.search {
width: auto;
}
-img.app {
- height: 48px;
- width: 48px;
+div.search table {
+ background: none;
+ margin: 20px;
padding: 8px;
+ width: auto;
+}
+
+img.app {
+ height: 40px;
+ width: 40px;
+ padding: 8px;
+}
+
+img.app2p {
+ height: 48px;
+ padding: 3px 8px;
}
table.app {