diff --git a/apps/i2psnark/java/src/org/klomp/snark/PeerCheckerTask.java b/apps/i2psnark/java/src/org/klomp/snark/PeerCheckerTask.java
index 7d7e9b054..88dee3101 100644
--- a/apps/i2psnark/java/src/org/klomp/snark/PeerCheckerTask.java
+++ b/apps/i2psnark/java/src/org/klomp/snark/PeerCheckerTask.java
@@ -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
diff --git a/apps/i2psnark/java/src/org/klomp/snark/Snark.java b/apps/i2psnark/java/src/org/klomp/snark/Snark.java
index e25ff1fe3..c2afec346 100644
--- a/apps/i2psnark/java/src/org/klomp/snark/Snark.java
+++ b/apps/i2psnark/java/src/org/klomp/snark/Snark.java
@@ -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));
}
/**
diff --git a/apps/i2psnark/java/src/org/klomp/snark/Storage.java b/apps/i2psnark/java/src/org/klomp/snark/Storage.java
index 4eeb21f6d..fba307f52 100644
--- a/apps/i2psnark/java/src/org/klomp/snark/Storage.java
+++ b/apps/i2psnark/java/src/org/klomp/snark/Storage.java
@@ -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;
diff --git a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java
index 3a58d65b5..af793721d 100644
--- a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java
+++ b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java
@@ -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(")\n" +
"
| \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("");
@@ -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("").append(s).append("");
@@ -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 = "
" +
- _("Directory");
+ status = toImg("tick") + _("Directory");
} else {
if (snark == null) {
// Assume complete, perhaps he removed a completed torrent but kept a bookmark
complete = true;
- status = "
" +
- _("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 = "
" +
- _("File not found in torrent?");
+ status = toImg("cancel") + _("File not found in torrent?");
} else if (remaining == 0 || length <= 0) {
complete = true;
- status = "
" +
- _("Complete");
+ status = toImg("tick") + _("Complete");
} else {
- status = "
" +
- (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("
");
// 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("
");
} else {
- buf.append("height=\"16\" width=\"16\" src=\"/i2psnark/_icons/").append(icon).append(".png\"> ");
+ buf.append(toImg(icon));
}
buf.append("");
} else {
- buf.append("
");
+ buf.append(toImg(icon));
}
buf.append(ls[i]);
if (complete)
buf.append("");
buf.append("");
if (!item.isDirectory())
- buf.append(DataHelper.formatSize(length)).append(' ').append(_("Bytes"));
+ buf.append(DataHelper.formatSize2(length)).append('B');
buf.append(" | ");
//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 " ";
+ }
+
/** inner class, don't bother reindenting */
private static class FetchAndAdd implements Runnable {
diff --git a/core/java/src/net/i2p/data/DataHelper.java b/core/java/src/net/i2p/data/DataHelper.java
index c39e541b2..07997fd10 100644
--- a/core/java/src/net/i2p/data/DataHelper.java
+++ b/core/java/src/net/i2p/data/DataHelper.java
@@ -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)
*/
diff --git a/history.txt b/history.txt
index 28f7324ef..a16a2758c 100644
--- a/history.txt
+++ b/history.txt
@@ -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
diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java
index 5a58b19bc..e36cd3b14 100644
--- a/router/java/src/net/i2p/router/RouterVersion.java
+++ b/router/java/src/net/i2p/router/RouterVersion.java
@@ -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 = "";
|