forked from I2P_Developers/i2p.i2p
propagate from branch 'i2p.i2p' (head e606c473eb1e461a477e45419f6295b6430a7353)
to branch 'i2p.i2p.zzz.test2' (head 6212892778308db10a86e58f9f275c838f604973)
This commit is contained in:
@ -54,8 +54,15 @@ public interface CompleteListener {
|
||||
*/
|
||||
public void gotPiece(Snark snark);
|
||||
|
||||
// not really listeners but the easiest way to get back to an optional SnarkManager
|
||||
/** not really listeners but the easiest way to get back to an optional SnarkManager */
|
||||
public long getSavedTorrentTime(Snark snark);
|
||||
public BitField getSavedTorrentBitField(Snark snark);
|
||||
/**
|
||||
* @since 0.9.15
|
||||
*/
|
||||
public boolean getSavedPreserveNamesSetting(Snark snark);
|
||||
/**
|
||||
* @since 0.9.15
|
||||
*/
|
||||
public long getSavedUploaded(Snark snark);
|
||||
}
|
||||
|
@ -281,6 +281,14 @@ class PeerCoordinator implements PeerListener
|
||||
return uploaded;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the initial total of uploaded bytes of all peers (from a saved status)
|
||||
* @since 0.9.15
|
||||
*/
|
||||
public void setUploaded(long up) {
|
||||
uploaded = up;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the total number of downloaded bytes of all peers.
|
||||
*/
|
||||
|
@ -237,6 +237,7 @@ public class Snark
|
||||
private volatile boolean _autoStoppable;
|
||||
// String indicating main activity
|
||||
private volatile String activity = "Not started";
|
||||
private final long savedUploaded;
|
||||
|
||||
|
||||
/**
|
||||
@ -463,6 +464,7 @@ public class Snark
|
||||
trackerclient = new TrackerClient(meta, coordinator);
|
||||
*/
|
||||
|
||||
savedUploaded = (completeListener != null) ? completeListener.getSavedUploaded(this) : 0;
|
||||
if (start)
|
||||
startTorrent();
|
||||
}
|
||||
@ -488,6 +490,7 @@ public class Snark
|
||||
this.infoHash = ih;
|
||||
this.additionalTrackerURL = trackerURL;
|
||||
this.rootDataDir = rootDir != null ? new File(rootDir) : null; // null only for FetchAndAdd extension
|
||||
savedUploaded = 0;
|
||||
stopped = true;
|
||||
id = generateID();
|
||||
|
||||
@ -556,6 +559,7 @@ public class Snark
|
||||
_log.info("Starting PeerCoordinator, ConnectionAcceptor, and TrackerClient");
|
||||
activity = "Collecting pieces";
|
||||
coordinator = new PeerCoordinator(_util, id, infoHash, meta, storage, this, this);
|
||||
coordinator.setUploaded(savedUploaded);
|
||||
if (_peerCoordinatorSet != null) {
|
||||
// multitorrent
|
||||
_peerCoordinatorSet.add(coordinator);
|
||||
@ -619,7 +623,7 @@ public class Snark
|
||||
pc.halt();
|
||||
Storage st = storage;
|
||||
if (st != null) {
|
||||
boolean changed = storage.isChanged();
|
||||
boolean changed = storage.isChanged() || getUploaded() != savedUploaded;
|
||||
try {
|
||||
storage.close();
|
||||
} catch (IOException ioe) {
|
||||
@ -773,7 +777,7 @@ public class Snark
|
||||
PeerCoordinator coord = coordinator;
|
||||
if (coord != null)
|
||||
return coord.getUploaded();
|
||||
return 0;
|
||||
return savedUploaded;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -92,6 +92,7 @@ public class SnarkManager implements CompleteListener {
|
||||
private static final String PROP_META_BITFIELD = "bitfield";
|
||||
private static final String PROP_META_PRIORITY = "priority";
|
||||
private static final String PROP_META_PRESERVE_NAMES = "preserveFileNames";
|
||||
private static final String PROP_META_UPLOADED = "uploaded";
|
||||
//private static final String PROP_META_BITFIELD_SUFFIX = ".bitfield";
|
||||
//private static final String PROP_META_PRIORITY_SUFFIX = ".priority";
|
||||
private static final String PROP_META_MAGNET_PREFIX = "i2psnark.magnet.";
|
||||
@ -128,6 +129,9 @@ public class SnarkManager implements CompleteListener {
|
||||
/**
|
||||
* "name", "announceURL=websiteURL" pairs
|
||||
* '=' in announceURL must be escaped as ,
|
||||
*
|
||||
* Please use host name, not b32 or full dest, in announce URL. Ensure in default hosts.txt.
|
||||
* Please use host name, not b32 or full dest, in website URL. Ensure in default hosts.txt.
|
||||
*/
|
||||
private static final String DEFAULT_TRACKERS[] = {
|
||||
// "Postman", "http://YRgrgTLGnbTq2aZOZDJQ~o6Uk5k6TK-OZtx0St9pb0G-5EGYURZioxqYG8AQt~LgyyI~NCj6aYWpPO-150RcEvsfgXLR~CxkkZcVpgt6pns8SRc3Bi-QSAkXpJtloapRGcQfzTtwllokbdC-aMGpeDOjYLd8b5V9Im8wdCHYy7LRFxhEtGb~RL55DA8aYOgEXcTpr6RPPywbV~Qf3q5UK55el6Kex-6VCxreUnPEe4hmTAbqZNR7Fm0hpCiHKGoToRcygafpFqDw5frLXToYiqs9d4liyVB-BcOb0ihORbo0nS3CLmAwZGvdAP8BZ7cIYE3Z9IU9D1G8JCMxWarfKX1pix~6pIA-sp1gKlL1HhYhPMxwyxvuSqx34o3BqU7vdTYwWiLpGM~zU1~j9rHL7x60pVuYaXcFQDR4-QVy26b6Pt6BlAZoFmHhPcAuWfu-SFhjyZYsqzmEmHeYdAwa~HojSbofg0TMUgESRXMw6YThK1KXWeeJVeztGTz25sL8AAAA.i2p/announce.php=http://tracker.postman.i2p/"
|
||||
@ -1357,7 +1361,7 @@ public class SnarkManager implements CompleteListener {
|
||||
return false;
|
||||
}
|
||||
// so addTorrent won't recheck
|
||||
saveTorrentStatus(metainfo, bitfield, null, baseFile, true); // no file priorities
|
||||
saveTorrentStatus(metainfo, bitfield, null, baseFile, true, 0); // no file priorities
|
||||
try {
|
||||
locked_writeMetaInfo(metainfo, filename, areFilesPublic());
|
||||
// hold the lock for a long time
|
||||
@ -1522,6 +1526,21 @@ public class SnarkManager implements CompleteListener {
|
||||
Properties config = getConfig(snark);
|
||||
return Boolean.parseBoolean(config.getProperty(PROP_META_PRESERVE_NAMES));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get setting for a torrent from the config file.
|
||||
* @return setting, 0 if not found
|
||||
* @since 0.9.15
|
||||
*/
|
||||
public long getSavedUploaded(Snark snark) {
|
||||
Properties config = getConfig(snark);
|
||||
if (config != null) {
|
||||
try {
|
||||
return Long.parseLong(config.getProperty(PROP_META_UPLOADED));
|
||||
} catch (NumberFormatException nfe) {}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the completion status of a torrent and other data in the config file
|
||||
@ -1535,7 +1554,8 @@ public class SnarkManager implements CompleteListener {
|
||||
if (meta == null || storage == null)
|
||||
return;
|
||||
saveTorrentStatus(meta, storage.getBitField(), storage.getFilePriorities(),
|
||||
storage.getBase(), storage.getPreserveFileNames());
|
||||
storage.getBase(), storage.getPreserveFileNames(),
|
||||
snark.getUploaded());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1550,14 +1570,14 @@ public class SnarkManager implements CompleteListener {
|
||||
* @param base may be null
|
||||
*/
|
||||
private void saveTorrentStatus(MetaInfo metainfo, BitField bitfield, int[] priorities,
|
||||
File base, boolean preserveNames) {
|
||||
File base, boolean preserveNames, long uploaded) {
|
||||
synchronized (_configLock) {
|
||||
locked_saveTorrentStatus(metainfo, bitfield, priorities, base, preserveNames);
|
||||
locked_saveTorrentStatus(metainfo, bitfield, priorities, base, preserveNames, uploaded);
|
||||
}
|
||||
}
|
||||
|
||||
private void locked_saveTorrentStatus(MetaInfo metainfo, BitField bitfield, int[] priorities,
|
||||
File base, boolean preserveNames) {
|
||||
File base, boolean preserveNames, long uploaded) {
|
||||
byte[] ih = metainfo.getInfoHash();
|
||||
String bfs;
|
||||
if (bitfield.complete()) {
|
||||
@ -1570,6 +1590,7 @@ public class SnarkManager implements CompleteListener {
|
||||
config.setProperty(PROP_META_STAMP, Long.toString(System.currentTimeMillis()));
|
||||
config.setProperty(PROP_META_BITFIELD, bfs);
|
||||
config.setProperty(PROP_META_PRESERVE_NAMES, Boolean.toString(preserveNames));
|
||||
config.setProperty(PROP_META_UPLOADED, Long.toString(uploaded));
|
||||
if (base != null)
|
||||
config.setProperty(PROP_META_BASE, base.getAbsolutePath());
|
||||
|
||||
@ -1826,7 +1847,7 @@ public class SnarkManager implements CompleteListener {
|
||||
Storage storage = snark.getStorage();
|
||||
if (meta != null && storage != null)
|
||||
saveTorrentStatus(meta, storage.getBitField(), storage.getFilePriorities(),
|
||||
storage.getBase(), storage.getPreserveFileNames());
|
||||
storage.getBase(), storage.getPreserveFileNames(), snark.getUploaded());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1849,7 +1870,7 @@ public class SnarkManager implements CompleteListener {
|
||||
return null;
|
||||
}
|
||||
saveTorrentStatus(meta, storage.getBitField(), null,
|
||||
storage.getBase(), storage.getPreserveFileNames()); // no file priorities
|
||||
storage.getBase(), storage.getPreserveFileNames(), 0);
|
||||
// temp for addMessage() in case canonical throws
|
||||
String name = storage.getBaseName();
|
||||
try {
|
||||
|
@ -316,15 +316,34 @@ public class Storage
|
||||
}
|
||||
|
||||
/**
|
||||
* Get index to pass to remaining(), getPriority(), setPriority()
|
||||
*
|
||||
* @param file non-canonical path (non-directory)
|
||||
* @return internal index of file; -1 if unknown file
|
||||
* @since 0.9.15
|
||||
*/
|
||||
public int indexOf(File file) {
|
||||
for (int i = 0; i < _torrentFiles.size(); i++) {
|
||||
File f = _torrentFiles.get(i).RAFfile;
|
||||
if (f.equals(file))
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param fileIndex as obtained from indexOf
|
||||
* @return number of bytes remaining; -1 if unknown file
|
||||
* @since 0.7.14
|
||||
*/
|
||||
public long remaining(File file) {
|
||||
public long remaining(int fileIndex) {
|
||||
if (fileIndex < 0 || fileIndex >= _torrentFiles.size())
|
||||
return -1;
|
||||
long bytes = 0;
|
||||
for (TorrentFile tf : _torrentFiles) {
|
||||
File f = tf.RAFfile;
|
||||
if (f.equals(file)) {
|
||||
for (int i = 0; i < _torrentFiles.size(); i++) {
|
||||
TorrentFile tf = _torrentFiles.get(i);
|
||||
if (i == fileIndex) {
|
||||
File f = tf.RAFfile;
|
||||
if (complete())
|
||||
return 0;
|
||||
int psz = piece_size;
|
||||
@ -350,37 +369,30 @@ public class Storage
|
||||
}
|
||||
|
||||
/**
|
||||
* @param file non-canonical path (non-directory)
|
||||
* @param fileIndex as obtained from indexOf
|
||||
* @since 0.8.1
|
||||
*/
|
||||
public int getPriority(File file) {
|
||||
public int getPriority(int fileIndex) {
|
||||
if (complete() || metainfo.getFiles() == null)
|
||||
return 0;
|
||||
for (TorrentFile tf : _torrentFiles) {
|
||||
File f = tf.RAFfile;
|
||||
if (f.equals(file))
|
||||
return tf.priority;
|
||||
}
|
||||
return 0;
|
||||
if (fileIndex < 0 || fileIndex >= _torrentFiles.size())
|
||||
return 0;
|
||||
return _torrentFiles.get(fileIndex).priority;
|
||||
}
|
||||
|
||||
/**
|
||||
* Must call Snark.updatePiecePriorities()
|
||||
* (which calls getPiecePriorities()) after calling this.
|
||||
* @param file non-canonical path (non-directory)
|
||||
* @param fileIndex as obtained from indexOf
|
||||
* @param pri default 0; <0 to disable
|
||||
* @since 0.8.1
|
||||
*/
|
||||
public void setPriority(File file, int pri) {
|
||||
public void setPriority(int fileIndex, int pri) {
|
||||
if (complete() || metainfo.getFiles() == null)
|
||||
return;
|
||||
for (TorrentFile tf : _torrentFiles) {
|
||||
File f = tf.RAFfile;
|
||||
if (f.equals(file)) {
|
||||
tf.priority = pri;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (fileIndex < 0 || fileIndex >= _torrentFiles.size())
|
||||
return;
|
||||
_torrentFiles.get(fileIndex).priority = pri;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -72,6 +72,8 @@ public class TrackerClient implements Runnable {
|
||||
private static final String STOPPED_EVENT = "stopped";
|
||||
private static final String NOT_REGISTERED = "torrent not registered"; //bytemonsoon
|
||||
private static final String NOT_REGISTERED_2 = "torrent not found"; // diftracker
|
||||
private static final String NOT_REGISTERED_3 = "torrent unauthorised"; // vuze
|
||||
private static final String ERROR_GOT_HTML = "received html"; // fake return
|
||||
/** this is our equivalent to router.utorrent.com for bootstrap */
|
||||
private static final String DEFAULT_BACKUP_TRACKER = "http://tracker.welterde.i2p/a";
|
||||
|
||||
@ -577,14 +579,20 @@ public class TrackerClient implements Runnable {
|
||||
if (tr.isPrimary)
|
||||
snark.setTrackerProblems(tr.trackerProblems);
|
||||
String tplc = tr.trackerProblems.toLowerCase(Locale.US);
|
||||
if (tplc.startsWith(NOT_REGISTERED) || tplc.startsWith(NOT_REGISTERED_2)) {
|
||||
if (tplc.startsWith(NOT_REGISTERED) || tplc.startsWith(NOT_REGISTERED_2) ||
|
||||
tplc.startsWith(NOT_REGISTERED_3) || tplc.startsWith(ERROR_GOT_HTML)) {
|
||||
// Give a guy some time to register it if using opentrackers too
|
||||
//if (trckrs.size() == 1) {
|
||||
// stop = true;
|
||||
// snark.stopTorrent();
|
||||
//} else { // hopefully each on the opentrackers list is really open
|
||||
if (tr.registerFails++ > MAX_REGISTER_FAILS ||
|
||||
!completed || // no use retrying if we aren't seeding
|
||||
tplc.startsWith(ERROR_GOT_HTML) || // fake msg from doRequest()
|
||||
(!tr.isPrimary && tr.registerFails > MAX_REGISTER_FAILS / 2))
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Not longer announcing to " + tr.announce + " : " +
|
||||
tr.trackerProblems + " after " + tr.registerFails + " failures");
|
||||
tr.stop = true;
|
||||
//
|
||||
}
|
||||
@ -797,10 +805,15 @@ public class TrackerClient implements Runnable {
|
||||
tr.lastRequestTime = System.currentTimeMillis();
|
||||
// Don't wait for a response to stopped when shutting down
|
||||
boolean fast = _fastUnannounce && event.equals(STOPPED_EVENT);
|
||||
byte[] fetched = _util.get(s, true, fast ? -1 : 0, small ? 128 : 1024, small ? 1024 : 8*1024);
|
||||
if (fetched == null) {
|
||||
throw new IOException("Error fetching " + s);
|
||||
}
|
||||
byte[] fetched = _util.get(s, true, fast ? -1 : 0, small ? 128 : 1024, small ? 1024 : 32*1024);
|
||||
if (fetched == null)
|
||||
throw new IOException("Error fetching");
|
||||
if (fetched.length == 0)
|
||||
throw new IOException("No data");
|
||||
// The HTML check only works if we didn't exceed the maxium fetch size specified in get(),
|
||||
// otherwise we already threw an IOE.
|
||||
if (fetched[0] == '<')
|
||||
throw new IOException(ERROR_GOT_HTML);
|
||||
|
||||
InputStream in = new ByteArrayInputStream(fetched);
|
||||
|
||||
|
@ -295,6 +295,10 @@ class UpdateRunner implements UpdateTask, CompleteListener {
|
||||
return _smgr.getSavedPreserveNamesSetting(snark);
|
||||
}
|
||||
|
||||
public long getSavedUploaded(Snark snark) {
|
||||
return _smgr.getSavedUploaded(snark);
|
||||
}
|
||||
|
||||
//////// end CompleteListener methods
|
||||
|
||||
private static String linkify(String url) {
|
||||
|
@ -25,8 +25,10 @@ import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import net.i2p.data.Base32;
|
||||
import net.i2p.data.Base64;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.data.Hash;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
import org.klomp.snark.I2PSnarkUtil;
|
||||
@ -498,7 +500,7 @@ public class I2PSnarkServlet extends BasicServlet {
|
||||
out.write(_("RX"));
|
||||
out.write("\">");
|
||||
out.write("</th>\n<th align=\"right\">");
|
||||
if (_manager.util().connected() && !snarks.isEmpty()) {
|
||||
if (!snarks.isEmpty()) {
|
||||
out.write("<img border=\"0\" src=\"" + _imgPath + "head_tx.png\" title=\"");
|
||||
out.write(_("Uploaded"));
|
||||
out.write("\" alt=\"");
|
||||
@ -1430,8 +1432,7 @@ public class I2PSnarkServlet extends BasicServlet {
|
||||
out.write("</td><td class=\"snarkTorrentName\"");
|
||||
if (isMultiFile) {
|
||||
// link on the whole td
|
||||
String jsec = encodedBaseName.replace("'", "\\'");
|
||||
out.write(" onclick=\"document.location='" + jsec + "/';\">");
|
||||
out.write(" onclick=\"document.location='" + encodedBaseName + "/';\">");
|
||||
} else {
|
||||
out.write('>');
|
||||
}
|
||||
@ -1465,15 +1466,15 @@ public class I2PSnarkServlet extends BasicServlet {
|
||||
// out.write("??"); // no meta size yet
|
||||
out.write("</td>\n\t");
|
||||
out.write("<td align=\"right\" class=\"snarkTorrentUploaded\">");
|
||||
if(isRunning && isValid)
|
||||
if (isValid && uploaded > 0)
|
||||
out.write(formatSize(uploaded));
|
||||
out.write("</td>\n\t");
|
||||
out.write("<td align=\"right\" class=\"snarkTorrentRateDown\">");
|
||||
if(isRunning && needed > 0)
|
||||
if (isRunning && needed > 0)
|
||||
out.write(formatSize(downBps) + "ps");
|
||||
out.write("</td>\n\t");
|
||||
out.write("<td align=\"right\" class=\"snarkTorrentRateUp\">");
|
||||
if(isRunning && isValid)
|
||||
if (isRunning && isValid)
|
||||
out.write(formatSize(upBps) + "ps");
|
||||
out.write("</td>\n\t");
|
||||
out.write("<td align=\"center\" class=\"snarkTorrentAction\">");
|
||||
@ -1717,8 +1718,10 @@ public class I2PSnarkServlet extends BasicServlet {
|
||||
}
|
||||
|
||||
/**
|
||||
* Start of anchor only, caller must add anchor text or img and close anchor
|
||||
* @return string or null
|
||||
* Generate link to details page if we know it supports it.
|
||||
* Start of anchor only, caller must add anchor text or img and close anchor.
|
||||
*
|
||||
* @return string or null if unknown tracker
|
||||
* @since 0.8.4
|
||||
*/
|
||||
private String getTrackerLinkUrl(String announce, byte[] infohash) {
|
||||
@ -1745,8 +1748,8 @@ public class I2PSnarkServlet extends BasicServlet {
|
||||
}
|
||||
|
||||
/**
|
||||
* Full anchor with img
|
||||
* @return string or null
|
||||
* Full link to details page with img
|
||||
* @return string or null if details page unsupported
|
||||
* @since 0.8.4
|
||||
*/
|
||||
private String getTrackerLink(String announce, byte[] infohash) {
|
||||
@ -1762,7 +1765,7 @@ public class I2PSnarkServlet extends BasicServlet {
|
||||
}
|
||||
|
||||
/**
|
||||
* Full anchor with shortened URL as anchor text
|
||||
* Full anchor to home page or details page with shortened host name as anchor text
|
||||
* @return string, non-null
|
||||
* @since 0.9.5
|
||||
*/
|
||||
@ -1771,14 +1774,37 @@ public class I2PSnarkServlet extends BasicServlet {
|
||||
String trackerLinkUrl = getTrackerLinkUrl(announce, infohash);
|
||||
if (announce.startsWith("http://"))
|
||||
announce = announce.substring(7);
|
||||
// strip path
|
||||
int slsh = announce.indexOf('/');
|
||||
if (slsh > 0)
|
||||
announce = announce.substring(0, slsh);
|
||||
if (trackerLinkUrl != null)
|
||||
if (trackerLinkUrl != null) {
|
||||
buf.append(trackerLinkUrl);
|
||||
else
|
||||
// TODO encode
|
||||
buf.append("<a href=\"http://").append(urlEncode(announce)).append("/\">");
|
||||
} else {
|
||||
// browsers don't like a full b64 dest, so convert it to b32
|
||||
String host = announce;
|
||||
if (host.length() >= 516) {
|
||||
int colon = announce.indexOf(':');
|
||||
String port = "";
|
||||
if (colon > 0) {
|
||||
port = host.substring(colon);
|
||||
host = host.substring(0, colon);
|
||||
}
|
||||
if (host.endsWith(".i2p"))
|
||||
host = host.substring(0, host.length() - 4);
|
||||
byte[] b = Base64.decode(host);
|
||||
if (b != null) {
|
||||
Hash h = _context.sha().calculateHash(b);
|
||||
// should we add the port back or strip it?
|
||||
host = Base32.encode(h.getData()) + ".b32.i2p" + port;
|
||||
}
|
||||
}
|
||||
buf.append("<a href=\"http://").append(urlEncode(host)).append("/\">");
|
||||
}
|
||||
// strip port
|
||||
int colon = announce.indexOf(':');
|
||||
if (colon > 0)
|
||||
announce = announce.substring(0, colon);
|
||||
if (announce.length() > 67)
|
||||
announce = DataHelper.escapeHTML(announce.substring(0, 40)) + "…" +
|
||||
DataHelper.escapeHTML(announce.substring(announce.length() - 8));
|
||||
@ -2673,6 +2699,7 @@ public class I2PSnarkServlet extends BasicServlet {
|
||||
boolean complete = false;
|
||||
String status = "";
|
||||
long length = item.length();
|
||||
int fileIndex = -1;
|
||||
int priority = 0;
|
||||
if (item.isDirectory()) {
|
||||
complete = true;
|
||||
@ -2684,8 +2711,9 @@ public class I2PSnarkServlet extends BasicServlet {
|
||||
status = toImg("cancel") + ' ' + _("Torrent not found?");
|
||||
} else {
|
||||
Storage storage = snark.getStorage();
|
||||
fileIndex = storage.indexOf(item);
|
||||
|
||||
long remaining = storage.remaining(item);
|
||||
long remaining = storage.remaining(fileIndex);
|
||||
if (remaining < 0) {
|
||||
complete = true;
|
||||
status = toImg("cancel") + ' ' + _("File not found in torrent?");
|
||||
@ -2693,7 +2721,7 @@ public class I2PSnarkServlet extends BasicServlet {
|
||||
complete = true;
|
||||
status = toImg("tick") + ' ' + _("Complete");
|
||||
} else {
|
||||
priority = storage.getPriority(item);
|
||||
priority = storage.getPriority(fileIndex);
|
||||
if (priority < 0)
|
||||
status = toImg("cancel");
|
||||
else if (priority == 0)
|
||||
@ -2745,17 +2773,17 @@ public class I2PSnarkServlet extends BasicServlet {
|
||||
if (showPriority) {
|
||||
buf.append("<td class=\"priority\">");
|
||||
if ((!complete) && (!item.isDirectory())) {
|
||||
buf.append("\n<input type=\"radio\" onclick=\"priorityclicked();\" class=\"prihigh\" value=\"5\" name=\"pri.").append(item).append("\" ");
|
||||
buf.append("\n<input type=\"radio\" onclick=\"priorityclicked();\" class=\"prihigh\" value=\"5\" name=\"pri.").append(fileIndex).append("\" ");
|
||||
if (priority > 0)
|
||||
buf.append("checked=\"checked\"");
|
||||
buf.append('>').append(_("High"));
|
||||
|
||||
buf.append("\n<input type=\"radio\" onclick=\"priorityclicked();\" class=\"prinorm\" value=\"0\" name=\"pri.").append(item).append("\" ");
|
||||
buf.append("\n<input type=\"radio\" onclick=\"priorityclicked();\" class=\"prinorm\" value=\"0\" name=\"pri.").append(fileIndex).append("\" ");
|
||||
if (priority == 0)
|
||||
buf.append("checked=\"checked\"");
|
||||
buf.append('>').append(_("Normal"));
|
||||
|
||||
buf.append("\n<input type=\"radio\" onclick=\"priorityclicked();\" class=\"priskip\" value=\"-9\" name=\"pri.").append(item).append("\" ");
|
||||
buf.append("\n<input type=\"radio\" onclick=\"priorityclicked();\" class=\"priskip\" value=\"-9\" name=\"pri.").append(fileIndex).append("\" ");
|
||||
if (priority < 0)
|
||||
buf.append("checked=\"checked\"");
|
||||
buf.append('>').append(_("Skip"));
|
||||
@ -2857,10 +2885,10 @@ public class I2PSnarkServlet extends BasicServlet {
|
||||
String key = entry.getKey();
|
||||
if (key.startsWith("pri.")) {
|
||||
try {
|
||||
File file = new File(key.substring(4));
|
||||
int fileIndex = Integer.parseInt(key.substring(4));
|
||||
String val = entry.getValue()[0]; // jetty arrays
|
||||
int pri = Integer.parseInt(val);
|
||||
storage.setPriority(file, pri);
|
||||
storage.setPriority(fileIndex, pri);
|
||||
//System.err.println("Priority now " + pri + " for " + file);
|
||||
} catch (Throwable t) { t.printStackTrace(); }
|
||||
}
|
||||
|
@ -84,6 +84,7 @@ class URIUtil
|
||||
case '<':
|
||||
case '>':
|
||||
case ' ':
|
||||
case ':':
|
||||
buf=new StringBuilder(path.length()*2);
|
||||
break loop;
|
||||
default:
|
||||
@ -139,6 +140,9 @@ class URIUtil
|
||||
case 0x7f:
|
||||
buf.append("%7F");
|
||||
continue;
|
||||
case ':':
|
||||
buf.append("%3A");
|
||||
continue;
|
||||
default:
|
||||
if (c <= 0x1f) // includes negative
|
||||
toHex(c,buf);
|
||||
@ -183,6 +187,9 @@ class URIUtil
|
||||
case ' ':
|
||||
buf.append("%20");
|
||||
continue;
|
||||
case ':':
|
||||
buf.append("%3A");
|
||||
continue;
|
||||
default:
|
||||
if (c <= 0x1f || (c >= 0x7f && c <= 0x9f) || Character.isSpaceChar(c))
|
||||
toHex(c,buf);
|
||||
|
Reference in New Issue
Block a user