* i2psnark: Listing fixes and cleanups; icons on front page; tweak bw choker again
This commit is contained in:
@ -115,10 +115,10 @@ class PeerCheckerTask extends TimerTask
|
||||
+ " C: " + peer.isChoked(),
|
||||
Snark.DEBUG);
|
||||
|
||||
// Choke a third of them rather than all so it isn't so drastic...
|
||||
// Choke a percentage of them rather than all so it isn't so drastic...
|
||||
// unless this torrent is over the limit all by itself.
|
||||
boolean overBWLimitChoke = upload > 0 &&
|
||||
((overBWLimit && random.nextInt(3) == 0) ||
|
||||
((overBWLimit && random.nextInt(5) < 2) ||
|
||||
(coordinator.overUpBWLimit(uploaded)));
|
||||
|
||||
// If we are at our max uploaders and we have lots of other
|
||||
|
@ -734,7 +734,7 @@ public class Snark
|
||||
//if (debug >= INFO && t != null)
|
||||
// t.printStackTrace();
|
||||
stopTorrent();
|
||||
throw new RuntimeException(s + (t == null ? "" : ": " + t.getMessage()));
|
||||
throw new RuntimeException(s + (t == null ? "" : ": " + t));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -287,7 +287,7 @@ public class Storage
|
||||
}
|
||||
|
||||
/**
|
||||
* @param file absolute path (non-directory)
|
||||
* @param file canonical path (non-directory)
|
||||
* @return number of bytes remaining; -1 if unknown file
|
||||
* @since 0.7.14
|
||||
*/
|
||||
@ -295,7 +295,16 @@ public class Storage
|
||||
long bytes = 0;
|
||||
for (int i = 0; i < rafs.length; i++) {
|
||||
File f = RAFfile[i];
|
||||
if (f != null && f.getAbsolutePath().equals(file)) {
|
||||
// use canonical in case snark dir or sub dirs are symlinked
|
||||
String canonical = null;
|
||||
if (f != null) {
|
||||
try {
|
||||
canonical = f.getCanonicalPath();
|
||||
} catch (IOException ioe) {
|
||||
f = null;
|
||||
}
|
||||
}
|
||||
if (f != null && canonical.equals(file)) {
|
||||
if (complete())
|
||||
return 0;
|
||||
int psz = metainfo.getPieceLength(0);
|
||||
@ -305,7 +314,8 @@ public class Storage
|
||||
long rv = 0;
|
||||
if (!bitfield.get(pc))
|
||||
rv = Math.min(psz - (start % psz), lengths[i]);
|
||||
for (int j = pc + 1; j * psz < end; j++) {
|
||||
int pieces = metainfo.getPieces();
|
||||
for (int j = pc + 1; j * psz < end && j < pieces; j++) {
|
||||
if (!bitfield.get(j)) {
|
||||
if ((j+1)*psz < end)
|
||||
rv += psz;
|
||||
|
@ -271,7 +271,7 @@ public class I2PSnarkServlet extends Default {
|
||||
out.write(" (");
|
||||
out.write(_("{0} torrents", snarks.size()));
|
||||
out.write(", ");
|
||||
out.write(DataHelper.formatSize(stats[5]) + "B, ");
|
||||
out.write(DataHelper.formatSize2(stats[5]) + "B, ");
|
||||
out.write(_("{0} connected peers", stats[4]));
|
||||
out.write(")</th>\n" +
|
||||
" <th> </th>\n" +
|
||||
@ -683,6 +683,12 @@ public class I2PSnarkServlet extends Default {
|
||||
out.write(_("Open file"));
|
||||
out.write("\">");
|
||||
}
|
||||
String icon;
|
||||
if (snark.meta.getFiles() != null)
|
||||
icon = "folder";
|
||||
else
|
||||
icon = toIcon(fullFilename);
|
||||
out.write(toImg(icon));
|
||||
out.write(filename);
|
||||
if (remaining == 0 || snark.meta.getFiles() != null)
|
||||
out.write("</a>");
|
||||
@ -1078,7 +1084,7 @@ public class I2PSnarkServlet extends Default {
|
||||
private static final String HOPS = _x("hops");
|
||||
private static final String TUNNELS = _x("tunnels");
|
||||
|
||||
/** modded from ConfigTunnelsHelper */
|
||||
/** modded from ConfigTunnelsHelper @since 0.7.14 */
|
||||
private String renderOptions(int min, int max, String strNow, String selName, String name) {
|
||||
int now = 2;
|
||||
try {
|
||||
@ -1130,6 +1136,7 @@ public class I2PSnarkServlet extends Default {
|
||||
return ((bytes + 512*1024*1024)/(1024*1024*1024)) + " GB";
|
||||
}
|
||||
|
||||
/** @since 0.7.14 */
|
||||
private static String urlify(String s) {
|
||||
StringBuilder buf = new StringBuilder(256);
|
||||
buf.append("<a href=\"").append(s).append("\">").append(s).append("</a>");
|
||||
@ -1174,6 +1181,7 @@ public class I2PSnarkServlet extends Default {
|
||||
* @param base The base URL
|
||||
* @param parent True if the parent directory should be included
|
||||
* @return String of HTML
|
||||
* @since 0.7.14
|
||||
*/
|
||||
private String getListHTML(Resource r, String base, boolean parent)
|
||||
throws IOException
|
||||
@ -1247,14 +1255,12 @@ public class I2PSnarkServlet extends Default {
|
||||
long length = item.length();
|
||||
if (item.isDirectory()) {
|
||||
complete = true;
|
||||
status = "<img height=\"16\" width=\"16\" src=\"/i2psnark/_icons/tick.png\"> " +
|
||||
_("Directory");
|
||||
status = toImg("tick") + _("Directory");
|
||||
} else {
|
||||
if (snark == null) {
|
||||
// Assume complete, perhaps he removed a completed torrent but kept a bookmark
|
||||
complete = true;
|
||||
status = "<img height=\"16\" width=\"16\" src=\"/i2psnark/_icons/cancel.png\"> " +
|
||||
_("Torrent not found?");
|
||||
status = toImg("cancel") + _("Torrent not found?");
|
||||
} else {
|
||||
try {
|
||||
File f = item.getFile();
|
||||
@ -1262,16 +1268,14 @@ public class I2PSnarkServlet extends Default {
|
||||
long remaining = snark.storage.remaining(f.getCanonicalPath());
|
||||
if (remaining < 0) {
|
||||
complete = true;
|
||||
status = "<img height=\"16\" width=\"16\" src=\"/i2psnark/_icons/cancel.png\"> " +
|
||||
_("File not found in torrent?");
|
||||
status = toImg("cancel") + _("File not found in torrent?");
|
||||
} else if (remaining == 0 || length <= 0) {
|
||||
complete = true;
|
||||
status = "<img height=\"16\" width=\"16\" src=\"/i2psnark/_icons/tick.png\"> " +
|
||||
_("Complete");
|
||||
status = toImg("tick") + _("Complete");
|
||||
} else {
|
||||
status = "<img height=\"16\" width=\"16\" src=\"/i2psnark/_icons/clock.png\"> " +
|
||||
(100 - (100 * remaining / length)) + "% " + _("complete") +
|
||||
" (" + DataHelper.formatSize(remaining) + " " + _("bytes remaining") + ")";
|
||||
status = toImg("clock") +
|
||||
(100 * (length - remaining) / length) + "% " + _("complete") +
|
||||
" (" + DataHelper.formatSize2(remaining) + _("bytes remaining") + ")";
|
||||
}
|
||||
} else {
|
||||
status = "Not a file?";
|
||||
@ -1285,71 +1289,31 @@ public class I2PSnarkServlet extends Default {
|
||||
String path=URI.addPaths(base,encoded);
|
||||
if (item.isDirectory() && !path.endsWith("/"))
|
||||
path=URI.addPaths(path,"/");
|
||||
String plc = path.toLowerCase();
|
||||
String icon = toIcon(item);
|
||||
|
||||
// pick an icon; try to catch the common types in an i2p environment
|
||||
String icon;
|
||||
if (item.isDirectory()) {
|
||||
icon = "folder";
|
||||
} else {
|
||||
// Should really just add to the mime.properties file in org.mortbay.jetty.jar
|
||||
// instead of this mishmash. We can't get to HttpContext.setMimeMapping()
|
||||
// from here? We could do it from a web.xml perhaps.
|
||||
// Or could we put our own org/mortbay/http/mime.properties file in the war?
|
||||
String mime = getServletContext().getMimeType(path);
|
||||
if (mime == null)
|
||||
mime = "";
|
||||
if (mime.equals("text/html"))
|
||||
icon = "html";
|
||||
else if (mime.equals("text/plain") || plc.endsWith(".nfo"))
|
||||
icon = "page";
|
||||
else if (mime.equals("application/java-archive") || plc.endsWith(".war"))
|
||||
icon = "package";
|
||||
else if (plc.endsWith(".xpi2p"))
|
||||
icon = "plugin";
|
||||
else if (mime.equals("application/pdf"))
|
||||
icon = "page_white_acrobat";
|
||||
else if (mime.startsWith("image/") || plc.endsWith(".ico"))
|
||||
icon = "photo";
|
||||
else if (mime.startsWith("audio/") || mime.equals("application/ogg") ||
|
||||
plc.endsWith(".flac") || plc.endsWith(".m4a") || plc.endsWith(".wma") ||
|
||||
plc.endsWith(".ape"))
|
||||
icon = "music";
|
||||
else if (mime.startsWith("video/") || plc.endsWith(".mkv") || plc.endsWith(".m4v") ||
|
||||
plc.endsWith(".mp4"))
|
||||
icon = "film";
|
||||
else if (mime.equals("application/zip") || mime.equals("application/x-gtar") ||
|
||||
mime.equals("application/compress") || mime.equals("application/gzip") ||
|
||||
mime.equals("application/x-tar") ||
|
||||
plc.endsWith(".rar") || plc.endsWith(".bz2") || plc.endsWith(".7z"))
|
||||
icon = "compress";
|
||||
else if (plc.endsWith(".exe"))
|
||||
icon = "application";
|
||||
else
|
||||
icon = "bug";
|
||||
}
|
||||
if (complete) {
|
||||
buf.append("<a href=\"").append(path).append("\"><img alt=\"\" border=\"0\" ");
|
||||
buf.append("<a href=\"").append(path).append("\">");
|
||||
// thumbnail ?
|
||||
String plc = item.toString().toLowerCase();
|
||||
if (plc.endsWith(".jpg") || plc.endsWith(".jpeg") || plc.endsWith(".png") ||
|
||||
plc.endsWith(".gif") || plc.endsWith(".ico")) {
|
||||
buf.append("class=\"thumb\" src=\"")
|
||||
buf.append("<img alt=\"\" border=\"0\" class=\"thumb\" src=\"")
|
||||
.append(path).append("\"></a> ");
|
||||
} else {
|
||||
buf.append("height=\"16\" width=\"16\" src=\"/i2psnark/_icons/").append(icon).append(".png\"></a> ");
|
||||
buf.append(toImg(icon));
|
||||
}
|
||||
buf.append("<A HREF=\"");
|
||||
buf.append(path);
|
||||
buf.append("\">");
|
||||
} else {
|
||||
buf.append("<img height=\"16\" width=\"16\" src=\"/i2psnark/_icons/").append(icon).append(".png\"> ");
|
||||
buf.append(toImg(icon));
|
||||
}
|
||||
buf.append(ls[i]);
|
||||
if (complete)
|
||||
buf.append("</a>");
|
||||
buf.append("</TD><TD ALIGN=right class=\"").append(rowClass).append(" snarkFileSize\">");
|
||||
if (!item.isDirectory())
|
||||
buf.append(DataHelper.formatSize(length)).append(' ').append(_("Bytes"));
|
||||
buf.append(DataHelper.formatSize2(length)).append('B');
|
||||
buf.append("</TD><TD class=\"").append(rowClass).append(" snarkFileStatus\">");
|
||||
//buf.append(dfmt.format(new Date(item.lastModified())));
|
||||
buf.append(status);
|
||||
@ -1361,6 +1325,64 @@ public class I2PSnarkServlet extends Default {
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/** @since 0.7.14 */
|
||||
private String toIcon(Resource item) {
|
||||
if (item.isDirectory())
|
||||
return "folder";
|
||||
return toIcon(item.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Pick an icon; try to catch the common types in an i2p environment
|
||||
* @return file name not including ".png"
|
||||
* @since 0.7.14
|
||||
*/
|
||||
private String toIcon(String path) {
|
||||
String icon;
|
||||
// Should really just add to the mime.properties file in org.mortbay.jetty.jar
|
||||
// instead of this mishmash. We can't get to HttpContext.setMimeMapping()
|
||||
// from here? We could do it from a web.xml perhaps.
|
||||
// Or could we put our own org/mortbay/http/mime.properties file in the war?
|
||||
String plc = path.toLowerCase();
|
||||
String mime = getServletContext().getMimeType(path);
|
||||
if (mime == null)
|
||||
mime = "";
|
||||
if (mime.equals("text/html"))
|
||||
icon = "html";
|
||||
else if (mime.equals("text/plain") || plc.endsWith(".nfo"))
|
||||
icon = "page";
|
||||
else if (mime.equals("application/java-archive") || plc.endsWith(".war"))
|
||||
icon = "package";
|
||||
else if (plc.endsWith(".xpi2p"))
|
||||
icon = "plugin";
|
||||
else if (mime.equals("application/pdf"))
|
||||
icon = "page_white_acrobat";
|
||||
else if (mime.startsWith("image/") || plc.endsWith(".ico"))
|
||||
icon = "photo";
|
||||
else if (mime.startsWith("audio/") || mime.equals("application/ogg") ||
|
||||
plc.endsWith(".flac") || plc.endsWith(".m4a") || plc.endsWith(".wma") ||
|
||||
plc.endsWith(".ape"))
|
||||
icon = "music";
|
||||
else if (mime.startsWith("video/") || plc.endsWith(".mkv") || plc.endsWith(".m4v") ||
|
||||
plc.endsWith(".mp4"))
|
||||
icon = "film";
|
||||
else if (mime.equals("application/zip") || mime.equals("application/x-gtar") ||
|
||||
mime.equals("application/compress") || mime.equals("application/gzip") ||
|
||||
mime.equals("application/x-tar") ||
|
||||
plc.endsWith(".rar") || plc.endsWith(".bz2") || plc.endsWith(".7z"))
|
||||
icon = "compress";
|
||||
else if (plc.endsWith(".exe"))
|
||||
icon = "application";
|
||||
else
|
||||
icon = "bug";
|
||||
return icon;
|
||||
}
|
||||
|
||||
/** @since 0.7.14 */
|
||||
private static String toImg(String icon) {
|
||||
return "<img alt=\"\" height=\"16\" width=\"16\" src=\"/i2psnark/_icons/" + icon + ".png\"> ";
|
||||
}
|
||||
|
||||
|
||||
/** inner class, don't bother reindenting */
|
||||
private static class FetchAndAdd implements Runnable {
|
||||
|
@ -1029,6 +1029,30 @@ public class DataHelper {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Like formatSize but with a space after the number
|
||||
* @since 0.7.14
|
||||
*/
|
||||
public static String formatSize2(long bytes) {
|
||||
double val = bytes;
|
||||
int scale = 0;
|
||||
while (val >= 1024) {
|
||||
scale++;
|
||||
val /= 1024;
|
||||
}
|
||||
|
||||
DecimalFormat fmt = new DecimalFormat("##0.00");
|
||||
|
||||
String str = fmt.format(val);
|
||||
switch (scale) {
|
||||
case 1: return str + " K";
|
||||
case 2: return str + " M";
|
||||
case 3: return str + " G";
|
||||
case 4: return str + " T";
|
||||
default: return bytes + " ";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Strip out any HTML (simply removing any less than / greater than symbols)
|
||||
*/
|
||||
|
@ -1,3 +1,7 @@
|
||||
2010-05-26 zzz
|
||||
* i2psnark: Listing fixes and cleanups;
|
||||
icons on front page; tweak bw choker again
|
||||
|
||||
2010-05-24 zzz
|
||||
* i2psnark: Listing icons and cleanups
|
||||
|
||||
@ -6,7 +10,6 @@
|
||||
- fixed major security hole in DatagramDissector
|
||||
* I2PTunnelServer: Implemented WEBIRC support in IRC server tunnel
|
||||
|
||||
|
||||
2010-05-23 zzz
|
||||
* i2psnark:
|
||||
- Choke slower when at bandwidth limit
|
||||
|
@ -18,7 +18,7 @@ public class RouterVersion {
|
||||
/** deprecated */
|
||||
public final static String ID = "Monotone";
|
||||
public final static String VERSION = CoreVersion.VERSION;
|
||||
public final static long BUILD = 11;
|
||||
public final static long BUILD = 12;
|
||||
|
||||
/** for example "-test" */
|
||||
public final static String EXTRA = "";
|
||||
|
Reference in New Issue
Block a user