propagate from branch 'i2p.i2p.str4d.test' (head 190d9be59620f8c6f80e0cb2fc4d9fa839edbb4f)

to branch 'i2p.i2p' (head c884db74f90a9d1c33deca6e2fd2e29f6c1ac8fa)
This commit is contained in:
str4d
2012-08-03 21:30:29 +00:00
332 changed files with 37657 additions and 40410 deletions

View File

@ -67,7 +67,7 @@ public class ConnectionAcceptor implements Runnable
thread = new I2PAppThread(this, "I2PSnark acceptor");
thread.setDaemon(true);
thread.start();
SimpleScheduler.getInstance().addPeriodicEvent(new Cleaner(), BAD_CLEAN_INTERVAL);
_util.getContext().simpleScheduler().addPeriodicEvent(new Cleaner(), BAD_CLEAN_INTERVAL);
}
}
}
@ -82,7 +82,7 @@ public class ConnectionAcceptor implements Runnable
thread = new I2PAppThread(this, "I2PSnark acceptor");
thread.setDaemon(true);
thread.start();
SimpleScheduler.getInstance().addPeriodicEvent(new Cleaner(), BAD_CLEAN_INTERVAL);
_util.getContext().simpleScheduler().addPeriodicEvent(new Cleaner(), BAD_CLEAN_INTERVAL);
}
public void halt()
@ -146,7 +146,7 @@ public class ConnectionAcceptor implements Runnable
}
} else {
if (socket.getPeerDestination().equals(_util.getMyDestination())) {
_util.debug("Incoming connection from myself", Snark.ERROR);
_log.error("Incoming connection from myself");
try { socket.close(); } catch (IOException ioe) {}
continue;
}
@ -163,13 +163,13 @@ public class ConnectionAcceptor implements Runnable
catch (I2PException ioe)
{
if (!socketChanged) {
_util.debug("Error while accepting: " + ioe, Snark.ERROR);
_log.error("Error while accepting", ioe);
stop = true;
}
}
catch (IOException ioe)
{
_util.debug("Error while accepting: " + ioe, Snark.ERROR);
_log.error("Error while accepting", ioe);
stop = true;
}
// catch oom?

View File

@ -309,7 +309,7 @@ public class I2PSnarkUtil {
return rv;
} catch (I2PException ie) {
_shitlist.add(dest);
SimpleScheduler.getInstance().addEvent(new Unshitlist(dest), 10*60*1000);
_context.simpleScheduler().addEvent(new Unshitlist(dest), 10*60*1000);
throw new IOException("Unable to reach the peer " + peer + ": " + ie.getMessage());
}
}
@ -538,40 +538,6 @@ public class I2PSnarkUtil {
return buf.toString();
}
/** hook between snark's logger and an i2p log */
void debug(String msg, int snarkDebugLevel) {
debug(msg, snarkDebugLevel, null);
}
void debug(String msg, int snarkDebugLevel, Throwable t) {
if (t instanceof OutOfMemoryError) {
try { Thread.sleep(100); } catch (InterruptedException ie) {}
try {
t.printStackTrace();
} catch (Throwable tt) {}
try {
System.out.println("OOM thread: " + Thread.currentThread().getName());
} catch (Throwable tt) {}
}
switch (snarkDebugLevel) {
case 0:
case 1:
_log.error(msg, t);
break;
case 2:
_log.warn(msg, t);
break;
case 3:
case 4:
_log.info(msg, t);
break;
case 5:
case 6:
default:
_log.debug(msg, t);
break;
}
}
private static final String BUNDLE_NAME = "org.klomp.snark.web.messages";
/** lang in routerconsole.lang property, else current locale */

View File

