forked from I2P_Developers/i2p.i2p
Console: Sort tunnels by name on /tunnels, /configtunnels, /i2ptunnel
This commit is contained in:
@@ -10,7 +10,10 @@ package net.i2p.i2ptunnel.web;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.text.Collator;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
@@ -358,6 +361,41 @@ public class IndexBean {
|
||||
if (_group == null) return 0;
|
||||
return _group.getControllers().size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return tunnel numbers of clients or servers only, sorted by tunnel name
|
||||
* @param isClient true for clients, false for servers
|
||||
* @return non-null, may be empty
|
||||
* @since 0.9.57
|
||||
*/
|
||||
public List<Integer> getControllerNumbers(boolean isClient) {
|
||||
if (_group == null)
|
||||
return Collections.emptyList();
|
||||
List<TunnelController> all = _group.getControllers();
|
||||
List<Integer> rv = new ArrayList<Integer>(all.size());
|
||||
for (int i = 0; i < all.size(); i++) {
|
||||
TunnelController tc = all.get(i);
|
||||
if (tc.isClient() == isClient)
|
||||
rv.add(Integer.valueOf(i));
|
||||
}
|
||||
if (rv.size() > 1)
|
||||
Collections.sort(rv, new TCComparator());
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort tunnel numbers by the name of the tunnel
|
||||
* @since 0.9.57
|
||||
*/
|
||||
private class TCComparator implements Comparator<Integer> {
|
||||
private final Collator _comp = Collator.getInstance();
|
||||
public int compare(Integer l, Integer r) {
|
||||
int rv = _comp.compare(getTunnelName(l), getTunnelName(r));
|
||||
if (rv != 0)
|
||||
return rv;
|
||||
return l.compareTo(r);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Is it a client or server in the UI and I2P side?
|
||||
|
||||
@@ -85,8 +85,7 @@
|
||||
<th class="tunnelControl"><%=intl._t("Control")%></th>
|
||||
</tr>
|
||||
<%
|
||||
for (int curServer = 0; curServer < indexBean.getTunnelCount(); curServer++) {
|
||||
if (indexBean.isClient(curServer)) continue;
|
||||
for (int curServer : indexBean.getControllerNumbers(false)) {
|
||||
%>
|
||||
<tr class="tunnelProperties">
|
||||
<td class="tunnelName">
|
||||
@@ -258,8 +257,7 @@
|
||||
<th class="tunnelControl"><%=intl._t("Control")%></th>
|
||||
</tr>
|
||||
<%
|
||||
for (int curClient = 0; curClient < indexBean.getTunnelCount(); curClient++) {
|
||||
if (!indexBean.isClient(curClient)) continue;
|
||||
for (int curClient : indexBean.getControllerNumbers(true)) {
|
||||
%>
|
||||
<tr class="tunnelProperties">
|
||||
<td class="tunnelName">
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
package net.i2p.router.web.helpers;
|
||||
|
||||
import java.text.Collator;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.data.Destination;
|
||||
import net.i2p.data.Hash;
|
||||
import net.i2p.router.TunnelManagerFacade;
|
||||
import net.i2p.router.TunnelPoolSettings;
|
||||
import net.i2p.router.transport.TransportUtil;
|
||||
@@ -23,46 +28,78 @@ public class ConfigTunnelsHelper extends HelperBase {
|
||||
buf.append("<input type=\"hidden\" name=\"pool.0\" value=\"exploratory\" >\n");
|
||||
int cur = 1;
|
||||
Set<Destination> clients = _context.clientManager().listClients();
|
||||
TunnelManagerFacade mgr = _context.tunnelManager();
|
||||
// display name to in pool
|
||||
List<TunnelPoolSettings> sorted = new ArrayList<TunnelPoolSettings>(clients.size());
|
||||
for (Destination dest : clients) {
|
||||
TunnelPoolSettings in = mgr.getInboundSettings(dest.calculateHash());
|
||||
if (in != null)
|
||||
sorted.add(in);
|
||||
}
|
||||
if (sorted.size() > 1)
|
||||
DataHelper.sort(sorted, new TPComparator());
|
||||
for (TunnelPoolSettings in : sorted) {
|
||||
buf.append("<input type=\"hidden\" name=\"pool.").append(cur).append("\" value=\"");
|
||||
buf.append(dest.calculateHash().toBase64()).append("\" >\n");
|
||||
buf.append(in.getDestination().toBase64()).append("\" >\n");
|
||||
cur++;
|
||||
}
|
||||
|
||||
buf.append("<table id=\"tunnelconfig\">\n");
|
||||
TunnelManagerFacade mgr = _context.tunnelManager();
|
||||
TunnelPoolSettings exploratoryIn = mgr.getInboundSettings();
|
||||
TunnelPoolSettings exploratoryOut = mgr.getOutboundSettings();
|
||||
|
||||
renderForm(buf, 0, "exploratory", _t("Exploratory tunnels"), exploratoryIn, exploratoryOut);
|
||||
|
||||
cur = 1;
|
||||
for (Destination dest : clients) {
|
||||
TunnelPoolSettings in = mgr.getInboundSettings(dest.calculateHash());
|
||||
TunnelPoolSettings out = mgr.getOutboundSettings(dest.calculateHash());
|
||||
|
||||
if (in == null || in.getAliasOf() != null ||
|
||||
for (TunnelPoolSettings in : sorted) {
|
||||
Hash h = in.getDestination();
|
||||
TunnelPoolSettings out = mgr.getOutboundSettings(h);
|
||||
|
||||
if (in.getAliasOf() != null ||
|
||||
out == null || out.getAliasOf() != null) {
|
||||
cur++;
|
||||
continue;
|
||||
}
|
||||
|
||||
String name = in.getDestinationNickname();
|
||||
if (name == null) {
|
||||
name = out.getDestinationNickname();
|
||||
if (name == null)
|
||||
name = dest.calculateHash().toBase32();
|
||||
}
|
||||
|
||||
String prefix = dest.calculateHash().toBase64().substring(0,4);
|
||||
renderForm(buf, cur, prefix, _t("Client tunnels for {0}", DataHelper.escapeHTML(_t(name))), in, out);
|
||||
|
||||
String prefix = h.toBase64().substring(0,4);
|
||||
renderForm(buf, cur, prefix, _t("Client tunnels for {0}", getTunnelName(in)), in, out);
|
||||
cur++;
|
||||
}
|
||||
|
||||
|
||||
buf.append("</table>\n");
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort tunnels by the name of the tunnel
|
||||
* @since 0.9.57
|
||||
*/
|
||||
private class TPComparator implements Comparator<TunnelPoolSettings> {
|
||||
private final Collator _comp = Collator.getInstance();
|
||||
public int compare(TunnelPoolSettings l, TunnelPoolSettings r) {
|
||||
int rv = _comp.compare(getTunnelName(l), getTunnelName(r));
|
||||
if (rv != 0)
|
||||
return rv;
|
||||
return l.getDestination().toBase32().compareTo(r.getDestination().toBase32());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get display name for the tunnel
|
||||
* @since 0.9.57
|
||||
*/
|
||||
private String getTunnelName(TunnelPoolSettings ins) {
|
||||
String name = ins.getDestinationNickname();
|
||||
if (name == null) {
|
||||
TunnelPoolSettings outPool = _context.tunnelManager().getOutboundSettings(ins.getDestination());
|
||||
if (outPool != null)
|
||||
name = outPool.getDestinationNickname();
|
||||
}
|
||||
if (name != null)
|
||||
return DataHelper.escapeHTML(_t(name));
|
||||
return ins.getDestination().toBase32();
|
||||
}
|
||||
|
||||
private static final int WARN_LENGTH = 4;
|
||||
private static final int MAX_LENGTH = 4;
|
||||
private static final int MAX_ADVANCED_LENGTH = 7;
|
||||
|
||||
@@ -3,6 +3,7 @@ package net.i2p.router.web.helpers;
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.io.Writer;
|
||||
import java.text.Collator;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
@@ -17,6 +18,8 @@ import net.i2p.data.TunnelId;
|
||||
import net.i2p.router.Router;
|
||||
import net.i2p.router.RouterContext;
|
||||
import net.i2p.router.TunnelInfo;
|
||||
import net.i2p.router.TunnelManagerFacade;
|
||||
import net.i2p.router.TunnelPoolSettings;
|
||||
import net.i2p.router.tunnel.HopConfig;
|
||||
import net.i2p.router.tunnel.pool.TunnelPool;
|
||||
import net.i2p.router.web.HelperBase;
|
||||
@@ -37,8 +40,9 @@ class TunnelRenderer {
|
||||
}
|
||||
|
||||
public void renderStatusHTML(Writer out) throws IOException {
|
||||
TunnelPool ei = _context.tunnelManager().getInboundExploratoryPool();
|
||||
TunnelPool eo = _context.tunnelManager().getOutboundExploratoryPool();
|
||||
TunnelManagerFacade tm = _context.tunnelManager();
|
||||
TunnelPool ei = tm.getInboundExploratoryPool();
|
||||
TunnelPool eo = tm.getOutboundExploratoryPool();
|
||||
out.write("<h3 class=\"tabletitle\" id=\"exploratorytunnels\"><a name=\"exploratory\" ></a>" + _t("Exploratory tunnels"));
|
||||
// links are set to float:right in CSS so they will be displayed in reverse order
|
||||
out.write(" <a href=\"/configtunnels#exploratory\" title=\"" + _t("Configure tunnels") + "\">[" + _t("configure") + "]</a>");
|
||||
@@ -46,37 +50,26 @@ class TunnelRenderer {
|
||||
out.write("</h3>\n");
|
||||
renderPool(out, ei, eo);
|
||||
|
||||
List<Hash> destinations = null;
|
||||
Map<Hash, TunnelPool> clientInboundPools = _context.tunnelManager().getInboundClientPools();
|
||||
Map<Hash, TunnelPool> clientOutboundPools = _context.tunnelManager().getOutboundClientPools();
|
||||
destinations = new ArrayList<Hash>(clientInboundPools.keySet());
|
||||
Map<Hash, TunnelPool> clientInboundPools = tm.getInboundClientPools();
|
||||
boolean debug = _context.getBooleanProperty(HelperBase.PROP_ADVANCED);
|
||||
for (int i = 0; i < destinations.size(); i++) {
|
||||
Hash client = destinations.get(i);
|
||||
// display name to in pool
|
||||
List<TunnelPool> sorted = new ArrayList<TunnelPool>(clientInboundPools.values());
|
||||
if (sorted.size() > 1)
|
||||
DataHelper.sort(sorted, new TPComparator());
|
||||
for (TunnelPool in : sorted) {
|
||||
Hash client = in.getSettings().getDestination();
|
||||
boolean isLocal = _context.clientManager().isLocal(client);
|
||||
if ((!isLocal) && (!debug))
|
||||
continue;
|
||||
TunnelPool in = clientInboundPools.get(client);
|
||||
TunnelPool outPool = clientOutboundPools.get(client);
|
||||
if ((in != null && in.getSettings().getAliasOf() != null) ||
|
||||
TunnelPool outPool = tm.getOutboundPool(client);
|
||||
if (in.getSettings().getAliasOf() != null ||
|
||||
(outPool != null && outPool.getSettings().getAliasOf() != null)) {
|
||||
// skip aliases, we will print a header under the main tunnel pool below
|
||||
continue;
|
||||
}
|
||||
// TODO the following code is duplicated in SummaryHelper
|
||||
String name = (in != null) ? in.getSettings().getDestinationNickname() : null;
|
||||
if ( (name == null) && (outPool != null) )
|
||||
name = outPool.getSettings().getDestinationNickname();
|
||||
String b64 = client.toBase64().substring(0, 4);
|
||||
String dname;
|
||||
if (name == null) {
|
||||
name = b64;
|
||||
dname = client.toBase32();
|
||||
} else {
|
||||
dname = DataHelper.escapeHTML(_t(name));
|
||||
}
|
||||
out.write("<h3 class=\"tabletitle\" id=\"" + b64
|
||||
+ "\" >" + _t("Client tunnels for {0}", dname));
|
||||
+ "\" >" + _t("Client tunnels for {0}", getTunnelName(in)));
|
||||
if (isLocal) {
|
||||
// links are set to float:right in CSS so they will be displayed in reverse order
|
||||
out.write(" <a href=\"/configtunnels#" + b64 + "\" title=\"" + _t("Configure tunnels for session") + "\">[" + _t("configure") + "]</a>");
|
||||
@@ -85,7 +78,7 @@ class TunnelRenderer {
|
||||
} else {
|
||||
out.write(" (" + _t("dead") + ")</h3>\n");
|
||||
}
|
||||
if (in != null) {
|
||||
|
||||
// list aliases
|
||||
Set<Hash> aliases = in.getSettings().getAliases();
|
||||
if (aliases != null) {
|
||||
@@ -105,7 +98,7 @@ class TunnelRenderer {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
renderPool(out, in, outPool);
|
||||
}
|
||||
|
||||
@@ -236,6 +229,37 @@ class TunnelRenderer {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort tunnels by the name of the tunnel
|
||||
* @since 0.9.57
|
||||
*/
|
||||
private class TPComparator implements Comparator<TunnelPool> {
|
||||
private final Collator _comp = Collator.getInstance();
|
||||
public int compare(TunnelPool l, TunnelPool r) {
|
||||
int rv = _comp.compare(getTunnelName(l), getTunnelName(r));
|
||||
if (rv != 0)
|
||||
return rv;
|
||||
return l.getSettings().getDestination().toBase32().compareTo(r.getSettings().getDestination().toBase32());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get display name for the tunnel
|
||||
* @since 0.9.57
|
||||
*/
|
||||
private String getTunnelName(TunnelPool in) {
|
||||
TunnelPoolSettings ins = in.getSettings();
|
||||
String name = ins.getDestinationNickname();
|
||||
if (name == null) {
|
||||
TunnelPoolSettings outPool = _context.tunnelManager().getOutboundSettings(ins.getDestination());
|
||||
if (outPool != null)
|
||||
name = outPool.getDestinationNickname();
|
||||
}
|
||||
if (name != null)
|
||||
return DataHelper.escapeHTML(_t(name));
|
||||
return ins.getDestination().toBase32();
|
||||
}
|
||||
|
||||
/** @since 0.9.35 */
|
||||
private void writeGraphLinks(Writer out, TunnelPool in, TunnelPool outPool) throws IOException {
|
||||
if (in == null || outPool == null)
|
||||
|
||||
Reference in New Issue
Block a user