forked from I2P_Developers/i2p.i2p
i2psnark: Add support for specifying data dir in add form (ticket #1028)
This commit is contained in:
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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> <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));
|
||||
}
|
||||
|
Reference in New Issue
Block a user