@ -133,7 +133,7 @@ class PeerCheckerTask implements Runnable
// Check if it still wants pieces from us.
if (!peer.isInterested())
{
if (_log.shouldLog(Log.INFO))
if (_log.shouldLog(Log.DEBUG))
_log.debug("Choke uninterested peer: " + peer);
peer.setChoking(true);
uploaders--;
@ -144,7 +144,7 @@ class PeerCheckerTask implements Runnable
}
else if (overBWLimitChoke)
{
if (_log.shouldLog(Log.INFO))
if (_log.shouldLog(Log.DEBUG))
_log.debug("BW limit (" + upload + "/" + uploaded + "), choke peer: " + peer);
peer.setChoking(true);
uploaders--;

View File

@ -160,7 +160,7 @@ class PeerCoordinator implements PeerListener
// Install a timer to check the uploaders.
// Randomize the first start time so multiple tasks are spread out,
// this will help the behavior with global limits
timer = new CheckEvent(new PeerCheckerTask(_util, this));
timer = new CheckEvent(_util.getContext(), new PeerCheckerTask(_util, this));
timer.schedule((CHECK_PERIOD / 2) + _random.nextInt((int) CHECK_PERIOD));
}
@ -170,8 +170,8 @@ class PeerCoordinator implements PeerListener
*/
private static class CheckEvent extends SimpleTimer2.TimedEvent {
private final PeerCheckerTask _task;
public CheckEvent(PeerCheckerTask task) {
super(SimpleTimer2.getInstance());
public CheckEvent(I2PAppContext ctx, PeerCheckerTask task) {
super(ctx.simpleTimer2());
_task = task;
}
public void timeReached() {

View File

@ -35,6 +35,7 @@ import net.i2p.I2PAppContext;
import net.i2p.client.streaming.I2PServerSocket;
import net.i2p.data.Destination;
import net.i2p.util.I2PThread;
import net.i2p.util.Log;
/**
* Main Snark program startup class.
@ -47,29 +48,6 @@ public class Snark
private final static int MIN_PORT = 6881;
private final static int MAX_PORT = 6889;
// Error messages (non-fatal)
public final static int ERROR = 1;
// Warning messages
public final static int WARNING = 2;
// Notices (peer level)
public final static int NOTICE = 3;
// Info messages (protocol policy level)
public final static int INFO = 4;
// Debug info (protocol level)
public final static int DEBUG = 5;
// Very low level stuff (network level)
public final static int ALL = 6;
/**
* What level of debug info to show.
*/
//public static int debug = NOTICE;
// Whether or not to ask the user for commands while sharing
//private static boolean command_interpreter = true;
@ -249,12 +227,13 @@ public class Snark
private TrackerClient trackerclient;
private String rootDataDir = ".";
private final CompleteListener completeListener;
private boolean stopped;
private boolean starting;
private volatile boolean stopped;
private volatile boolean starting;
private byte[] id;
private byte[] infoHash;
private String additionalTrackerURL;
private final I2PSnarkUtil _util;
private final Log _log;
private final PeerCoordinatorSet _peerCoordinatorSet;
private String trackerProblems;
private int trackerSeenPeers;
@ -308,6 +287,7 @@ public class Snark
completeListener = complistener;
_util = util;
_log = util.getContext().logManager().getLog(Snark.class);
_peerCoordinatorSet = peerCoordinatorSet;
acceptor = connectionAcceptor;
@ -318,7 +298,8 @@ public class Snark
activity = "Network setup";
id = generateID();
debug("My peer id: " + PeerID.idencode(id), Snark.INFO);
if (_log.shouldLog(Log.INFO))
_log.info("My peer id: " + PeerID.idencode(id));
/*
* Don't start a tunnel if the torrent isn't going to be started.
@ -403,7 +384,8 @@ public class Snark
try { in.close(); } catch (IOException ioe) {}
}
debug(meta.toString(), INFO);
if (_log.shouldLog(Log.INFO))
_log.info(meta.toString());
// When the metainfo torrent was created from an existing file/dir
// it already exists.
@ -464,6 +446,7 @@ public class Snark
{
completeListener = complistener;
_util = util;
_log = util.getContext().logManager().getLog(Snark.class);
_peerCoordinatorSet = peerCoordinatorSet;
acceptor = connectionAcceptor;
this.torrent = torrent;
@ -531,9 +514,11 @@ public class Snark
fatal("Unable to listen for I2P connections");
else {
Destination d = serversocket.getManager().getSession().getMyDestination();
debug("Listening on I2P destination " + d.toBase64() + " / " + d.calculateHash().toBase64(), NOTICE);
if (_log.shouldLog(Log.INFO))
_log.info("Listening on I2P destination " + d.toBase64() + " / " + d.calculateHash().toBase64());
}
debug("Starting PeerCoordinator, ConnectionAcceptor, and TrackerClient", NOTICE);
if (_log.shouldLog(Log.INFO))
_log.info("Starting PeerCoordinator, ConnectionAcceptor, and TrackerClient");
activity = "Collecting pieces";
coordinator = new PeerCoordinator(_util, id, infoHash, meta, storage, this, this);
if (_peerCoordinatorSet != null) {
@ -573,7 +558,8 @@ public class Snark
}
trackerclient.start();
} else {
debug("NOT starting TrackerClient???", NOTICE);
if (_log.shouldLog(Log.INFO))
_log.info("NOT starting TrackerClient???");
}
}
@ -1017,22 +1003,13 @@ public class Snark
private static void usage()
{
System.out.println
("Usage: snark [--debug [level]] [--no-commands] [--port <port>]");
("Usage: snark [--no-commands] [--port <port>]");
System.out.println
(" [--eepproxy hostname portnum]");
System.out.println
(" [--i2cp routerHost routerPort ['name=val name=val name=val']]");
System.out.println
(" (<url>|<file>)");
System.out.println
(" --debug\tShows some extra info and stacktraces");
System.out.println
(" level\tHow much debug details to show");
System.out.println
(" \t(defaults to "
+ NOTICE + ", with --debug to "
+ INFO + ", highest level is "
+ ALL + ").");
System.out.println
(" --no-commands\tDon't read interactive commands or show usage info.");
System.out.println
@ -1071,7 +1048,7 @@ public class Snark
*/
private void fatal(String s, Throwable t)
{
_util.debug(s, ERROR, t);
_log.error(s, t);
//System.err.println("snark: " + s + ((t == null) ? "" : (": " + t)));
//if (debug >= INFO && t != null)
// t.printStackTrace();
@ -1083,14 +1060,6 @@ public class Snark
throw new RuntimeException(s, t);
}
/**
* Show debug info if debug is true.
*/
private void debug(String s, int level)
{
_util.debug(s, level, null);
}
/** CoordinatorListener - this does nothing */
public void peerChange(PeerCoordinator coordinator, Peer peer)
{
@ -1168,9 +1137,10 @@ public class Snark
// + " pieces: ");
checking = true;
}
if (!checking)
debug("Got " + (checked ? "" : "BAD ") + "piece: " + num,
Snark.INFO);
if (!checking) {
if (_log.shouldLog(Log.INFO))
_log.info("Got " + (checked ? "" : "BAD ") + "piece: " + num);
}
}
public void storageAllChecked(Storage storage)
@ -1186,7 +1156,8 @@ public class Snark
public void storageCompleted(Storage storage)
{
debug("Completely received " + torrent, Snark.INFO);
if (_log.shouldLog(Log.INFO))
_log.info("Completely received " + torrent);
//storage.close();
//System.out.println("Completely received: " + torrent);
if (completeListener != null)
@ -1259,7 +1230,8 @@ public class Snark
total += c.getCurrentUploadRate();
}
long limit = 1024l * _util.getMaxUpBW();
debug("Total up bw: " + total + " Limit: " + limit, Snark.NOTICE);
if (_log.shouldLog(Log.INFO))
_log.info("Total up bw: " + total + " Limit: " + limit);
return total > limit;
}

View File

@ -1728,7 +1728,7 @@ public class SnarkManager implements Snark.CompleteListener {
if (count > 0) {
// Schedule this even for final shutdown, as there's a chance
// that it's just this webapp that is stopping.
SimpleScheduler.getInstance().addEvent(new Disconnector(), 60*1000);
_context.simpleScheduler().addEvent(new Disconnector(), 60*1000);
addMessage(_("Closing I2P tunnel after notifying trackers."));
if (finalShutdown) {
try { Thread.sleep(5*1000); } catch (InterruptedException ie) {}

View File

@ -34,6 +34,7 @@ import java.util.StringTokenizer;
import java.util.concurrent.ConcurrentHashMap;
import net.i2p.crypto.SHA1;
import net.i2p.util.Log;
import net.i2p.util.SecureFile;
/**
@ -55,6 +56,7 @@ public class Storage
private final StorageListener listener;
private final I2PSnarkUtil _util;
private final Log _log;
private /* FIXME final FIXME */ BitField bitfield; // BitField to represent the pieces
private int needed; // Number of pieces needed
@ -87,6 +89,7 @@ public class Storage
throws IOException
{
_util = util;
_log = util.getContext().logManager().getLog(Storage.class);
this.metainfo = metainfo;
this.listener = listener;
needed = metainfo.getPieces();
@ -110,6 +113,7 @@ public class Storage
throws IOException
{
_util = util;
_log = util.getContext().logManager().getLog(Storage.class);
this.listener = listener;
// Create names, rafs and lengths arrays.
getFiles(baseFile);
@ -232,8 +236,9 @@ public class Storage
File[] files = f.listFiles();
if (files == null)
{
_util.debug("WARNING: Skipping '" + f
+ "' not a normal file.", Snark.WARNING);
if (_log.shouldLog(Log.WARN))
_log.warn("WARNING: Skipping '" + f
+ "' not a normal file.");
return;
}
for (int i = 0; i < files.length; i++)
@ -457,7 +462,8 @@ public class Storage
if (files == null)
{
// Create base as file.
_util.debug("Creating/Checking file: " + base, Snark.NOTICE);
if (_log.shouldLog(Log.INFO))
_log.info("Creating/Checking file: " + base);
if (!base.createNewFile() && !base.exists())
throw new IOException("Could not create file " + base);
@ -481,7 +487,8 @@ public class Storage
else
{
// Create base as dir.
_util.debug("Creating/Checking directory: " + base, Snark.NOTICE);
if (_log.shouldLog(Log.INFO))
_log.info("Creating/Checking directory: " + base);
if (!base.mkdir() && !base.isDirectory())
throw new IOException("Could not create directory " + base);
@ -540,19 +547,22 @@ public class Storage
bitfield = savedBitField;
needed = metainfo.getPieces() - bitfield.count();
_probablyComplete = complete();
_util.debug("Found saved state and files unchanged, skipping check", Snark.NOTICE);
if (_log.shouldLog(Log.INFO))
_log.info("Found saved state and files unchanged, skipping check");
} else {
// the following sets the needed variable
changed = true;
checkCreateFiles(false);
}
if (complete()) {
_util.debug("Torrent is complete", Snark.NOTICE);
if (_log.shouldLog(Log.INFO))
_log.info("Torrent is complete");
} else {
// fixme saved priorities
if (files != null)
priorities = new int[files.size()];
_util.debug("Still need " + needed + " out of " + metainfo.getPieces() + " pieces", Snark.NOTICE);
if (_log.shouldLog(Log.INFO))
_log.info("Still need " + needed + " out of " + metainfo.getPieces() + " pieces");
}
}
@ -731,7 +741,7 @@ public class Storage
String msg = "File '" + names[i] + "' exists, but has wrong length (expected " +
lengths[i] + " but found " + length + ") - repairing corruption";
SnarkManager.instance().addMessage(msg);
_util.debug(msg, Snark.ERROR);
_log.error(msg);
changed = true;
resume = true;
_probablyComplete = false; // to force RW
@ -844,7 +854,8 @@ public class Storage
*/
private void balloonFile(int nr) throws IOException
{
_util.debug("Ballooning " + nr + ": " + RAFfile[nr], Snark.INFO);
if (_log.shouldLog(Log.INFO))
_log.info("Ballooning " + nr + ": " + RAFfile[nr]);
long remaining = lengths[nr];
final int ZEROBLOCKSIZE = (int) Math.min(remaining, 32*1024);
byte[] zeros = new byte[ZEROBLOCKSIZE];
@ -875,7 +886,7 @@ public class Storage
closeRAF(i);
}
} catch (IOException ioe) {
_util.debug("Error closing " + RAFfile[i], Snark.ERROR, ioe);
_log.error("Error closing " + RAFfile[i], ioe);
// gobble gobble
}
}
@ -896,7 +907,8 @@ public class Storage
try {
bs = new byte[len];
} catch (OutOfMemoryError oom) {
_util.debug("Out of memory, can't honor request for piece " + piece, Snark.WARNING, oom);
if (_log.shouldLog(Log.WARN))
_log.warn("Out of memory, can't honor request for piece " + piece, oom);
return null;
}
getUncheckedPiece(piece, bs, off, len);
@ -1000,8 +1012,9 @@ public class Storage
if (needed > 0) {
if (listener != null)
listener.setWantedPieces(this);
_util.debug("WARNING: Not really done, missing " + needed
+ " pieces", Snark.WARNING);
if (_log.shouldLog(Log.WARN))
_log.warn("WARNING: Not really done, missing " + needed
+ " pieces");
}
}

View File

@ -62,7 +62,7 @@ import net.i2p.util.SimpleTimer2;
* @author Mark Wielaard (mark@klomp.org)
*/
public class TrackerClient implements Runnable {
private final Log _log = I2PAppContext.getGlobalContext().logManager().getLog(TrackerClient.class);
private final Log _log;
private static final String NO_EVENT = "";
private static final String STARTED_EVENT = "started";
private static final String COMPLETED_EVENT = "completed";
@ -116,6 +116,7 @@ public class TrackerClient implements Runnable {
String id = urlencode(snark.getID());
_threadName = "TrackerClient " + id.substring(id.length() - 12);
_util = util;
_log = util.getContext().logManager().getLog(TrackerClient.class);
this.meta = meta;
this.additionalTrackerURL = additionalTrackerURL;
this.coordinator = coordinator;
@ -183,7 +184,7 @@ public class TrackerClient implements Runnable {
private class Runner extends SimpleTimer2.TimedEvent {
public Runner(long delay) {
super(SimpleTimer2.getInstance(), delay);
super(_util.getContext().simpleTimer2(), delay);
}
public void timeReached() {
@ -397,9 +398,10 @@ public class TrackerClient implements Runnable {
catch (IOException ioe)
{
// Probably not fatal (if it doesn't last to long...)
_util.debug
if (_log.shouldLog(Log.WARN))
_log.warn
("WARNING: Could not contact tracker at '"
+ tr.announce + "': " + ioe, Snark.WARNING);
+ tr.announce + "': " + ioe);
tr.trackerProblems = ioe.getMessage();
// don't show secondary tracker problems to the user
if (tr.isPrimary)
@ -421,8 +423,9 @@ public class TrackerClient implements Runnable {
}
}
} else {
_util.debug("Not announcing to " + tr.announce + " last announce was " +
new Date(tr.lastRequestTime) + " interval is " + DataHelper.formatDuration(tr.interval), Snark.INFO);
if (_log.shouldLog(Log.INFO))
_log.info("Not announcing to " + tr.announce + " last announce was " +
new Date(tr.lastRequestTime) + " interval is " + DataHelper.formatDuration(tr.interval));
}
if ((!tr.stop) && maxSeenPeers < tr.seenPeers)
maxSeenPeers = tr.seenPeers;
@ -432,7 +435,8 @@ public class TrackerClient implements Runnable {
if (coordinator.needOutboundPeers() && (meta == null || !meta.isPrivate()) && !stop) {
Set<PeerID> pids = coordinator.getPEXPeers();
if (!pids.isEmpty()) {
_util.debug("Got " + pids.size() + " from PEX", Snark.INFO);
if (_log.shouldLog(Log.INFO))
_log.info("Got " + pids.size() + " from PEX");
List<Peer> peers = new ArrayList(pids.size());
for (PeerID pID : pids) {
peers.add(new Peer(pID, snark.getID(), snark.getInfoHash(), snark.getMetaInfo()));
@ -448,7 +452,8 @@ public class TrackerClient implements Runnable {
}
}
} else {
_util.debug("Not getting PEX peers", Snark.INFO);
if (_log.shouldLog(Log.INFO))
_log.info("Not getting PEX peers");
}
// Get peers from DHT
@ -460,12 +465,14 @@ public class TrackerClient implements Runnable {
else
numwant = _util.getMaxConnections();
List<Hash> hashes = _util.getDHT().getPeers(snark.getInfoHash(), numwant, 2*60*1000);
_util.debug("Got " + hashes + " from DHT", Snark.INFO);
if (_log.shouldLog(Log.INFO))
_log.info("Got " + hashes + " from DHT");
// announce ourselves while the token is still good
// FIXME this needs to be in its own thread
if (!stop) {
int good = _util.getDHT().announce(snark.getInfoHash(), 8, 5*60*1000);
_util.debug("Sent " + good + " good announces to DHT", Snark.INFO);
if (_log.shouldLog(Log.INFO))
_log.info("Sent " + good + " good announces to DHT");
}
// now try these peers
@ -486,7 +493,8 @@ public class TrackerClient implements Runnable {
}
}
} else {
_util.debug("Not getting DHT peers", Snark.INFO);
if (_log.shouldLog(Log.INFO))
_log.info("Not getting DHT peers");
}
@ -497,7 +505,8 @@ public class TrackerClient implements Runnable {
return;
if (!runStarted)
_util.debug(" Retrying in one minute...", Snark.DEBUG);
if (_log.shouldLog(Log.DEBUG))
_log.debug(" Retrying in one minute...");
try {
// Sleep some minutes...
@ -526,7 +535,7 @@ public class TrackerClient implements Runnable {
} // try
catch (Throwable t)
{
_util.debug("TrackerClient: " + t, Snark.ERROR, t);
_log.error("TrackerClient: " + t, t);
if (t instanceof OutOfMemoryError)
throw (OutOfMemoryError)t;
}
@ -619,7 +628,8 @@ public class TrackerClient implements Runnable {
else
buf.append(_util.getMaxConnections());
String s = buf.toString();
_util.debug("Sending TrackerClient request: " + s, Snark.INFO);
if (_log.shouldLog(Log.INFO))
_log.info("Sending TrackerClient request: " + s);
tr.lastRequestTime = System.currentTimeMillis();
// Don't wait for a response to stopped when shutting down
@ -635,7 +645,8 @@ public class TrackerClient implements Runnable {
TrackerInfo info = new TrackerInfo(in, snark.getID(),
snark.getInfoHash(), snark.getMetaInfo());
_util.debug("TrackerClient response: " + info, Snark.INFO);
if (_log.shouldLog(Log.INFO))
_log.info("TrackerClient response: " + info);
String failure = info.getFailureReason();
if (failure != null)

View File

@ -232,7 +232,7 @@ public class I2PSnarkServlet extends DefaultServlet {
//out.write("<meta http-equiv=\"refresh\" content=\"" + delay + ";/i2psnark/" + peerString + "\">\n");
out.write("<script src=\"/js/ajax.js\" type=\"text/javascript\"></script>\n" +
"<script type=\"text/javascript\">\n" +
"var failMessage = \"<div class=\\\"routerdown\\\"><b>" + _("Router is down") + "<\\/b></div>\";\n" +
"var failMessage = \"<div class=\\\"routerdown\\\"><b>" + _("Router is down") + "<\\/b><\\/div>\";\n" +
"function requestAjax1() { ajax(\"/i2psnark/.ajax/xhr1.html" + peerString + "\", \"mainsection\", " + (delay*1000) + "); }\n" +
"function initAjax() { setTimeout(requestAjax1, " + (delay*1000) +"); }\n" +
"</script>\n");
@ -972,24 +972,24 @@ public class I2PSnarkServlet extends DefaultServlet {
String statusString;
if (err != null) {
if (isRunning && curPeers > 0 && !showPeers)
statusString = "<img border=\"0\" src=\"" + _imgPath + "trackererror.png\" title=\"" + err + "\"></td>" +
statusString = "<img alt=\"\" border=\"0\" src=\"" + _imgPath + "trackererror.png\" title=\"" + err + "\"></td>" +
"<td class=\"snarkTorrentStatus " + rowClass + "\">" + _("Tracker Error") +
": <a href=\"" + uri + "?p=" + Base64.encode(snark.getInfoHash()) + "\">" +
curPeers + thinsp(noThinsp) +
ngettext("1 peer", "{0} peers", knownPeers) + "</a>";
else if (isRunning)
statusString = "<img border=\"0\" src=\"" + _imgPath + "trackererror.png\" title=\"" + err + "\"></td>" +
statusString = "<img alt=\"\" border=\"0\" src=\"" + _imgPath + "trackererror.png\" title=\"" + err + "\"></td>" +
"<td class=\"snarkTorrentStatus " + rowClass + "\">" + _("Tracker Error") +
": " + curPeers + thinsp(noThinsp) +
ngettext("1 peer", "{0} peers", knownPeers);
else {
if (err.length() > MAX_DISPLAYED_ERROR_LENGTH)
err = err.substring(0, MAX_DISPLAYED_ERROR_LENGTH) + "&hellip;";
statusString = "<img border=\"0\" src=\"" + _imgPath + "trackererror.png\" title=\"" + err + "\"></td>" +
statusString = "<img alt=\"\" border=\"0\" src=\"" + _imgPath + "trackererror.png\" title=\"" + err + "\"></td>" +
"<td class=\"snarkTorrentStatus " + rowClass + "\">" + _("Tracker Error");
}
} else if (snark.isStarting()) {
statusString = "<img border=\"0\" src=\"" + _imgPath + "stalled.png\" title=\"" + _("Starting") + "\"></td>" +
statusString = "<img alt=\"\" border=\"0\" src=\"" + _imgPath + "stalled.png\" title=\"" + _("Starting") + "\"></td>" +
"<td class=\"snarkTorrentStatus " + rowClass + "\">" + _("Starting");
} else if (remaining == 0 || needed == 0) { // < 0 means no meta size yet
// partial complete or seeding
@ -1005,52 +1005,52 @@ public class I2PSnarkServlet extends DefaultServlet {
txt = _("Complete");
}
if (curPeers > 0 && !showPeers)
statusString = "<img border=\"0\" src=\"" + _imgPath + img + ".png\" title=\"" + txt + "\"></td>" +
statusString = "<img alt=\"\" border=\"0\" src=\"" + _imgPath + img + ".png\" title=\"" + txt + "\"></td>" +
"<td class=\"snarkTorrentStatus " + rowClass + "\">" + txt +
": <a href=\"" + uri + "?p=" + Base64.encode(snark.getInfoHash()) + "\">" +
curPeers + thinsp(noThinsp) +
ngettext("1 peer", "{0} peers", knownPeers) + "</a>";
else
statusString = "<img border=\"0\" src=\"" + _imgPath + img + ".png\" title=\"" + txt + "\"></td>" +
statusString = "<img alt=\"\" border=\"0\" src=\"" + _imgPath + img + ".png\" title=\"" + txt + "\"></td>" +
"<td class=\"snarkTorrentStatus " + rowClass + "\">" + txt +
": " + curPeers + thinsp(noThinsp) +
ngettext("1 peer", "{0} peers", knownPeers);
} else {
statusString = "<img border=\"0\" src=\"" + _imgPath + "complete.png\" title=\"" + _("Complete") + "\"></td>" +
statusString = "<img alt=\"\" border=\"0\" src=\"" + _imgPath + "complete.png\" title=\"" + _("Complete") + "\"></td>" +
"<td class=\"snarkTorrentStatus " + rowClass + "\">" + _("Complete");
}
} else {
if (isRunning && curPeers > 0 && downBps > 0 && !showPeers)
statusString = "<img border=\"0\" src=\"" + _imgPath + "downloading.png\" title=\"" + _("OK") + "\"></td>" +
statusString = "<img alt=\"\" border=\"0\" src=\"" + _imgPath + "downloading.png\" title=\"" + _("OK") + "\"></td>" +
"<td class=\"snarkTorrentStatus " + rowClass + "\">" + _("OK") +
": <a href=\"" + uri + "?p=" + Base64.encode(snark.getInfoHash()) + "\">" +
curPeers + thinsp(noThinsp) +
ngettext("1 peer", "{0} peers", knownPeers) + "</a>";
else if (isRunning && curPeers > 0 && downBps > 0)
statusString = "<img border=\"0\" src=\"" + _imgPath + "downloading.png\" title=\"" + _("OK") + "\"></td>" +
statusString = "<img alt=\"\" border=\"0\" src=\"" + _imgPath + "downloading.png\" title=\"" + _("OK") + "\"></td>" +
"<td class=\"snarkTorrentStatus " + rowClass + "\">" + _("OK") +
": " + curPeers + thinsp(noThinsp) +
ngettext("1 peer", "{0} peers", knownPeers);
else if (isRunning && curPeers > 0 && !showPeers)
statusString = "<img border=\"0\" src=\"" + _imgPath + "stalled.png\" title=\"" + _("Stalled") + "\"></td>" +
statusString = "<img alt=\"\" border=\"0\" src=\"" + _imgPath + "stalled.png\" title=\"" + _("Stalled") + "\"></td>" +
"<td class=\"snarkTorrentStatus " + rowClass + "\">" + _("Stalled") +
": <a href=\"" + uri + "?p=" + Base64.encode(snark.getInfoHash()) + "\">" +
curPeers + thinsp(noThinsp) +
ngettext("1 peer", "{0} peers", knownPeers) + "</a>";
else if (isRunning && curPeers > 0)
statusString = "<img border=\"0\" src=\"" + _imgPath + "stalled.png\" title=\"" + _("Stalled") + "\"></td>" +
statusString = "<img alt=\"\" border=\"0\" src=\"" + _imgPath + "stalled.png\" title=\"" + _("Stalled") + "\"></td>" +
"<td class=\"snarkTorrentStatus " + rowClass + "\">" + _("Stalled") +
": " + curPeers + thinsp(noThinsp) +
ngettext("1 peer", "{0} peers", knownPeers);
else if (isRunning && knownPeers > 0)
statusString = "<img border=\"0\" src=\"" + _imgPath + "nopeers.png\" title=\"" + _("No Peers") + "\"></td>" +
statusString = "<img alt=\"\" border=\"0\" src=\"" + _imgPath + "nopeers.png\" title=\"" + _("No Peers") + "\"></td>" +
"<td class=\"snarkTorrentStatus " + rowClass + "\">" + _("No Peers") +
": 0" + thinsp(noThinsp) + knownPeers ;
else if (isRunning)
statusString = "<img border=\"0\" src=\"" + _imgPath + "nopeers.png\" title=\"" + _("No Peers") + "\"></td>" +
statusString = "<img alt=\"\" border=\"0\" src=\"" + _imgPath + "nopeers.png\" title=\"" + _("No Peers") + "\"></td>" +
"<td class=\"snarkTorrentStatus " + rowClass + "\">" + _("No Peers");
else
statusString = "<img border=\"0\" src=\"" + _imgPath + "stopped.png\" title=\"" + _("Stopped") + "\"></td>" +
statusString = "<img alt=\"\" border=\"0\" src=\"" + _imgPath + "stopped.png\" title=\"" + _("Stopped") + "\"></td>" +
"<td class=\"snarkTorrentStatus " + rowClass + "\">" + _("Stopped");
}
@ -1098,7 +1098,7 @@ public class I2PSnarkServlet extends DefaultServlet {
else
icon = "magnet";
if (isValid) {
out.write(toImg(icon, _("Info")));
out.write(toImg(icon));
out.write("</a>");
} else {
out.write(toImg(icon));