package net.i2p.router.web; 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"; private static final String PROP_SEARCH = "routerconsole.showSearch"; static final String DEFAULT_SERVICES = _x("Addressbook") + S + _x("Manage your I2P hosts file here (I2P domain name resolution)") + S + "/dns" + S + I + "book_addresses.png" + S + _x("Configure Bandwidth") + S + _x("I2P Bandwidth Configuration") + S + "/config" + S + I + "action_log.png" + S + _x("Configure Language") + S + _x("Console Language Selection") + S + "/configui" + S + I + "wrench_orange.png" + S + _x("Customize Home Page") + S + _x("I2P Home Page Configuration") + S + "/confighome" + S + I + "home_page.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 + "support.png" + S + _x("Router Console") + S + _x("I2P Router Console") + S + "/console" + S + I + "toolbox.png" + S + _x("Torrents") + S + _x("Built-in anonymous BitTorrent Client") + S + "/i2psnark/" + S + I + "magnet.png" + S + _x("Website") + S + _x("Local web server") + S + "http://127.0.0.1:7658/" + S + I + "server_32x32.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 + //"colombo-bt.i2p" + S + _x("The Italian Bittorrent Resource") + S + "http://colombo-bt.i2p/" + S + I + "colomboicon.png" + S + _x("Dev Forum") + S + _x("Development forum") + S + "http://zzz.i2p/" + S + I + "eepsite.png" + S + _x("diftracker") + S + _x("Bittorrent tracker") + S + "http://diftracker.i2p/" + S + I + "eepsite.png" + S + "echelon.i2p" + S + _x("I2P Applications") + S + "http://echelon.i2p/" + S + I + "eepsite.png" + S + _x("FAQ") + S + _x("Frequently Asked Questions") + S + "http://www.i2p2.i2p/faq" + S + I + "question.png" + S + _x("Forum") + S + _x("Community forum") + S + "http://forum.i2p/" + S + I + "eepsite.png" + S + _x("Anonymous Git Hosting") + S + _x("A public anonymous Git hosting site - supports pulling via Git and HTTP and pushing via SSH") + S + "http://git.repo.i2p/" + S + I + "git-logo.png" + S + "Ident " + _x("Microblog") + S + _x("Your premier microblogging service on I2P") + S + "http://id3nt.i2p/" + S + I + "ident_icon_blue.png" + S + _x("Javadocs") + S + _x("Technical documentation") + S + "http://i2p-javadocs.i2p/" + S + I + "education.png" + S + //_x("Key Server") + S + _x("OpenPGP Keyserver") + S + "http://keys.i2p/" + S + I + "education.png" + S + "killyourtv.i2p" + S + _x("Debian and Tahoe-LAFS repositories") + S + "http://killyourtv.i2p/" + S + I + "eepsite.png" + S + "open4you.i2p" + S + S + "http://open4you.i2p/" + S + I + "eepsite.png" + S + _x("Pastebin") + S + _x("I2P Pastebin") + S + "http://pastethis.i2p/" + S + I + "eepsite.png" + S + "Planet I2P" + S + _x("I2P News") + S + "http://planet.i2p/" + S + I + "eepsite.png" + S + _x("Plugins") + S + _x("Add-on directory") + S + "http://plugins.i2p/" + S + I + "plugin.png" + S + _x("Postman's Tracker") + S + _x("Bittorrent tracker") + S + "http://tracker2.postman.i2p/" + S + I + "eepsite.png" + S + _x("Project Website") + S + _x("I2P home page") + S + "http://www.i2p2.i2p/" + S + I + "info_rhombus.png" + S + "stats.i2p" + S + _x("I2P Network Statistics") + S + "http://stats.i2p/cgi-bin/dashboard.cgi" + S + I + "eepsite.png" + S + _x("Technical Docs") + S + _x("Technical documentation") + S + "http://www.i2p2.i2p/how" + S + I + "education.png" + S + _x("Trac Wiki") + S + S + "http://trac.i2p2.i2p/" + S + I + "eepsite.png" + S + _x("Ugha's Wiki") + S + S + "http://ugha.i2p/" + S + I + "eepsite.png" + S + _x("Sponge's main site") + S + _x("Seedless and the Robert BitTorrent applications") + S + "http://sponge.i2p/" + S + I + "eepsite.png" + S + ""; public boolean shouldShowWelcome() { return _context.getProperty(Messages.PROP_LANG) == null; } public boolean shouldShowSearch() { return _context.getBooleanProperty(PROP_SEARCH); } 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" + "
" + "
" + "" + "
" + "
\n"); } buf.append("
\n"); return buf.toString(); } private String renderConfig(Collection apps) { StringBuilder buf = new StringBuilder(1024); buf.append("\n"); for (App app : apps) { buf.append("\n"); } buf.append("" + ""); buf.append("
") .append(_("Remove")) .append("") .append(_("Name")) .append("") .append(_("URL")) .append("
"); if (app.icon != null) { buf.append("\"\""); } buf.append("") .append(app.name) .append("") .append(app.url.replace("&", "&")) .append("
") .append(_("Add")).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()); } } }