i2psnark: Add support for specifying data dir in add form (ticket #1028)

This commit is contained in:
zzz
2014-11-08 17:50:27 +00:00
parent 049044b827
commit 555189f123
4 changed files with 88 additions and 21 deletions

View File

@ -1119,21 +1119,23 @@ public class SnarkManager implements CompleteListener {
* Caller must verify this torrent is not already added.
*
* @param filename the absolute path to save the metainfo to, generally ending in ".torrent"
* @param baseFile may be null, if so look in rootDataDir
* @param baseFile may be null, if so look in dataDir
* @throws RuntimeException via Snark.fatal()
*/
private void addTorrent(String filename) {
addTorrent(filename, null, false);
private void addTorrent(String filename, File baseFile, boolean dontAutoStart) {
addTorrent(filename, baseFile, dontAutoStart, null);
}
/**
* Caller must verify this torrent is not already added.
*
* @param filename the absolute path to save the metainfo to, generally ending in ".torrent"
* @param baseFile may be null, if so look in rootDataDir
* @param baseFile may be null, if so look in dataDir
* @param dataDir must exist, or null to default to snark data directory
* @throws RuntimeException via Snark.fatal()
* @since 0.9.17
*/
private void addTorrent(String filename, File baseFile, boolean dontAutoStart) {
private void addTorrent(String filename, File baseFile, boolean dontAutoStart, File dataDir) {
if ((!dontAutoStart) && !_util.connected()) {
addMessage(_("Connecting to I2P"));
boolean ok = _util.connect();
@ -1150,7 +1152,8 @@ public class SnarkManager implements CompleteListener {
addMessage(_("Error: Could not add the torrent {0}", filename) + ": " + ioe);
return;
}
File dataDir = getDataDir();
if (dataDir == null)
dataDir = getDataDir();
Snark torrent = null;
synchronized (_snarks) {
torrent = _snarks.get(filename);
@ -1266,7 +1269,25 @@ public class SnarkManager implements CompleteListener {
*/
public void addMagnet(String name, byte[] ih, String trackerURL, boolean updateStatus) {
// updateStatus is true from UI, false from config file bulk add
addMagnet(name, ih, trackerURL, updateStatus, updateStatus, this);
addMagnet(name, ih, trackerURL, updateStatus, updateStatus, null, this);
}
/**
* Add a torrent with the info hash alone (magnet / maggot)
*
* @param name hex or b32 name from the magnet link
* @param ih 20 byte info hash
* @param trackerURL may be null
* @param updateStatus should we add this magnet to the config file,
* to save it across restarts, in case we don't get
* the metadata before shutdown?
* @param dataDir must exist, or null to default to snark data directory
* @throws RuntimeException via Snark.fatal()
* @since 0.9.17
*/
public void addMagnet(String name, byte[] ih, String trackerURL, boolean updateStatus, File dataDir) {
// updateStatus is true from UI, false from config file bulk add
addMagnet(name, ih, trackerURL, updateStatus, updateStatus, dataDir, this);
}
/**
@ -1279,16 +1300,18 @@ public class SnarkManager implements CompleteListener {
* @param updateStatus should we add this magnet to the config file,
* to save it across restarts, in case we don't get
* the metadata before shutdown?
* @param dataDir must exist, or null to default to snark data directory
* @param listener to intercept callbacks, should pass through to this
* @return the new Snark or null on failure
* @throws RuntimeException via Snark.fatal()
* @since 0.9.4
*/
public Snark addMagnet(String name, byte[] ih, String trackerURL, boolean updateStatus,
boolean autoStart, CompleteListener listener) {
boolean autoStart, File dataDir, CompleteListener listener) {
String dirPath = dataDir != null ? dataDir.getAbsolutePath() : getDataDir().getPath();
Snark torrent = new Snark(_util, name, ih, trackerURL, listener,
_peerCoordinatorSet, _connectionAcceptor,
false, getDataDir().getPath());
false, dirPath);
synchronized (_snarks) {
Snark snark = getTorrentByInfoHash(ih);
@ -1407,10 +1430,11 @@ public class SnarkManager implements CompleteListener {
* @param fromfile where the file is now, presumably in a temp directory somewhere
* @param filename the absolute path to save the metainfo to, generally ending in ".torrent", which is also the name of the torrent
* Must be a filesystem-safe name.
* @param dataDir must exist, or null to default to snark data directory
* @throws RuntimeException via Snark.fatal()
* @since 0.8.4
*/
public void copyAndAddTorrent(File fromfile, String filename) throws IOException {
public void copyAndAddTorrent(File fromfile, String filename, File dataDir) throws IOException {
// prevent interference by DirMonitor
synchronized (_snarks) {
boolean success = FileUtil.copy(fromfile.getAbsolutePath(), filename, false);
@ -1422,7 +1446,7 @@ public class SnarkManager implements CompleteListener {
if (!areFilesPublic())
SecureFileOutputStream.setPerms(new File(filename));
// hold the lock for a long time
addTorrent(filename);
addTorrent(filename, null, false, dataDir);
}
}

View File

@ -110,7 +110,7 @@ class UpdateRunner implements UpdateTask, CompleteListener {
_umgr.notifyAttemptFailed(this, "No tracker, no DHT, no OT", null);
continue;
}
_snark = _smgr.addMagnet(name, ih, trackerURL, true, true, this);
_snark = _smgr.addMagnet(name, ih, trackerURL, true, true, null, this);
if (_snark != null) {
updateStatus("<b>" + _smgr.util().getString("Updating from {0}", linkify(updateURL)) + "</b>");
new Timeout();

View File

@ -50,6 +50,7 @@ public class FetchAndAdd extends Snark implements EepGet.StatusListener, Runnabl
private final String _url;
private final byte[] _fakeHash;
private final String _name;
private final File _dataDir;
private volatile long _remaining = -1;
private volatile long _total = -1;
private volatile long _transferred;
@ -65,8 +66,10 @@ public class FetchAndAdd extends Snark implements EepGet.StatusListener, Runnabl
/**
* Caller should call _mgr.addDownloader(this), which
* will start things off.
*
* @param dataDir null to default to snark data directory
*/
public FetchAndAdd(I2PAppContext ctx, SnarkManager mgr, String url) {
public FetchAndAdd(I2PAppContext ctx, SnarkManager mgr, String url, File dataDir) {
// magnet constructor
super(mgr.util(), "Torrent download",
null, null, null, null, null, false, null);
@ -75,6 +78,7 @@ public class FetchAndAdd extends Snark implements EepGet.StatusListener, Runnabl
_mgr = mgr;
_url = url;
_name = _("Download torrent file from {0}", url);
_dataDir = dataDir;
byte[] fake = null;
try {
fake = SHA1.getInstance().digest(url.getBytes("ISO-8859-1"));
@ -176,7 +180,7 @@ public class FetchAndAdd extends Snark implements EepGet.StatusListener, Runnabl
_mgr.addMessage(_("Torrent already in the queue: {0}", name));
} else {
// This may take a LONG time to create the storage.
_mgr.copyAndAddTorrent(file, canonical);
_mgr.copyAndAddTorrent(file, canonical, _dataDir);
snark = _mgr.getTorrentByBaseName(originalName);
if (snark != null)
snark.startTorrent();

View File

@ -30,6 +30,7 @@ import net.i2p.data.Base64;
import net.i2p.data.DataHelper;
import net.i2p.data.Hash;
import net.i2p.util.Log;
import net.i2p.util.SecureFile;
import org.klomp.snark.I2PSnarkUtil;
import org.klomp.snark.MagnetURI;
@ -933,13 +934,41 @@ public class I2PSnarkServlet extends BasicServlet {
} else
*****/
if (newURL != null) {
String newDir = req.getParameter("nofilter_newDir");
File dir = null;
if (newDir != null) {
newDir = newDir.trim();
if (newDir.length() > 0) {
dir = new SecureFile(newDir);
if (!dir.isAbsolute()) {
_manager.addMessage(_("Data directory must be an absolute path") + ": " + dir);
return;
}
if (!dir.isDirectory() && !dir.mkdirs()) {
_manager.addMessage(_("Data directory cannot be created") + ": " + dir);
return;
}
Collection<Snark> snarks = _manager.getTorrents();
for (Snark s : snarks) {
Storage storage = s.getStorage();
if (storage == null)
continue;
File sbase = storage.getBase();
if (isParentOf(sbase, dir)) {
_manager.addMessage(_("Cannot add torrent {0} inside another torrent: {1}",
dir.getAbsolutePath(), sbase));
return;
}
}
}
}
if (newURL.startsWith("http://")) {
FetchAndAdd fetch = new FetchAndAdd(_context, _manager, newURL);
FetchAndAdd fetch = new FetchAndAdd(_context, _manager, newURL, dir);
_manager.addDownloader(fetch);
} else if (newURL.startsWith(MagnetURI.MAGNET) || newURL.startsWith(MagnetURI.MAGGOT)) {
addMagnet(newURL);
addMagnet(newURL, dir);
} else if (newURL.length() == 40 && newURL.replaceAll("[a-fA-F0-9]", "").length() == 0) {
addMagnet(MagnetURI.MAGNET_FULL + newURL);
addMagnet(MagnetURI.MAGNET_FULL + newURL, dir);
} else {
_manager.addMessage(_("Invalid URL: Must start with \"http://\", \"{0}\", or \"{1}\"",
MagnetURI.MAGNET, MagnetURI.MAGGOT));
@ -2000,6 +2029,7 @@ public class I2PSnarkServlet extends BasicServlet {
out.write(toThemeImg("add"));
out.write(' ');
out.write(_("Add Torrent"));
out.write("</span><hr>\n<table border=\"0\"><tr><td>");
out.write(_("From URL"));
out.write(":<td><input type=\"text\" name=\"nofilter_newURL\" size=\"85\" value=\"" + newURL + "\" spellcheck=\"false\"");
@ -2010,9 +2040,17 @@ public class I2PSnarkServlet extends BasicServlet {
//out.write("From file: <input type=\"file\" name=\"newFile\" size=\"50\" value=\"" + newFile + "\" /><br>");
out.write("<input type=\"submit\" class=\"add\" value=\"");
out.write(_("Add torrent"));
out.write("\" name=\"foo\" ><br>\n");
out.write("\" name=\"foo\" ><br>\n" +
"<tr><td>");
out.write(_("Data dir"));
out.write(":<td><input type=\"text\" name=\"nofilter_newDir\" size=\"85\" value=\"\" spellcheck=\"false\"");
out.write(" title=\"");
out.write(_("Enter the directory to save the data in (default {0})", _manager.getDataDir().getAbsolutePath()));
out.write("\"></td></tr>\n");
out.write("<tr><td>&nbsp;<td><span class=\"snarkAddInfo\">");
out.write(_("You can also copy .torrent files to: {0}.", "<code>" + _manager.getDataDir().getAbsolutePath () + "</code>"));
out.write(_("You can also copy .torrent files to: {0}.", "<code>" + _manager.getDataDir().getAbsolutePath() + "</code>"));
out.write("\n");
out.write(_("Removing a .torrent will cause it to stop."));
out.write("<br></span></table>\n");
@ -2372,15 +2410,16 @@ public class I2PSnarkServlet extends BasicServlet {
/**
* @param url in base32 or hex
* @param dataDir null to default to snark data directory
* @since 0.8.4
*/
private void addMagnet(String url) {
private void addMagnet(String url, File dataDir) {
try {
MagnetURI magnet = new MagnetURI(_manager.util(), url);
String name = magnet.getName();
byte[] ih = magnet.getInfoHash();
String trackerURL = magnet.getTrackerURL();
_manager.addMagnet(name, ih, trackerURL, true);
_manager.addMagnet(name, ih, trackerURL, true, dataDir);
} catch (IllegalArgumentException iae) {
_manager.addMessage(_("Invalid magnet URL {0}", url));
}