i2psnark: Add recheck/start/stop buttons to details page (ticket #372)

remove dup CSS item
This commit is contained in:
zzz
2015-09-19 17:05:09 +00:00
parent 462c882f4e
commit 287f94ad19
8 changed files with 176 additions and 29 deletions

View File

@@ -1264,6 +1264,7 @@ public class Snark
public void setWantedPieces(Storage storage) public void setWantedPieces(Storage storage)
{ {
if (coordinator != null)
coordinator.setWantedPieces(); coordinator.setWantedPieces();
} }

View File

@@ -8,6 +8,7 @@ import java.io.FilenameFilter;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.Serializable; import java.io.Serializable;
import java.text.DecimalFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
@@ -2364,6 +2365,18 @@ public class SnarkManager implements CompleteListener {
public void startTorrent(byte[] infoHash) { public void startTorrent(byte[] infoHash) {
for (Snark snark : _snarks.values()) { for (Snark snark : _snarks.values()) {
if (DataHelper.eq(infoHash, snark.getInfoHash())) { if (DataHelper.eq(infoHash, snark.getInfoHash())) {
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()) { if (snark.isStarting() || !snark.isStopped()) {
addMessage("Torrent already started"); addMessage("Torrent already started");
return; return;
@@ -2380,10 +2393,6 @@ public class SnarkManager implements CompleteListener {
(new I2PAppThread(new ThreadedStarter(snark), "TorrentStarter", true)).start(); (new I2PAppThread(new ThreadedStarter(snark), "TorrentStarter", true)).start();
try { Thread.sleep(200); } catch (InterruptedException ie) {} try { Thread.sleep(200); } catch (InterruptedException ie) {}
} }
return;
}
}
addMessage("Torrent not found?");
} }
/** /**
@@ -2499,6 +2508,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 * ignore case, current locale
* @since 0.9 * @since 0.9

View File

@@ -533,6 +533,9 @@ public class Storage implements Closeable
/** /**
* Creates (and/or checks) all files from the metainfo file list. * Creates (and/or checks) all files from the metainfo file list.
* Only call this once, and only after the constructor with the metainfo. * 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 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. * Creates (and/or checks) all files from the metainfo file list.
* Use a saved bitfield and timestamp from a config file. * Use a saved bitfield and timestamp from a config file.
* Only call this once, and only after the constructor with the metainfo. * 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 public void check(long savedTime, BitField savedBitField) throws IOException
{ {
@@ -821,6 +827,24 @@ public class Storage implements Closeable
return rv; 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, * This is called at the beginning, and at presumed completion,
* so we have to be careful about locking. * so we have to be careful about locking.

View File

@@ -2613,11 +2613,22 @@ public class I2PSnarkServlet extends BasicServlet {
String[] val = postParams.get("nonce"); String[] val = postParams.get("nonce");
if (val != null) { if (val != null) {
String nonce = val[0]; String nonce = val[0];
if (String.valueOf(_nonce).equals(nonce)) if (String.valueOf(_nonce).equals(nonce)) {
if (postParams.get("savepri") != null) {
savePriorities(snark, postParams); savePriorities(snark, postParams);
else } 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)"); _manager.addMessage("Please retry form submission (bad nonce)");
} }
}
return null; return null;
} }
@@ -2639,6 +2650,7 @@ public class I2PSnarkServlet extends BasicServlet {
r = new File(""); r = new File("");
} }
boolean showStopStart = snark != null;
boolean showPriority = snark != null && snark.getStorage() != null && !snark.getStorage().complete() && boolean showPriority = snark != null && snark.getStorage() != null && !snark.getStorage().complete() &&
r.isDirectory(); r.isDirectory();
@@ -2668,7 +2680,8 @@ public class I2PSnarkServlet extends BasicServlet {
if (parent) // always true if (parent) // always true
buf.append("<div class=\"page\"><div class=\"mainsection\">"); 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("<form action=\"").append(base).append("\" method=\"POST\">\n");
buf.append("<input type=\"hidden\" name=\"nonce\" value=\"").append(_nonce).append("\" >\n"); buf.append("<input type=\"hidden\" name=\"nonce\" value=\"").append(_nonce).append("\" >\n");
if (sortParam != null) { if (sortParam != null) {
@@ -2905,7 +2918,36 @@ public class I2PSnarkServlet extends BasicServlet {
.append(":</b> ") .append(":</b> ")
.append(formatSize(snark.getPieceLength(0))) .append(formatSize(snark.getPieceLength(0)))
.append("</td></tr>\n"); .append("</td></tr>\n");
// buttons
if (showStopStart) {
buf.append("<tr><td>");
toThemeImg(buf, "file");
if (snark.isChecking()) {
buf.append("&nbsp;<b>").append(_("Checking")).append("&hellip;</b>&nbsp;&nbsp;&nbsp;")
.append("<a href=\"").append(base).append("\">")
.append(_("Refresh page for results")).append("</a>");
} else if (snark.isStarting()) {
buf.append("&nbsp;<b>").append(_("Starting")).append("&hellip;</b>");
} else if (snark.isAllocating()) {
buf.append("&nbsp;<b>").append(_("Allocating")).append("&hellip;</b>");
} else { } 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("&nbsp;&nbsp;&nbsp;<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 // shouldn't happen
buf.append("<tr><th>Not found<br>resource=\"").append(r.toString()) buf.append("<tr><th>Not found<br>resource=\"").append(r.toString())
.append("\"<br>base=\"").append(base) .append("\"<br>base=\"").append(base)
@@ -3158,7 +3200,8 @@ public class I2PSnarkServlet extends BasicServlet {
"</th></tr></thead>\n"); "</th></tr></thead>\n");
} }
buf.append("</table>\n"); buf.append("</table>\n");
if (showPriority) // for stop/start/check
if (showStopStart || showPriority)
buf.append("</form>"); buf.append("</form>");
buf.append("</div></div></BODY></HTML>\n"); buf.append("</div></div></BODY></HTML>\n");

View File

@@ -1,3 +1,6 @@
2015-09-19 zzz
* i2psnark: Add recheck/start/stop buttons to details page (ticket #372)
2015-09-18 zzz 2015-09-18 zzz
* EepGet: * EepGet:
- Send Accept-Encoding: gzip even when proxied - Send Accept-Encoding: gzip even when proxied

View File

@@ -656,12 +656,6 @@ input.add {
min-height: 22px; 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 { input.cancel {
background: #989 url('../../console/images/cancel.png') no-repeat 2px center; background: #989 url('../../console/images/cancel.png') no-repeat 2px center;
padding: 2px 3px 2px 20px !important; padding: 2px 3px 2px 20px !important;
@@ -686,6 +680,18 @@ input.reload {
min-height: 22px; 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 { select {
background: #333; background: #333;
background: url('/themes/snark/ubergine/images/graytile.png') !important; background: url('/themes/snark/ubergine/images/graytile.png') !important;

View File

@@ -694,6 +694,18 @@ input.reload {
min-height: 22px; 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 { select {
background: #fff; background: #fff;
/* background: url('/themes/snark/ubergine/images/graytile.png') !important;*/ /* background: url('/themes/snark/ubergine/images/graytile.png') !important;*/

View File

@@ -18,7 +18,7 @@ public class RouterVersion {
/** deprecated */ /** deprecated */
public final static String ID = "Monotone"; public final static String ID = "Monotone";
public final static String VERSION = CoreVersion.VERSION; public final static String VERSION = CoreVersion.VERSION;
public final static long BUILD = 6; public final static long BUILD = 7;
/** for example "-test" */ /** for example "-test" */
public final static String EXTRA = ""; public final static String EXTRA = "";