forked from I2P_Developers/i2p.i2p
i2psnark:
- Consolidate and clean up parameters code - Click to sort by column
This commit is contained in:
@ -194,22 +194,8 @@ public class I2PSnarkServlet extends BasicServlet {
|
|||||||
resp.setHeader("Content-Security-Policy", "default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline'");
|
resp.setHeader("Content-Security-Policy", "default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline'");
|
||||||
resp.setHeader("X-XSS-Protection", "1; mode=block");
|
resp.setHeader("X-XSS-Protection", "1; mode=block");
|
||||||
|
|
||||||
String peerParam = req.getParameter("p");
|
String pOverride = _manager.util().connected() ? null : "";
|
||||||
String stParam = req.getParameter("st");
|
String peerString = getQueryString(req, pOverride, null, null);
|
||||||
String peerString;
|
|
||||||
if (peerParam == null || (!_manager.util().connected()) ||
|
|
||||||
peerParam.replaceAll("[a-zA-Z0-9~=-]", "").length() > 0) { // XSS
|
|
||||||
peerString = "";
|
|
||||||
} else {
|
|
||||||
peerString = "?p=" + DataHelper.stripHTML(peerParam);
|
|
||||||
}
|
|
||||||
if (stParam != null && !stParam.equals("0")) {
|
|
||||||
stParam = DataHelper.stripHTML(stParam);
|
|
||||||
if (peerString.length() > 0)
|
|
||||||
peerString += "&st=" + stParam;
|
|
||||||
else
|
|
||||||
peerString = "?st="+ stParam;
|
|
||||||
}
|
|
||||||
|
|
||||||
// AJAX for mainsection
|
// AJAX for mainsection
|
||||||
if ("/.ajax/xhr1.html".equals(path)) {
|
if ("/.ajax/xhr1.html".equals(path)) {
|
||||||
@ -292,6 +278,7 @@ public class I2PSnarkServlet extends BasicServlet {
|
|||||||
out.write(_("Configuration"));
|
out.write(_("Configuration"));
|
||||||
else
|
else
|
||||||
out.write(_("Anonymous BitTorrent Client"));
|
out.write(_("Anonymous BitTorrent Client"));
|
||||||
|
String peerParam = req.getParameter("p");
|
||||||
if ("2".equals(peerParam))
|
if ("2".equals(peerParam))
|
||||||
out.write(" | Debug Mode");
|
out.write(" | Debug Mode");
|
||||||
out.write("</title>\n");
|
out.write("</title>\n");
|
||||||
@ -413,13 +400,7 @@ public class I2PSnarkServlet extends BasicServlet {
|
|||||||
boolean isForm = _manager.util().connected() || !snarks.isEmpty();
|
boolean isForm = _manager.util().connected() || !snarks.isEmpty();
|
||||||
if (isForm) {
|
if (isForm) {
|
||||||
out.write("<form action=\"_post\" method=\"POST\">\n");
|
out.write("<form action=\"_post\" method=\"POST\">\n");
|
||||||
out.write("<input type=\"hidden\" name=\"nonce\" value=\"" + _nonce + "\" >\n");
|
writeHiddenInputs(out, req, null);
|
||||||
// don't lose peer setting
|
|
||||||
if (peerParam != null)
|
|
||||||
out.write("<input type=\"hidden\" name=\"p\" value=\"" + peerParam + "\" >\n");
|
|
||||||
// ...or st setting
|
|
||||||
if (stParam != null)
|
|
||||||
out.write("<input type=\"hidden\" name=\"st\" value=\"" + stParam + "\" >\n");
|
|
||||||
}
|
}
|
||||||
out.write(TABLE_HEADER);
|
out.write(TABLE_HEADER);
|
||||||
|
|
||||||
@ -441,18 +422,19 @@ public class I2PSnarkServlet extends BasicServlet {
|
|||||||
}
|
}
|
||||||
int pageSize = Math.max(_manager.getPageSize(), 5);
|
int pageSize = Math.max(_manager.getPageSize(), 5);
|
||||||
|
|
||||||
out.write("<tr><th><img border=\"0\" src=\"" + _imgPath + "status.png\" title=\"");
|
String currentSort = req.getParameter("sort");
|
||||||
|
out.write("<tr><th>");
|
||||||
|
String sort = ("2".equals(currentSort)) ? "-2" : "2";
|
||||||
|
out.write("<a href=\"" + _contextPath + '/' + getQueryString(req, null, null, sort));
|
||||||
|
out.write("\"><img border=\"0\" src=\"" + _imgPath + "status.png\" title=\"");
|
||||||
out.write(_("Status"));
|
out.write(_("Status"));
|
||||||
out.write("\" alt=\"");
|
out.write("\" alt=\"");
|
||||||
out.write(_("Status"));
|
out.write(_("Status"));
|
||||||
out.write("\"></th>\n<th>");
|
out.write("\"></a></th>\n<th>");
|
||||||
if (_manager.util().connected() && !snarks.isEmpty()) {
|
if (_manager.util().connected() && !snarks.isEmpty()) {
|
||||||
out.write(" <a href=\"" + _contextPath + '/');
|
out.write(" <a href=\"" + _contextPath + '/');
|
||||||
if (peerParam != null) {
|
if (peerParam != null) {
|
||||||
if (stParam != null) {
|
// disable peer view
|
||||||
out.write("?st=");
|
|
||||||
out.write(stParam);
|
|
||||||
}
|
|
||||||
out.write("\">");
|
out.write("\">");
|
||||||
out.write("<img border=\"0\" src=\"" + _imgPath + "hidepeers.png\" title=\"");
|
out.write("<img border=\"0\" src=\"" + _imgPath + "hidepeers.png\" title=\"");
|
||||||
out.write(_("Hide Peers"));
|
out.write(_("Hide Peers"));
|
||||||
@ -460,11 +442,8 @@ public class I2PSnarkServlet extends BasicServlet {
|
|||||||
out.write(_("Hide Peers"));
|
out.write(_("Hide Peers"));
|
||||||
out.write("\">");
|
out.write("\">");
|
||||||
} else {
|
} else {
|
||||||
out.write("?p=1");
|
// enable peer view
|
||||||
if (stParam != null) {
|
out.write(getQueryString(req, "1", null, null));
|
||||||
out.write("&st=");
|
|
||||||
out.write(stParam);
|
|
||||||
}
|
|
||||||
out.write("\">");
|
out.write("\">");
|
||||||
out.write("<img border=\"0\" src=\"" + _imgPath + "showpeers.png\" title=\"");
|
out.write("<img border=\"0\" src=\"" + _imgPath + "showpeers.png\" title=\"");
|
||||||
out.write(_("Show Peers"));
|
out.write(_("Show Peers"));
|
||||||
@ -475,56 +454,69 @@ public class I2PSnarkServlet extends BasicServlet {
|
|||||||
out.write("</a><br>\n");
|
out.write("</a><br>\n");
|
||||||
}
|
}
|
||||||
out.write("</th>\n<th colspan=\"2\" align=\"left\">");
|
out.write("</th>\n<th colspan=\"2\" align=\"left\">");
|
||||||
out.write("<img border=\"0\" src=\"" + _imgPath + "torrent.png\" title=\"");
|
sort = (currentSort == null || "0".equals(currentSort) || "1".equals(currentSort)) ? "-1" : "";
|
||||||
|
out.write("<a href=\"" + _contextPath + '/' + getQueryString(req, null, null, sort));
|
||||||
|
out.write("\"><img border=\"0\" src=\"" + _imgPath + "torrent.png\" title=\"");
|
||||||
out.write(_("Torrent"));
|
out.write(_("Torrent"));
|
||||||
out.write("\" alt=\"");
|
out.write("\" alt=\"");
|
||||||
out.write(_("Torrent"));
|
out.write(_("Torrent"));
|
||||||
out.write("\"></th>\n<th align=\"center\">");
|
out.write("\"></a></th>\n<th align=\"center\">");
|
||||||
if (total > 0 && (start > 0 || total > pageSize)) {
|
if (total > 0 && (start > 0 || total > pageSize)) {
|
||||||
writePageNav(out, start, pageSize, total, peerParam, noThinsp);
|
writePageNav(out, req, start, pageSize, total, noThinsp);
|
||||||
}
|
}
|
||||||
out.write("</th>\n<th align=\"right\">");
|
out.write("</th>\n<th align=\"right\">");
|
||||||
if (_manager.util().connected() && !snarks.isEmpty()) {
|
if (_manager.util().connected() && !snarks.isEmpty()) {
|
||||||
out.write("<img border=\"0\" src=\"" + _imgPath + "eta.png\" title=\"");
|
sort = ("4".equals(currentSort)) ? "-4" : "4";
|
||||||
|
out.write("<a href=\"" + _contextPath + '/' + getQueryString(req, null, null, sort));
|
||||||
|
out.write("\"><img border=\"0\" src=\"" + _imgPath + "eta.png\" title=\"");
|
||||||
out.write(_("Estimated time remaining"));
|
out.write(_("Estimated time remaining"));
|
||||||
out.write("\" alt=\"");
|
out.write("\" alt=\"");
|
||||||
// Translators: Please keep short or translate as " "
|
// Translators: Please keep short or translate as " "
|
||||||
out.write(_("ETA"));
|
out.write(_("ETA"));
|
||||||
out.write("\">");
|
out.write("\"></a>");
|
||||||
}
|
}
|
||||||
out.write("</th>\n<th align=\"right\">");
|
out.write("</th>\n<th align=\"right\">");
|
||||||
out.write("<img border=\"0\" src=\"" + _imgPath + "head_rx.png\" title=\"");
|
// sort by size, not downloaded
|
||||||
|
sort = ("5".equals(currentSort)) ? "-5" : "5";
|
||||||
|
out.write("<a href=\"" + _contextPath + '/' + getQueryString(req, null, null, sort));
|
||||||
|
out.write("\"><img border=\"0\" src=\"" + _imgPath + "head_rx.png\" title=\"");
|
||||||
out.write(_("Downloaded"));
|
out.write(_("Downloaded"));
|
||||||
out.write("\" alt=\"");
|
out.write("\" alt=\"");
|
||||||
// Translators: Please keep short or translate as " "
|
// Translators: Please keep short or translate as " "
|
||||||
out.write(_("RX"));
|
out.write(_("RX"));
|
||||||
out.write("\">");
|
out.write("\"></a>");
|
||||||
out.write("</th>\n<th align=\"right\">");
|
out.write("</th>\n<th align=\"right\">");
|
||||||
if (!snarks.isEmpty()) {
|
if (!snarks.isEmpty()) {
|
||||||
out.write("<img border=\"0\" src=\"" + _imgPath + "head_tx.png\" title=\"");
|
sort = ("7".equals(currentSort)) ? "-7" : "7";
|
||||||
|
out.write("<a href=\"" + _contextPath + '/' + getQueryString(req, null, null, sort));
|
||||||
|
out.write("\"><img border=\"0\" src=\"" + _imgPath + "head_tx.png\" title=\"");
|
||||||
out.write(_("Uploaded"));
|
out.write(_("Uploaded"));
|
||||||
out.write("\" alt=\"");
|
out.write("\" alt=\"");
|
||||||
// Translators: Please keep short or translate as " "
|
// Translators: Please keep short or translate as " "
|
||||||
out.write(_("TX"));
|
out.write(_("TX"));
|
||||||
out.write("\">");
|
out.write("\"></a>");
|
||||||
}
|
}
|
||||||
out.write("</th>\n<th align=\"right\">");
|
out.write("</th>\n<th align=\"right\">");
|
||||||
if (_manager.util().connected() && !snarks.isEmpty()) {
|
if (_manager.util().connected() && !snarks.isEmpty()) {
|
||||||
out.write("<img border=\"0\" src=\"" + _imgPath + "head_rxspeed.png\" title=\"");
|
sort = ("8".equals(currentSort)) ? "-8" : "8";
|
||||||
|
out.write("<a href=\"" + _contextPath + '/' + getQueryString(req, null, null, sort));
|
||||||
|
out.write("\"><img border=\"0\" src=\"" + _imgPath + "head_rxspeed.png\" title=\"");
|
||||||
out.write(_("Down Rate"));
|
out.write(_("Down Rate"));
|
||||||
out.write("\" alt=\"");
|
out.write("\" alt=\"");
|
||||||
// Translators: Please keep short or translate as " "
|
// Translators: Please keep short or translate as " "
|
||||||
out.write(_("RX Rate"));
|
out.write(_("RX Rate"));
|
||||||
out.write(" \">");
|
out.write("\"></a>");
|
||||||
}
|
}
|
||||||
out.write("</th>\n<th align=\"right\">");
|
out.write("</th>\n<th align=\"right\">");
|
||||||
if (_manager.util().connected() && !snarks.isEmpty()) {
|
if (_manager.util().connected() && !snarks.isEmpty()) {
|
||||||
out.write("<img border=\"0\" src=\"" + _imgPath + "head_txspeed.png\" title=\"");
|
sort = ("9".equals(currentSort)) ? "-9" : "9";
|
||||||
|
out.write("<a href=\"" + _contextPath + '/' + getQueryString(req, null, null, sort));
|
||||||
|
out.write("\"><img border=\"0\" src=\"" + _imgPath + "head_txspeed.png\" title=\"");
|
||||||
out.write(_("Up Rate"));
|
out.write(_("Up Rate"));
|
||||||
out.write("\" alt=\"");
|
out.write("\" alt=\"");
|
||||||
// Translators: Please keep short or translate as " "
|
// Translators: Please keep short or translate as " "
|
||||||
out.write(_("TX Rate"));
|
out.write(_("TX Rate"));
|
||||||
out.write(" \">");
|
out.write("\"></a>");
|
||||||
}
|
}
|
||||||
out.write("</th>\n<th align=\"center\">");
|
out.write("</th>\n<th align=\"center\">");
|
||||||
|
|
||||||
@ -580,12 +572,11 @@ public class I2PSnarkServlet extends BasicServlet {
|
|||||||
String uri = _contextPath + '/';
|
String uri = _contextPath + '/';
|
||||||
boolean showDebug = "2".equals(peerParam);
|
boolean showDebug = "2".equals(peerParam);
|
||||||
|
|
||||||
String stParamStr = stParam == null ? "" : "&st=" + stParam;
|
|
||||||
for (int i = 0; i < total; i++) {
|
for (int i = 0; i < total; i++) {
|
||||||
Snark snark = snarks.get(i);
|
Snark snark = snarks.get(i);
|
||||||
boolean showPeers = showDebug || "1".equals(peerParam) || Base64.encode(snark.getInfoHash()).equals(peerParam);
|
boolean showPeers = showDebug || "1".equals(peerParam) || Base64.encode(snark.getInfoHash()).equals(peerParam);
|
||||||
boolean hide = i < start || i >= start + pageSize;
|
boolean hide = i < start || i >= start + pageSize;
|
||||||
displaySnark(out, snark, uri, i, stats, showPeers, isDegraded, noThinsp, showDebug, hide, stParamStr);
|
displaySnark(out, req, snark, uri, i, stats, showPeers, isDegraded, noThinsp, showDebug, hide);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (total == 0) {
|
if (total == 0) {
|
||||||
@ -636,17 +627,105 @@ public class I2PSnarkServlet extends BasicServlet {
|
|||||||
return start == 0;
|
return start == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hidden inputs for nonce and paramters p, st, and sort
|
||||||
|
*
|
||||||
|
* @param out writes to it
|
||||||
|
* @param action if non-null, add it as the action
|
||||||
|
* @since 0.9.16
|
||||||
|
*/
|
||||||
|
private void writeHiddenInputs(PrintWriter out, HttpServletRequest req, String action) {
|
||||||
|
StringBuilder buf = new StringBuilder(256);
|
||||||
|
writeHiddenInputs(buf, req, action);
|
||||||
|
out.write(buf.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hidden inputs for nonce and paramters p, st, and sort
|
||||||
|
*
|
||||||
|
* @param out appends to it
|
||||||
|
* @param action if non-null, add it as the action
|
||||||
|
* @since 0.9.16
|
||||||
|
*/
|
||||||
|
private void writeHiddenInputs(StringBuilder buf, HttpServletRequest req, String action) {
|
||||||
|
buf.append("<input type=\"hidden\" name=\"nonce\" value=\"")
|
||||||
|
.append(_nonce).append("\" >\n");
|
||||||
|
String peerParam = req.getParameter("p");
|
||||||
|
if (peerParam != null) {
|
||||||
|
buf.append("<input type=\"hidden\" name=\"p\" value=\"")
|
||||||
|
.append(DataHelper.stripHTML(peerParam)).append("\" >\n");
|
||||||
|
}
|
||||||
|
String stParam = req.getParameter("st");
|
||||||
|
if (stParam != null) {
|
||||||
|
buf.append("<input type=\"hidden\" name=\"st\" value=\"")
|
||||||
|
.append(DataHelper.stripHTML(stParam)).append("\" >\n");
|
||||||
|
}
|
||||||
|
String soParam = req.getParameter("sort");
|
||||||
|
if (soParam != null) {
|
||||||
|
buf.append("<input type=\"hidden\" name=\"sort\" value=\"")
|
||||||
|
.append(DataHelper.stripHTML(soParam)).append("\" >\n");
|
||||||
|
}
|
||||||
|
if (action != null) {
|
||||||
|
buf.append("<input type=\"hidden\" name=\"action\" value=\"")
|
||||||
|
.append(action).append("\" >\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build HTML-escaped and stripped query string
|
||||||
|
*
|
||||||
|
* @param p override or "" for default or null to keep the same as in req
|
||||||
|
* @param st override or "" for default or null to keep the same as in req
|
||||||
|
* @param so override or "" for default or null to keep the same as in req
|
||||||
|
* @return non-null, possibly empty
|
||||||
|
* @since 0.9.16
|
||||||
|
*/
|
||||||
|
private static String getQueryString(HttpServletRequest req, String p, String st, String so) {
|
||||||
|
StringBuilder buf = new StringBuilder(64);
|
||||||
|
if (p == null) {
|
||||||
|
p = req.getParameter("p");
|
||||||
|
if (p != null)
|
||||||
|
p = DataHelper.stripHTML(p);
|
||||||
|
}
|
||||||
|
if (p != null && !p.equals(""))
|
||||||
|
buf.append("?p=").append(p);
|
||||||
|
if (so == null) {
|
||||||
|
so = req.getParameter("sort");
|
||||||
|
if (so != null)
|
||||||
|
so = DataHelper.stripHTML(so);
|
||||||
|
}
|
||||||
|
if (so != null && !so.equals("")) {
|
||||||
|
if (buf.length() <= 0)
|
||||||
|
buf.append("?sort=");
|
||||||
|
else
|
||||||
|
buf.append("&sort=");
|
||||||
|
buf.append(so);
|
||||||
|
}
|
||||||
|
if (st == null) {
|
||||||
|
st = req.getParameter("st");
|
||||||
|
if (st != null)
|
||||||
|
st = DataHelper.stripHTML(st);
|
||||||
|
}
|
||||||
|
if (st != null && !st.equals("")) {
|
||||||
|
if (buf.length() <= 0)
|
||||||
|
buf.append("?st=");
|
||||||
|
else
|
||||||
|
buf.append("&st=");
|
||||||
|
buf.append(st);
|
||||||
|
}
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @since 0.9.6
|
* @since 0.9.6
|
||||||
*/
|
*/
|
||||||
private void writePageNav(PrintWriter out, int start, int pageSize, int total,
|
private void writePageNav(PrintWriter out, HttpServletRequest req, int start, int pageSize, int total,
|
||||||
String peerParam, boolean noThinsp) {
|
boolean noThinsp) {
|
||||||
// Page nav
|
// Page nav
|
||||||
if (start > 0) {
|
if (start > 0) {
|
||||||
// First
|
// First
|
||||||
out.write("<a href=\"" + _contextPath);
|
out.write("<a href=\"" + _contextPath);
|
||||||
if (peerParam != null)
|
out.write(getQueryString(req, null, "", null));
|
||||||
out.write("?p=" + peerParam);
|
|
||||||
out.write("\">" +
|
out.write("\">" +
|
||||||
"<img alt=\"" + _("First") + "\" title=\"" + _("First page") + "\" border=\"0\" src=\"" +
|
"<img alt=\"" + _("First") + "\" title=\"" + _("First page") + "\" border=\"0\" src=\"" +
|
||||||
_imgPath + "control_rewind_blue.png\">" +
|
_imgPath + "control_rewind_blue.png\">" +
|
||||||
@ -655,9 +734,9 @@ public class I2PSnarkServlet extends BasicServlet {
|
|||||||
//if (prev > 0) {
|
//if (prev > 0) {
|
||||||
if (true) {
|
if (true) {
|
||||||
// Back
|
// Back
|
||||||
out.write(" <a href=\"" + _contextPath + "?st=" + prev);
|
out.write(" <a href=\"" + _contextPath);
|
||||||
if (peerParam != null)
|
String sprev = (prev > 0) ? Integer.toString(prev) : "";
|
||||||
out.write("&p=" + peerParam);
|
out.write(getQueryString(req, null, sprev, null));
|
||||||
out.write("\">" +
|
out.write("\">" +
|
||||||
"<img alt=\"" + _("Prev") + "\" title=\"" + _("Previous page") + "\" border=\"0\" src=\"" +
|
"<img alt=\"" + _("Prev") + "\" title=\"" + _("Previous page") + "\" border=\"0\" src=\"" +
|
||||||
_imgPath + "control_back_blue.png\">" +
|
_imgPath + "control_back_blue.png\">" +
|
||||||
@ -690,9 +769,8 @@ public class I2PSnarkServlet extends BasicServlet {
|
|||||||
//if (next + pageSize < total) {
|
//if (next + pageSize < total) {
|
||||||
if (true) {
|
if (true) {
|
||||||
// Next
|
// Next
|
||||||
out.write(" <a href=\"" + _contextPath + "?st=" + next);
|
out.write(" <a href=\"" + _contextPath);
|
||||||
if (peerParam != null)
|
out.write(getQueryString(req, null, Integer.toString(next), null));
|
||||||
out.write("&p=" + peerParam);
|
|
||||||
out.write("\">" +
|
out.write("\">" +
|
||||||
"<img alt=\"" + _("Next") + "\" title=\"" + _("Next page") + "\" border=\"0\" src=\"" +
|
"<img alt=\"" + _("Next") + "\" title=\"" + _("Next page") + "\" border=\"0\" src=\"" +
|
||||||
_imgPath + "control_play_blue.png\">" +
|
_imgPath + "control_play_blue.png\">" +
|
||||||
@ -700,9 +778,8 @@ public class I2PSnarkServlet extends BasicServlet {
|
|||||||
}
|
}
|
||||||
// Last
|
// Last
|
||||||
int last = ((total - 1) / pageSize) * pageSize;
|
int last = ((total - 1) / pageSize) * pageSize;
|
||||||
out.write(" <a href=\"" + _contextPath + "?st=" + last);
|
out.write(" <a href=\"" + _contextPath);
|
||||||
if (peerParam != null)
|
out.write(getQueryString(req, null, Integer.toString(last), null));
|
||||||
out.write("&p=" + peerParam);
|
|
||||||
out.write("\">" +
|
out.write("\">" +
|
||||||
"<img alt=\"" + _("Last") + "\" title=\"" + _("Last page") + "\" border=\"0\" src=\"" +
|
"<img alt=\"" + _("Last") + "\" title=\"" + _("Last page") + "\" border=\"0\" src=\"" +
|
||||||
_imgPath + "control_fastforward_blue.png\">" +
|
_imgPath + "control_fastforward_blue.png\">" +
|
||||||
@ -1190,34 +1267,16 @@ public class I2PSnarkServlet extends BasicServlet {
|
|||||||
return buf.toString();
|
return buf.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Sort alphabetically in current locale, ignore case, ignore leading "the "
|
|
||||||
* (I guess this is worth it, a lot of torrents start with "The "
|
|
||||||
* @since 0.7.14
|
|
||||||
*/
|
|
||||||
private static class TorrentNameComparator implements Comparator<Snark>, Serializable {
|
|
||||||
|
|
||||||
public int compare(Snark l, Snark r) {
|
|
||||||
// put downloads and magnets first
|
|
||||||
if (l.getStorage() == null && r.getStorage() != null)
|
|
||||||
return -1;
|
|
||||||
if (l.getStorage() != null && r.getStorage() == null)
|
|
||||||
return 1;
|
|
||||||
String ls = l.getBaseName();
|
|
||||||
String llc = ls.toLowerCase(Locale.US);
|
|
||||||
if (llc.startsWith("the ") || llc.startsWith("the.") || llc.startsWith("the_"))
|
|
||||||
ls = ls.substring(4);
|
|
||||||
String rs = r.getBaseName();
|
|
||||||
String rlc = rs.toLowerCase(Locale.US);
|
|
||||||
if (rlc.startsWith("the ") || rlc.startsWith("the.") || rlc.startsWith("the_"))
|
|
||||||
rs = rs.substring(4);
|
|
||||||
return Collator.getInstance().compare(ls, rs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<Snark> getSortedSnarks(HttpServletRequest req) {
|
private List<Snark> getSortedSnarks(HttpServletRequest req) {
|
||||||
ArrayList<Snark> rv = new ArrayList<Snark>(_manager.getTorrents());
|
ArrayList<Snark> rv = new ArrayList<Snark>(_manager.getTorrents());
|
||||||
Collections.sort(rv, new TorrentNameComparator());
|
int sort = 0;
|
||||||
|
String ssort = req.getParameter("sort");
|
||||||
|
if (ssort != null) {
|
||||||
|
try {
|
||||||
|
sort = Integer.parseInt(ssort);
|
||||||
|
} catch (NumberFormatException nfe) {}
|
||||||
|
}
|
||||||
|
Collections.sort(rv, Sorters.getComparator(sort));
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1229,11 +1288,11 @@ public class I2PSnarkServlet extends BasicServlet {
|
|||||||
*
|
*
|
||||||
* @param stats in/out param (totals)
|
* @param stats in/out param (totals)
|
||||||
* @param statsOnly if true, output nothing, update stats only
|
* @param statsOnly if true, output nothing, update stats only
|
||||||
* @param stParam non null; empty or e.g. &st=10
|
|
||||||
*/
|
*/
|
||||||
private void displaySnark(PrintWriter out, Snark snark, String uri, int row, long stats[], boolean showPeers,
|
private void displaySnark(PrintWriter out, HttpServletRequest req,
|
||||||
boolean isDegraded, boolean noThinsp, boolean showDebug, boolean statsOnly,
|
Snark snark, String uri, int row, long stats[], boolean showPeers,
|
||||||
String stParam) throws IOException {
|
boolean isDegraded, boolean noThinsp, boolean showDebug, boolean statsOnly)
|
||||||
|
throws IOException {
|
||||||
// stats
|
// stats
|
||||||
long uploaded = snark.getUploaded();
|
long uploaded = snark.getUploaded();
|
||||||
stats[0] += snark.getDownloaded();
|
stats[0] += snark.getDownloaded();
|
||||||
@ -1335,7 +1394,7 @@ public class I2PSnarkServlet extends BasicServlet {
|
|||||||
if (curPeers > 0 && !showPeers)
|
if (curPeers > 0 && !showPeers)
|
||||||
statusString = "<img alt=\"\" border=\"0\" src=\"" + _imgPath + img + ".png\" title=\"" + txt + "\"></td>" +
|
statusString = "<img alt=\"\" border=\"0\" src=\"" + _imgPath + img + ".png\" title=\"" + txt + "\"></td>" +
|
||||||
"<td class=\"snarkTorrentStatus\">" + txt +
|
"<td class=\"snarkTorrentStatus\">" + txt +
|
||||||
": <a href=\"" + uri + "?p=" + Base64.encode(snark.getInfoHash()) + stParam + "\">" +
|
": <a href=\"" + uri + getQueryString(req, Base64.encode(snark.getInfoHash()), null, null) + "\">" +
|
||||||
curPeers + thinsp(noThinsp) +
|
curPeers + thinsp(noThinsp) +
|
||||||
ngettext("1 peer", "{0} peers", knownPeers) + "</a>";
|
ngettext("1 peer", "{0} peers", knownPeers) + "</a>";
|
||||||
else
|
else
|
||||||
@ -1351,7 +1410,7 @@ public class I2PSnarkServlet extends BasicServlet {
|
|||||||
if (isRunning && curPeers > 0 && downBps > 0 && !showPeers)
|
if (isRunning && curPeers > 0 && downBps > 0 && !showPeers)
|
||||||
statusString = "<img alt=\"\" border=\"0\" src=\"" + _imgPath + "downloading.png\" title=\"" + _("OK") + "\"></td>" +
|
statusString = "<img alt=\"\" border=\"0\" src=\"" + _imgPath + "downloading.png\" title=\"" + _("OK") + "\"></td>" +
|
||||||
"<td class=\"snarkTorrentStatus\">" + _("OK") +
|
"<td class=\"snarkTorrentStatus\">" + _("OK") +
|
||||||
": <a href=\"" + uri + "?p=" + Base64.encode(snark.getInfoHash()) + stParam + "\">" +
|
": <a href=\"" + uri + getQueryString(req, Base64.encode(snark.getInfoHash()), null, null) + "\">" +
|
||||||
curPeers + thinsp(noThinsp) +
|
curPeers + thinsp(noThinsp) +
|
||||||
ngettext("1 peer", "{0} peers", knownPeers) + "</a>";
|
ngettext("1 peer", "{0} peers", knownPeers) + "</a>";
|
||||||
else if (isRunning && curPeers > 0 && downBps > 0)
|
else if (isRunning && curPeers > 0 && downBps > 0)
|
||||||
@ -1362,7 +1421,7 @@ public class I2PSnarkServlet extends BasicServlet {
|
|||||||
else if (isRunning && curPeers > 0 && !showPeers)
|
else if (isRunning && curPeers > 0 && !showPeers)
|
||||||
statusString = "<img alt=\"\" border=\"0\" src=\"" + _imgPath + "stalled.png\" title=\"" + _("Stalled") + "\"></td>" +
|
statusString = "<img alt=\"\" border=\"0\" src=\"" + _imgPath + "stalled.png\" title=\"" + _("Stalled") + "\"></td>" +
|
||||||
"<td class=\"snarkTorrentStatus\">" + _("Stalled") +
|
"<td class=\"snarkTorrentStatus\">" + _("Stalled") +
|
||||||
": <a href=\"" + uri + "?p=" + Base64.encode(snark.getInfoHash()) + stParam + "\">" +
|
": <a href=\"" + uri + getQueryString(req, Base64.encode(snark.getInfoHash()), null, null) + "\">" +
|
||||||
curPeers + thinsp(noThinsp) +
|
curPeers + thinsp(noThinsp) +
|
||||||
ngettext("1 peer", "{0} peers", knownPeers) + "</a>";
|
ngettext("1 peer", "{0} peers", knownPeers) + "</a>";
|
||||||
else if (isRunning && curPeers > 0)
|
else if (isRunning && curPeers > 0)
|
||||||
@ -1484,7 +1543,8 @@ public class I2PSnarkServlet extends BasicServlet {
|
|||||||
} else if (isRunning) {
|
} else if (isRunning) {
|
||||||
// Stop Button
|
// Stop Button
|
||||||
if (isDegraded)
|
if (isDegraded)
|
||||||
out.write("<a href=\"" + _contextPath + "/?action=Stop_" + b64 + "&nonce=" + _nonce + stParam + "\"><img title=\"");
|
out.write("<a href=\"" + _contextPath + "/?action=Stop_" + b64 + "&nonce=" + _nonce +
|
||||||
|
getQueryString(req, "", null, null).replace("?", "&") + "\"><img title=\"");
|
||||||
else
|
else
|
||||||
out.write("<input type=\"image\" name=\"action_Stop_" + b64 + "\" value=\"foo\" title=\"");
|
out.write("<input type=\"image\" name=\"action_Stop_" + b64 + "\" value=\"foo\" title=\"");
|
||||||
out.write(_("Stop the torrent"));
|
out.write(_("Stop the torrent"));
|
||||||
@ -1498,7 +1558,8 @@ public class I2PSnarkServlet extends BasicServlet {
|
|||||||
// Start Button
|
// Start Button
|
||||||
// This works in Opera but it's displayed a little differently, so use noThinsp here too so all 3 icons are consistent
|
// This works in Opera but it's displayed a little differently, so use noThinsp here too so all 3 icons are consistent
|
||||||
if (noThinsp)
|
if (noThinsp)
|
||||||
out.write("<a href=\"" + _contextPath + "/?action=Start_" + b64 + "&nonce=" + _nonce + stParam + "\"><img title=\"");
|
out.write("<a href=\"" + _contextPath + "/?action=Start_" + b64 + "&nonce=" + _nonce +
|
||||||
|
getQueryString(req, "", null, null).replace("?", "&") + "\"><img title=\"");
|
||||||
else
|
else
|
||||||
out.write("<input type=\"image\" name=\"action_Start_" + b64 + "\" value=\"foo\" title=\"");
|
out.write("<input type=\"image\" name=\"action_Start_" + b64 + "\" value=\"foo\" title=\"");
|
||||||
out.write(_("Start the torrent"));
|
out.write(_("Start the torrent"));
|
||||||
@ -1512,7 +1573,8 @@ public class I2PSnarkServlet extends BasicServlet {
|
|||||||
// Remove Button
|
// Remove Button
|
||||||
// Doesnt work with Opera so use noThinsp instead of isDegraded
|
// Doesnt work with Opera so use noThinsp instead of isDegraded
|
||||||
if (noThinsp)
|
if (noThinsp)
|
||||||
out.write("<a href=\"" + _contextPath + "/?action=Remove_" + b64 + "&nonce=" + _nonce + stParam + "\"><img title=\"");
|
out.write("<a href=\"" + _contextPath + "/?action=Remove_" + b64 + "&nonce=" + _nonce +
|
||||||
|
getQueryString(req, "", null, null).replace("?", "&") + "\"><img title=\"");
|
||||||
else
|
else
|
||||||
out.write("<input type=\"image\" name=\"action_Remove_" + b64 + "\" value=\"foo\" title=\"");
|
out.write("<input type=\"image\" name=\"action_Remove_" + b64 + "\" value=\"foo\" title=\"");
|
||||||
out.write(_("Remove the torrent from the active list, deleting the .torrent file"));
|
out.write(_("Remove the torrent from the active list, deleting the .torrent file"));
|
||||||
@ -1532,7 +1594,8 @@ public class I2PSnarkServlet extends BasicServlet {
|
|||||||
// Delete Button
|
// Delete Button
|
||||||
// Doesnt work with Opera so use noThinsp instead of isDegraded
|
// Doesnt work with Opera so use noThinsp instead of isDegraded
|
||||||
if (noThinsp)
|
if (noThinsp)
|
||||||
out.write("<a href=\"" + _contextPath + "/?action=Delete_" + b64 + "&nonce=" + _nonce + stParam + "\"><img title=\"");
|
out.write("<a href=\"" + _contextPath + "/?action=Delete_" + b64 + "&nonce=" + _nonce +
|
||||||
|
getQueryString(req, "", null, null).replace("?", "&") + "\"><img title=\"");
|
||||||
else
|
else
|
||||||
out.write("<input type=\"image\" name=\"action_Delete_" + b64 + "\" value=\"foo\" title=\"");
|
out.write("<input type=\"image\" name=\"action_Delete_" + b64 + "\" value=\"foo\" title=\"");
|
||||||
out.write(_("Delete the .torrent file and the associated data file(s)"));
|
out.write(_("Delete the .torrent file and the associated data file(s)"));
|
||||||
@ -1826,12 +1889,7 @@ public class I2PSnarkServlet extends BasicServlet {
|
|||||||
out.write("<div class=\"snarkNewTorrent\">\n");
|
out.write("<div class=\"snarkNewTorrent\">\n");
|
||||||
// *not* enctype="multipart/form-data", so that the input type=file sends the filename, not the file
|
// *not* enctype="multipart/form-data", so that the input type=file sends the filename, not the file
|
||||||
out.write("<form action=\"_post\" method=\"POST\">\n");
|
out.write("<form action=\"_post\" method=\"POST\">\n");
|
||||||
out.write("<input type=\"hidden\" name=\"nonce\" value=\"" + _nonce + "\" >\n");
|
writeHiddenInputs(out, req, "Add");
|
||||||
out.write("<input type=\"hidden\" name=\"action\" value=\"Add\" >\n");
|
|
||||||
// don't lose peer setting
|
|
||||||
String peerParam = req.getParameter("p");
|
|
||||||
if (peerParam != null)
|
|
||||||
out.write("<input type=\"hidden\" name=\"p\" value=\"" + DataHelper.stripHTML(peerParam) + "\" >\n");
|
|
||||||
out.write("<div class=\"addtorrentsection\"><span class=\"snarkConfigTitle\">");
|
out.write("<div class=\"addtorrentsection\"><span class=\"snarkConfigTitle\">");
|
||||||
out.write("<img alt=\"\" border=\"0\" src=\"" + _imgPath + "add.png\"> ");
|
out.write("<img alt=\"\" border=\"0\" src=\"" + _imgPath + "add.png\"> ");
|
||||||
out.write(_("Add Torrent"));
|
out.write(_("Add Torrent"));
|
||||||
@ -1858,12 +1916,7 @@ public class I2PSnarkServlet extends BasicServlet {
|
|||||||
out.write("<a name=\"add\"></a><div class=\"newtorrentsection\"><div class=\"snarkNewTorrent\">\n");
|
out.write("<a name=\"add\"></a><div class=\"newtorrentsection\"><div class=\"snarkNewTorrent\">\n");
|
||||||
// *not* enctype="multipart/form-data", so that the input type=file sends the filename, not the file
|
// *not* enctype="multipart/form-data", so that the input type=file sends the filename, not the file
|
||||||
out.write("<form action=\"_post\" method=\"POST\">\n");
|
out.write("<form action=\"_post\" method=\"POST\">\n");
|
||||||
out.write("<input type=\"hidden\" name=\"nonce\" value=\"" + _nonce + "\" >\n");
|
writeHiddenInputs(out, req, "Create");
|
||||||
out.write("<input type=\"hidden\" name=\"action\" value=\"Create\" >\n");
|
|
||||||
// don't lose peer setting
|
|
||||||
String peerParam = req.getParameter("p");
|
|
||||||
if (peerParam != null)
|
|
||||||
out.write("<input type=\"hidden\" name=\"p\" value=\"" + DataHelper.stripHTML(peerParam) + "\" >\n");
|
|
||||||
out.write("<span class=\"snarkConfigTitle\">");
|
out.write("<span class=\"snarkConfigTitle\">");
|
||||||
out.write("<img alt=\"\" border=\"0\" src=\"" + _imgPath + "create.png\"> ");
|
out.write("<img alt=\"\" border=\"0\" src=\"" + _imgPath + "create.png\"> ");
|
||||||
out.write(_("Create Torrent"));
|
out.write(_("Create Torrent"));
|
||||||
@ -1929,10 +1982,9 @@ public class I2PSnarkServlet extends BasicServlet {
|
|||||||
//int seedPct = 0;
|
//int seedPct = 0;
|
||||||
|
|
||||||
out.write("<form action=\"" + _contextPath + "/configure\" method=\"POST\">\n" +
|
out.write("<form action=\"" + _contextPath + "/configure\" method=\"POST\">\n" +
|
||||||
"<div class=\"configsectionpanel\"><div class=\"snarkConfig\">\n" +
|
"<div class=\"configsectionpanel\"><div class=\"snarkConfig\">\n");
|
||||||
"<input type=\"hidden\" name=\"nonce\" value=\"" + _nonce + "\" >\n" +
|
writeHiddenInputs(out, req, "Save");
|
||||||
"<input type=\"hidden\" name=\"action\" value=\"Save\" >\n" +
|
out.write("<span class=\"snarkConfigTitle\">" +
|
||||||
"<span class=\"snarkConfigTitle\">" +
|
|
||||||
"<img alt=\"\" border=\"0\" src=\"" + _imgPath + "config.png\"> ");
|
"<img alt=\"\" border=\"0\" src=\"" + _imgPath + "config.png\"> ");
|
||||||
out.write(_("Configuration"));
|
out.write(_("Configuration"));
|
||||||
out.write("</span><hr>\n" +
|
out.write("</span><hr>\n" +
|
||||||
@ -2115,10 +2167,9 @@ public class I2PSnarkServlet extends BasicServlet {
|
|||||||
private void writeTrackerForm(PrintWriter out, HttpServletRequest req) throws IOException {
|
private void writeTrackerForm(PrintWriter out, HttpServletRequest req) throws IOException {
|
||||||
StringBuilder buf = new StringBuilder(1024);
|
StringBuilder buf = new StringBuilder(1024);
|
||||||
buf.append("<form action=\"" + _contextPath + "/configure\" method=\"POST\">\n" +
|
buf.append("<form action=\"" + _contextPath + "/configure\" method=\"POST\">\n" +
|
||||||
"<div class=\"configsectionpanel\"><div class=\"snarkConfig\">\n" +
|
"<div class=\"configsectionpanel\"><div class=\"snarkConfig\">\n");
|
||||||
"<input type=\"hidden\" name=\"nonce\" value=\"" + _nonce + "\" >\n" +
|
writeHiddenInputs(buf, req, "Save2");
|
||||||
"<input type=\"hidden\" name=\"action\" value=\"Save2\" >\n" +
|
buf.append("<span class=\"snarkConfigTitle\">" +
|
||||||
"<span class=\"snarkConfigTitle\">" +
|
|
||||||
"<img alt=\"\" border=\"0\" src=\"" + _imgPath + "config.png\"> ");
|
"<img alt=\"\" border=\"0\" src=\"" + _imgPath + "config.png\"> ");
|
||||||
buf.append(_("Trackers"));
|
buf.append(_("Trackers"));
|
||||||
buf.append("</span><hr>\n" +
|
buf.append("</span><hr>\n" +
|
||||||
|
261
apps/i2psnark/java/src/org/klomp/snark/web/Sorters.java
Normal file
261
apps/i2psnark/java/src/org/klomp/snark/web/Sorters.java
Normal file
@ -0,0 +1,261 @@
|
|||||||
|
package org.klomp.snark.web;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.text.Collator;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import org.klomp.snark.Snark;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Comparators for various columns
|
||||||
|
*
|
||||||
|
* @since 0.9.16 moved from I2PSnarkservlet
|
||||||
|
*/
|
||||||
|
class Sorters {
|
||||||
|
|
||||||
|
public static Comparator<Snark> getComparator(int type) {
|
||||||
|
boolean rev = type < 0;
|
||||||
|
Comparator<Snark> rv;
|
||||||
|
switch (type) {
|
||||||
|
|
||||||
|
case -1:
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
default:
|
||||||
|
rv = new TorrentNameComparator();
|
||||||
|
if (rev)
|
||||||
|
rv = Collections.reverseOrder(rv);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case -2:
|
||||||
|
case 2:
|
||||||
|
rv = new StatusComparator(rev);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case -3:
|
||||||
|
case 3:
|
||||||
|
rv = new PeersComparator(rev);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case -4:
|
||||||
|
case 4:
|
||||||
|
rv = new ETAComparator(rev);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case -5:
|
||||||
|
case 5:
|
||||||
|
rv = new SizeComparator(rev);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case -6:
|
||||||
|
case 6:
|
||||||
|
rv = new DownloadedComparator(rev);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case -7:
|
||||||
|
case 7:
|
||||||
|
rv = new UploadedComparator(rev);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case -8:
|
||||||
|
case 8:
|
||||||
|
rv = new DownRateComparator(rev);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case -9:
|
||||||
|
case 9:
|
||||||
|
rv = new UpRateComparator(rev);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case -10:
|
||||||
|
case 10:
|
||||||
|
rv = new RemainingComparator(rev);
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sort alphabetically in current locale, ignore case, ignore leading "the "
|
||||||
|
* (I guess this is worth it, a lot of torrents start with "The "
|
||||||
|
* @since 0.7.14
|
||||||
|
*/
|
||||||
|
private static class TorrentNameComparator implements Comparator<Snark>, Serializable {
|
||||||
|
|
||||||
|
public int compare(Snark l, Snark r) {
|
||||||
|
return comp(l, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int comp(Snark l, Snark r) {
|
||||||
|
// put downloads and magnets first
|
||||||
|
if (l.getStorage() == null && r.getStorage() != null)
|
||||||
|
return -1;
|
||||||
|
if (l.getStorage() != null && r.getStorage() == null)
|
||||||
|
return 1;
|
||||||
|
String ls = l.getBaseName();
|
||||||
|
String llc = ls.toLowerCase(Locale.US);
|
||||||
|
if (llc.startsWith("the ") || llc.startsWith("the.") || llc.startsWith("the_"))
|
||||||
|
ls = ls.substring(4);
|
||||||
|
String rs = r.getBaseName();
|
||||||
|
String rlc = rs.toLowerCase(Locale.US);
|
||||||
|
if (rlc.startsWith("the ") || rlc.startsWith("the.") || rlc.startsWith("the_"))
|
||||||
|
rs = rs.substring(4);
|
||||||
|
return Collator.getInstance().compare(ls, rs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forward or reverse sort, but the fallback is always forward
|
||||||
|
*/
|
||||||
|
private static abstract class Sort implements Comparator<Snark>, Serializable {
|
||||||
|
|
||||||
|
private final boolean _rev;
|
||||||
|
|
||||||
|
public Sort(boolean rev) {
|
||||||
|
_rev = rev;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int compare(Snark l, Snark r) {
|
||||||
|
int rv = compareIt(l, r);
|
||||||
|
if (rv != 0)
|
||||||
|
return _rev ? 0 - rv : rv;
|
||||||
|
return TorrentNameComparator.comp(l, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract int compareIt(Snark l, Snark r);
|
||||||
|
|
||||||
|
protected static int compLong(long l, long r) {
|
||||||
|
if (l < r)
|
||||||
|
return -1;
|
||||||
|
if (l > r)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static class StatusComparator extends Sort {
|
||||||
|
|
||||||
|
private StatusComparator(boolean rev) { super(rev); }
|
||||||
|
|
||||||
|
public int compareIt(Snark l, Snark r) {
|
||||||
|
return getStatus(l) - getStatus(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int getStatus(Snark snark) {
|
||||||
|
long remaining = snark.getRemainingLength();
|
||||||
|
long needed = snark.getNeededLength();
|
||||||
|
if (snark.isStopped()) {
|
||||||
|
if (remaining < 0)
|
||||||
|
return 0;
|
||||||
|
if (remaining > 0)
|
||||||
|
return 5;
|
||||||
|
return 10;
|
||||||
|
}
|
||||||
|
if (snark.isStarting())
|
||||||
|
return 15;
|
||||||
|
if (snark.isAllocating())
|
||||||
|
return 20;
|
||||||
|
if (remaining < 0)
|
||||||
|
return 15; // magnet
|
||||||
|
if (remaining == 0)
|
||||||
|
return 100;
|
||||||
|
if (snark.isChecking())
|
||||||
|
return 95;
|
||||||
|
if (snark.getNeededLength() <= 0)
|
||||||
|
return 90;
|
||||||
|
if (snark.getPeerCount() <= 0)
|
||||||
|
return 40;
|
||||||
|
if (snark.getDownloadRate() <= 0)
|
||||||
|
return 50;
|
||||||
|
return 60;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class PeersComparator extends Sort {
|
||||||
|
|
||||||
|
public PeersComparator(boolean rev) { super(rev); }
|
||||||
|
|
||||||
|
public int compareIt(Snark l, Snark r) {
|
||||||
|
return l.getPeerCount() - r.getPeerCount();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class RemainingComparator extends Sort {
|
||||||
|
|
||||||
|
public RemainingComparator(boolean rev) { super(rev); }
|
||||||
|
|
||||||
|
public int compareIt(Snark l, Snark r) {
|
||||||
|
return compLong(l.getNeededLength(), r.getNeededLength());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ETAComparator extends Sort {
|
||||||
|
|
||||||
|
public ETAComparator(boolean rev) { super(rev); }
|
||||||
|
|
||||||
|
public int compareIt(Snark l, Snark r) {
|
||||||
|
return compLong(eta(l), eta(r));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static long eta(Snark snark) {
|
||||||
|
long needed = snark.getNeededLength();
|
||||||
|
long total = snark.getTotalLength();
|
||||||
|
if (needed > total)
|
||||||
|
needed = total;
|
||||||
|
long remainingSeconds;
|
||||||
|
long downBps = snark.getDownloadRate();
|
||||||
|
if (downBps > 0 && needed > 0)
|
||||||
|
return needed / downBps;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class SizeComparator extends Sort {
|
||||||
|
|
||||||
|
public SizeComparator(boolean rev) { super(rev); }
|
||||||
|
|
||||||
|
public int compareIt(Snark l, Snark r) {
|
||||||
|
return compLong(l.getTotalLength(), r.getTotalLength());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static class DownloadedComparator extends Sort {
|
||||||
|
|
||||||
|
public DownloadedComparator(boolean rev) { super(rev); }
|
||||||
|
|
||||||
|
public int compareIt(Snark l, Snark r) {
|
||||||
|
return compLong(l.getDownloaded(), r.getDownloaded());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class UploadedComparator extends Sort {
|
||||||
|
|
||||||
|
public UploadedComparator(boolean rev) { super(rev); }
|
||||||
|
|
||||||
|
public int compareIt(Snark l, Snark r) {
|
||||||
|
return compLong(l.getUploaded(), r.getUploaded());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class DownRateComparator extends Sort {
|
||||||
|
|
||||||
|
public DownRateComparator(boolean rev) { super(rev); }
|
||||||
|
|
||||||
|
public int compareIt(Snark l, Snark r) {
|
||||||
|
return compLong(l.getDownloadRate(), r.getDownloadRate());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class UpRateComparator extends Sort {
|
||||||
|
|
||||||
|
public UpRateComparator(boolean rev) { super(rev); }
|
||||||
|
|
||||||
|
public int compareIt(Snark l, Snark r) {
|
||||||
|
return compLong(l.getUploadRate(), r.getUploadRate());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user