forked from I2P_Developers/i2p.i2p
i2psnark: Add recheck/start/stop buttons to details page (ticket #372)
remove dup CSS item
This commit is contained in:
@ -1264,7 +1264,8 @@ public class Snark
|
||||
|
||||
public void setWantedPieces(Storage storage)
|
||||
{
|
||||
coordinator.setWantedPieces();
|
||||
if (coordinator != null)
|
||||
coordinator.setWantedPieces();
|
||||
}
|
||||
|
||||
///////////// End StorageListener methods
|
||||
|
@ -8,6 +8,7 @@ import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
@ -2364,28 +2365,36 @@ public class SnarkManager implements CompleteListener {
|
||||
public void startTorrent(byte[] infoHash) {
|
||||
for (Snark snark : _snarks.values()) {
|
||||
if (DataHelper.eq(infoHash, snark.getInfoHash())) {
|
||||
if (snark.isStarting() || !snark.isStopped()) {
|
||||
addMessage("Torrent already started");
|
||||
return;
|
||||
}
|
||||
boolean connected = _util.connected();
|
||||
if ((!connected) && !_util.isConnecting())
|
||||
addMessage(_("Opening the I2P tunnel"));
|
||||
addMessage(_("Starting up torrent {0}", snark.getBaseName()));
|
||||
if (connected) {
|
||||
snark.startTorrent();
|
||||
} else {
|
||||
// mark it for the UI
|
||||
snark.setStarting();
|
||||
(new I2PAppThread(new ThreadedStarter(snark), "TorrentStarter", true)).start();
|
||||
try { Thread.sleep(200); } catch (InterruptedException ie) {}
|
||||
}
|
||||
startTorrent(snark);
|
||||
return;
|
||||
}
|
||||
}
|
||||
addMessage("Torrent not found?");
|
||||
}
|
||||
|
||||
/**
|
||||
* If not connected, thread it, otherwise inline
|
||||
* @since 0.9.23
|
||||
*/
|
||||
public void startTorrent(Snark snark) {
|
||||
if (snark.isStarting() || !snark.isStopped()) {
|
||||
addMessage("Torrent already started");
|
||||
return;
|
||||
}
|
||||
boolean connected = _util.connected();
|
||||
if ((!connected) && !_util.isConnecting())
|
||||
addMessage(_("Opening the I2P tunnel"));
|
||||
addMessage(_("Starting up torrent {0}", snark.getBaseName()));
|
||||
if (connected) {
|
||||
snark.startTorrent();
|
||||
} else {
|
||||
// mark it for the UI
|
||||
snark.setStarting();
|
||||
(new I2PAppThread(new ThreadedStarter(snark), "TorrentStarter", true)).start();
|
||||
try { Thread.sleep(200); } catch (InterruptedException ie) {}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If not connected, thread it, otherwise inline
|
||||
* @since 0.9.1
|
||||
@ -2498,6 +2507,55 @@ public class SnarkManager implements CompleteListener {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Threaded. Torrent must be stopped.
|
||||
* @since 0.9.23
|
||||
*/
|
||||
public void recheckTorrent(Snark snark) {
|
||||
if (snark.isStarting() || !snark.isStopped()) {
|
||||
addMessage("Cannot check " + snark.getBaseName() + ", torrent already started");
|
||||
return;
|
||||
}
|
||||
Storage storage = snark.getStorage();
|
||||
if (storage == null) {
|
||||
addMessage("Cannot check " + snark.getBaseName() + ", no storage");
|
||||
return;
|
||||
}
|
||||
(new I2PAppThread(new ThreadedRechecker(snark), "TorrentRechecker", true)).start();
|
||||
try { Thread.sleep(200); } catch (InterruptedException ie) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 0.9.23
|
||||
*/
|
||||
private class ThreadedRechecker implements Runnable {
|
||||
private final Snark snark;
|
||||
/** must have non-null storage */
|
||||
public ThreadedRechecker(Snark s) { snark = s; }
|
||||
public void run() {
|
||||
try {
|
||||
if (_log.shouldWarn())
|
||||
_log.warn("Starting recheck of " + snark.getBaseName());
|
||||
boolean changed = snark.getStorage().recheck();
|
||||
if (changed)
|
||||
updateStatus(snark);
|
||||
if (_log.shouldWarn())
|
||||
_log.warn("Finished recheck of " + snark.getBaseName() + " changed? " + changed);
|
||||
if (changed) {
|
||||
int pieces = snark.getPieces();
|
||||
double completion = (pieces - snark.getNeeded()) / (double) pieces;
|
||||
String complete = (new DecimalFormat("0.00%")).format(completion);
|
||||
addMessage(_("Finished recheck of torrent {0}, now {1} complete", snark.getBaseName(), complete));
|
||||
} else {
|
||||
addMessage(_("Finished recheck of torrent {0}, unchanged", snark.getBaseName()));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
_log.error("Error rechecking " + snark.getBaseName(), e);
|
||||
addMessage(_("Error checking the torrent {0}", snark.getBaseName()) + ": " + e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ignore case, current locale
|
||||
|
@ -533,6 +533,9 @@ public class Storage implements Closeable
|
||||
/**
|
||||
* Creates (and/or checks) all files from the metainfo file list.
|
||||
* Only call this once, and only after the constructor with the metainfo.
|
||||
* Use recheck() to check again later.
|
||||
*
|
||||
* @throws IllegalStateException if called more than once
|
||||
*/
|
||||
public void check() throws IOException
|
||||
{
|
||||
@ -543,6 +546,9 @@ public class Storage implements Closeable
|
||||
* Creates (and/or checks) all files from the metainfo file list.
|
||||
* Use a saved bitfield and timestamp from a config file.
|
||||
* Only call this once, and only after the constructor with the metainfo.
|
||||
* Use recheck() to check again later.
|
||||
*
|
||||
* @throws IllegalStateException if called more than once
|
||||
*/
|
||||
public void check(long savedTime, BitField savedBitField) throws IOException
|
||||
{
|
||||
@ -821,6 +827,24 @@ public class Storage implements Closeable
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Blocking. Holds lock.
|
||||
* Recommend running only when stopped.
|
||||
* Caller should thread.
|
||||
* Calls listener.setWantedPieces() on completion if anything changed.
|
||||
*
|
||||
* @return true if anything changed, false otherwise
|
||||
* @since 0.9.23
|
||||
*/
|
||||
public boolean recheck() throws IOException {
|
||||
int previousNeeded = needed;
|
||||
checkCreateFiles(true);
|
||||
boolean changed = previousNeeded != needed;
|
||||
if (listener != null && changed)
|
||||
listener.setWantedPieces(this);
|
||||
return changed;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is called at the beginning, and at presumed completion,
|
||||
* so we have to be careful about locking.
|
||||
|
@ -2613,10 +2613,21 @@ public class I2PSnarkServlet extends BasicServlet {
|
||||
String[] val = postParams.get("nonce");
|
||||
if (val != null) {
|
||||
String nonce = val[0];
|
||||
if (String.valueOf(_nonce).equals(nonce))
|
||||
savePriorities(snark, postParams);
|
||||
else
|
||||
if (String.valueOf(_nonce).equals(nonce)) {
|
||||
if (postParams.get("savepri") != null) {
|
||||
savePriorities(snark, postParams);
|
||||
} else if (postParams.get("stop") != null) {
|
||||
_manager.stopTorrent(snark, false);
|
||||
} else if (postParams.get("start") != null) {
|
||||
_manager.startTorrent(snark);
|
||||
} else if (postParams.get("recheck") != null) {
|
||||
_manager.recheckTorrent(snark);
|
||||
} else {
|
||||
_manager.addMessage("Unknown command");
|
||||
}
|
||||
} else {
|
||||
_manager.addMessage("Please retry form submission (bad nonce)");
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -2639,6 +2650,7 @@ public class I2PSnarkServlet extends BasicServlet {
|
||||
r = new File("");
|
||||
}
|
||||
|
||||
boolean showStopStart = snark != null;
|
||||
boolean showPriority = snark != null && snark.getStorage() != null && !snark.getStorage().complete() &&
|
||||
r.isDirectory();
|
||||
|
||||
@ -2668,7 +2680,8 @@ public class I2PSnarkServlet extends BasicServlet {
|
||||
|
||||
if (parent) // always true
|
||||
buf.append("<div class=\"page\"><div class=\"mainsection\">");
|
||||
if (showPriority) {
|
||||
// for stop/start/check
|
||||
if (showStopStart || showPriority) {
|
||||
buf.append("<form action=\"").append(base).append("\" method=\"POST\">\n");
|
||||
buf.append("<input type=\"hidden\" name=\"nonce\" value=\"").append(_nonce).append("\" >\n");
|
||||
if (sortParam != null) {
|
||||
@ -2905,7 +2918,36 @@ public class I2PSnarkServlet extends BasicServlet {
|
||||
.append(":</b> ")
|
||||
.append(formatSize(snark.getPieceLength(0)))
|
||||
.append("</td></tr>\n");
|
||||
|
||||
// buttons
|
||||
if (showStopStart) {
|
||||
buf.append("<tr><td>");
|
||||
toThemeImg(buf, "file");
|
||||
if (snark.isChecking()) {
|
||||
buf.append(" <b>").append(_("Checking")).append("…</b> ")
|
||||
.append("<a href=\"").append(base).append("\">")
|
||||
.append(_("Refresh page for results")).append("</a>");
|
||||
} else if (snark.isStarting()) {
|
||||
buf.append(" <b>").append(_("Starting")).append("…</b>");
|
||||
} else if (snark.isAllocating()) {
|
||||
buf.append(" <b>").append(_("Allocating")).append("…</b>");
|
||||
} else {
|
||||
boolean isRunning = !snark.isStopped();
|
||||
buf.append(" <input type=\"submit\" value=\"");
|
||||
if (isRunning)
|
||||
buf.append(_("Stop")).append("\" name=\"stop\" class=\"stoptorrent\">\n");
|
||||
else
|
||||
buf.append(_("Start")).append("\" name=\"start\" class=\"starttorrent\">\n");
|
||||
buf.append(" <input type=\"submit\" name=\"recheck\" value=\"").append(_("Force Recheck"));
|
||||
if (isRunning)
|
||||
buf.append("\" class=\"disabled\" disabled=\"disabled\">\n");
|
||||
else
|
||||
buf.append("\" class=\"reload\">\n");
|
||||
}
|
||||
buf.append("</td></tr>\n");
|
||||
}
|
||||
} else {
|
||||
// snark == null
|
||||
// shouldn't happen
|
||||
buf.append("<tr><th>Not found<br>resource=\"").append(r.toString())
|
||||
.append("\"<br>base=\"").append(base)
|
||||
@ -3158,7 +3200,8 @@ public class I2PSnarkServlet extends BasicServlet {
|
||||
"</th></tr></thead>\n");
|
||||
}
|
||||
buf.append("</table>\n");
|
||||
if (showPriority)
|
||||
// for stop/start/check
|
||||
if (showStopStart || showPriority)
|
||||
buf.append("</form>");
|
||||
buf.append("</div></div></BODY></HTML>\n");
|
||||
|
||||
|
@ -1,3 +1,6 @@
|
||||
2015-09-19 zzz
|
||||
* i2psnark: Add recheck/start/stop buttons to details page (ticket #372)
|
||||
|
||||
2015-09-18 zzz
|
||||
* EepGet:
|
||||
- Send Accept-Encoding: gzip even when proxied
|
||||
|
@ -656,12 +656,6 @@ input.add {
|
||||
min-height: 22px;
|
||||
}
|
||||
|
||||
input.create {
|
||||
background: #989 url('images/create.png') no-repeat 2px center;
|
||||
padding: 2px 3px 2px 20px !important;
|
||||
min-height: 22px;
|
||||
}
|
||||
|
||||
input.cancel {
|
||||
background: #989 url('../../console/images/cancel.png') no-repeat 2px center;
|
||||
padding: 2px 3px 2px 20px !important;
|
||||
@ -686,6 +680,18 @@ input.reload {
|
||||
min-height: 22px;
|
||||
}
|
||||
|
||||
input.starttorrent {
|
||||
background: #989 url('images/start.png') no-repeat 2px center;
|
||||
padding: 2px 3px 2px 20px !important;
|
||||
min-height: 22px;
|
||||
}
|
||||
|
||||
input.stoptorrent {
|
||||
background: #989 url('images/stop.png') no-repeat 2px center;
|
||||
padding: 2px 3px 2px 20px !important;
|
||||
min-height: 22px;
|
||||
}
|
||||
|
||||
select {
|
||||
background: #333;
|
||||
background: url('/themes/snark/ubergine/images/graytile.png') !important;
|
||||
|
@ -694,6 +694,18 @@ input.reload {
|
||||
min-height: 22px;
|
||||
}
|
||||
|
||||
input.starttorrent {
|
||||
background: #f3efc7 url('images/start.png') no-repeat 2px center;
|
||||
padding: 2px 3px 2px 20px !important;
|
||||
min-height: 22px;
|
||||
}
|
||||
|
||||
input.stoptorrent {
|
||||
background: #f3efc7 url('images/stop.png') no-repeat 2px center;
|
||||
padding: 2px 3px 2px 20px !important;
|
||||
min-height: 22px;
|
||||
}
|
||||
|
||||
select {
|
||||
background: #fff;
|
||||
/* background: url('/themes/snark/ubergine/images/graytile.png') !important;*/
|
||||
|
@ -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 = 6;
|
||||
public final static long BUILD = 7;
|
||||
|
||||
/** for example "-test" */
|
||||
public final static String EXTRA = "";
|
||||
|
Reference in New Issue
Block a user