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,6 +1264,7 @@ public class Snark
|
|||||||
|
|
||||||
public void setWantedPieces(Storage storage)
|
public void setWantedPieces(Storage storage)
|
||||||
{
|
{
|
||||||
|
if (coordinator != null)
|
||||||
coordinator.setWantedPieces();
|
coordinator.setWantedPieces();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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
|
||||||
|
@@ -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.
|
||||||
|
@@ -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(" <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 {
|
} 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
|
// 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");
|
||||||
|
|
||||||
|
@@ -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
|
||||||
|
@@ -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;
|
||||||
|
@@ -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;*/
|
||||||
|
@@ -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 = "";
|
||||||
|
Reference in New Issue
Block a user