forked from I2P_Developers/i2p.i2p
* i2psnark:
- Display torrent file downloads in torrent area - Sort magnets and downloads first - Fix sorting problem when torrent dir is a symlink - Reduce max file idle time - arrow_down icon copied from console css
This commit is contained in:
@ -250,6 +250,15 @@ public class I2PSnarkUtil {
|
||||
|
||||
public boolean connected() { return _manager != null; }
|
||||
|
||||
/**
|
||||
* For FetchAndAdd
|
||||
* @return null if not connected
|
||||
* @since 0.9.1
|
||||
*/
|
||||
public I2PSocketManager getSocketManager() {
|
||||
return _manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy the destination itself
|
||||
*/
|
||||
@ -310,7 +319,7 @@ public class I2PSnarkUtil {
|
||||
// we could use the system tmp dir but deleteOnExit() doesn't seem to work on all platforms...
|
||||
out = SecureFile.createTempFile("i2psnark", null, _tmpDir);
|
||||
} catch (IOException ioe) {
|
||||
ioe.printStackTrace();
|
||||
_log.error("temp file error", ioe);
|
||||
if (out != null)
|
||||
out.delete();
|
||||
return null;
|
||||
|
@ -346,6 +346,8 @@ public class Snark
|
||||
in = new FileInputStream(f);
|
||||
else
|
||||
{
|
||||
/**** No, we don't ever fetch a torrent file this way
|
||||
and we don't want to block in the constructor
|
||||
activity = "Getting torrent";
|
||||
File torrentFile = _util.get(torrent, 3);
|
||||
if (torrentFile == null) {
|
||||
@ -355,6 +357,8 @@ public class Snark
|
||||
torrentFile.deleteOnExit();
|
||||
in = new FileInputStream(torrentFile);
|
||||
}
|
||||
*****/
|
||||
throw new IOException("not found");
|
||||
}
|
||||
meta = new MetaInfo(in);
|
||||
infoHash = meta.getInfoHash();
|
||||
|
@ -598,7 +598,7 @@ public class SnarkManager implements Snark.CompleteListener {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ot null ok, default is none
|
||||
* @param pt null ok, default is none
|
||||
* @since 0.9.1
|
||||
*/
|
||||
public void savePrivateTrackers(List<String> pt) {
|
||||
@ -881,6 +881,29 @@ public class SnarkManager implements Snark.CompleteListener {
|
||||
_magnets.remove(snark.getName());
|
||||
removeMagnetStatus(snark.getInfoHash());
|
||||
}
|
||||
|
||||
/**
|
||||
* Add and start a FetchAndAdd task.
|
||||
* Remove it with deleteMagnet().
|
||||
*
|
||||
* @param torrent must be instanceof FetchAndAdd
|
||||
* @throws RuntimeException via Snark.fatal()?
|
||||
* @since 0.9.1
|
||||
*/
|
||||
public void addDownloader(Snark torrent) {
|
||||
synchronized (_snarks) {
|
||||
Snark snark = getTorrentByInfoHash(torrent.getInfoHash());
|
||||
if (snark != null) {
|
||||
addMessage(_("Download already running: {0}", snark.getBaseName()));
|
||||
return;
|
||||
}
|
||||
String name = torrent.getName();
|
||||
// Tell the dir monitor not to delete us
|
||||
_magnets.add(name);
|
||||
_snarks.put(name, torrent);
|
||||
}
|
||||
torrent.startTorrent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a torrent from a MetaInfo. Save the MetaInfo data to filename.
|
||||
@ -1399,7 +1422,7 @@ public class SnarkManager implements Snark.CompleteListener {
|
||||
byte[] ih = Base64.decode(b64);
|
||||
// ignore value - TODO put tracker URL in value
|
||||
if (ih != null && ih.length == 20)
|
||||
addMagnet("Magnet: " + I2PSnarkUtil.toHex(ih), ih, null, false);
|
||||
addMagnet("* " + _("Magnet") + ' ' + I2PSnarkUtil.toHex(ih), ih, null, false);
|
||||
// else remove from config?
|
||||
}
|
||||
}
|
||||
|
@ -1071,7 +1071,7 @@ public class Storage
|
||||
/**
|
||||
* Close unused RAFs - call periodically
|
||||
*/
|
||||
private static final long RAFCloseDelay = 7*60*1000;
|
||||
private static final long RAFCloseDelay = 4*60*1000;
|
||||
public void cleanRAFs() {
|
||||
long cutoff = System.currentTimeMillis() - RAFCloseDelay;
|
||||
for (int i = 0; i < RAFlock.length; i++) {
|
||||
|
346
apps/i2psnark/java/src/org/klomp/snark/web/FetchAndAdd.java
Normal file
346
apps/i2psnark/java/src/org/klomp/snark/web/FetchAndAdd.java
Normal file
@ -0,0 +1,346 @@
|
||||
package org.klomp.snark.web;
|
||||
|
||||
/*
|
||||
* Released into the public domain
|
||||
* with no warranty of any kind, either expressed or implied.
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.client.streaming.I2PSocketEepGet;
|
||||
import net.i2p.client.streaming.I2PSocketManager;
|
||||
import net.i2p.crypto.SHA1;
|
||||
import net.i2p.util.EepGet;
|
||||
import net.i2p.util.I2PAppThread;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.SecureFile;
|
||||
|
||||
import org.klomp.snark.MetaInfo;
|
||||
import org.klomp.snark.Snark;
|
||||
import org.klomp.snark.SnarkManager;
|
||||
import org.klomp.snark.Storage;
|
||||
|
||||
/**
|
||||
* A cancellable torrent file downloader.
|
||||
* We extend Snark so its status may be easily listed in the
|
||||
* web table without adding a lot of code there.
|
||||
*
|
||||
* Upon successful download, this Snark will be deleted and
|
||||
* a "real" Snark created.
|
||||
*
|
||||
* The methods return values similar to a Snark in magnet mode.
|
||||
* A fake info hash, which is the SHA1 of the URL, is returned
|
||||
* to prevent duplicates.
|
||||
*
|
||||
* This Snark may be stopped and restarted, although a partially
|
||||
* downloaded file is discarded.
|
||||
*
|
||||
* @since 0.9.1 Moved from I2PSnarkUtil
|
||||
*/
|
||||
public class FetchAndAdd extends Snark implements EepGet.StatusListener, Runnable {
|
||||
|
||||
private final I2PAppContext _ctx;
|
||||
private final Log _log;
|
||||
private final SnarkManager _mgr;
|
||||
private final String _url;
|
||||
private final byte[] _fakeHash;
|
||||
private final String _name;
|
||||
private volatile long _remaining = -1;
|
||||
private volatile long _total = -1;
|
||||
private volatile long _transferred;
|
||||
private volatile boolean _isRunning;
|
||||
private volatile boolean _active;
|
||||
private volatile long _started;
|
||||
private String _failCause;
|
||||
private Thread _thread;
|
||||
private EepGet _eepGet;
|
||||
|
||||
private static final int RETRIES = 3;
|
||||
|
||||
/**
|
||||
* Caller should call _mgr.addDownloader(this), which
|
||||
* will start things off.
|
||||
*/
|
||||
public FetchAndAdd(I2PAppContext ctx, SnarkManager mgr, String url) {
|
||||
// magnet constructor
|
||||
super(mgr.util(), "Torrent download",
|
||||
null, null, null, null, null, false, null);
|
||||
_ctx = ctx;
|
||||
_log = ctx.logManager().getLog(FetchAndAdd.class);
|
||||
_mgr = mgr;
|
||||
_url = url;
|
||||
_name = "* " + _("Download torrent file from {0}", url);
|
||||
byte[] fake = null;
|
||||
try {
|
||||
fake = SHA1.getInstance().digest(url.getBytes("ISO-8859-1"));
|
||||
} catch (IOException ioe) {}
|
||||
_fakeHash = fake;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set off by startTorrent()
|
||||
*/
|
||||
public void run() {
|
||||
_mgr.addMessage(_("Fetching {0}", urlify(_url)));
|
||||
File file = get();
|
||||
if (!_isRunning) // stopped?
|
||||
return;
|
||||
_isRunning = false;
|
||||
if (file != null && file.exists() && file.length() > 0) {
|
||||
// remove this in snarks
|
||||
_mgr.deleteMagnet(this);
|
||||
add(file);
|
||||
} else {
|
||||
_mgr.addMessage(_("Torrent was not retrieved from {0}", urlify(_url)) +
|
||||
((_failCause != null) ? (": " + _failCause) : ""));
|
||||
}
|
||||
if (file != null)
|
||||
file.delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Copied from I2PSnarkUtil so we may add ourselves as a status listener
|
||||
* @return null on failure
|
||||
*/
|
||||
private File get() {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Fetching [" + _url + "]");
|
||||
File out = null;
|
||||
try {
|
||||
out = SecureFile.createTempFile("torrentFile", null, _mgr.util().getTempDir());
|
||||
} catch (IOException ioe) {
|
||||
_log.error("temp file error", ioe);
|
||||
_mgr.addMessage("Temp file error: " + ioe);
|
||||
if (out != null)
|
||||
out.delete();
|
||||
return null;
|
||||
}
|
||||
out.deleteOnExit();
|
||||
|
||||
if (!_mgr.util().connected()) {
|
||||
_mgr.addMessage(_("Opening the I2P tunnel"));
|
||||
if (!_mgr.util().connect())
|
||||
return null;
|
||||
}
|
||||
I2PSocketManager manager = _mgr.util().getSocketManager();
|
||||
if (manager == null)
|
||||
return null;
|
||||
_eepGet = new I2PSocketEepGet(_ctx, manager, RETRIES, out.getAbsolutePath(), _url);
|
||||
_eepGet.addStatusListener(this);
|
||||
if (_eepGet.fetch()) {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Fetch successful [" + _url + "]: size=" + out.length());
|
||||
return out;
|
||||
} else {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Fetch failed [" + _url + ']');
|
||||
out.delete();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell SnarkManager to copy the torrent file over and add it to the Snarks list.
|
||||
* This Snark may then be deleted.
|
||||
*/
|
||||
private void add(File file) {
|
||||
_mgr.addMessage(_("Torrent fetched from {0}", urlify(_url)));
|
||||
FileInputStream in = null;
|
||||
try {
|
||||
in = new FileInputStream(file);
|
||||
byte[] fileInfoHash = new byte[20];
|
||||
String name = MetaInfo.getNameAndInfoHash(in, fileInfoHash);
|
||||
try { in.close(); } catch (IOException ioe) {}
|
||||
Snark snark = _mgr.getTorrentByInfoHash(fileInfoHash);
|
||||
if (snark != null) {
|
||||
_mgr.addMessage(_("Torrent with this info hash is already running: {0}", snark.getBaseName()));
|
||||
return;
|
||||
}
|
||||
|
||||
name = Storage.filterName(name);
|
||||
name = name + ".torrent";
|
||||
File torrentFile = new File(_mgr.getDataDir(), name);
|
||||
|
||||
String canonical = torrentFile.getCanonicalPath();
|
||||
|
||||
if (torrentFile.exists()) {
|
||||
if (_mgr.getTorrent(canonical) != null)
|
||||
_mgr.addMessage(_("Torrent already running: {0}", name));
|
||||
else
|
||||
_mgr.addMessage(_("Torrent already in the queue: {0}", name));
|
||||
} else {
|
||||
// This may take a LONG time to create the storage.
|
||||
_mgr.copyAndAddTorrent(file, canonical);
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
_mgr.addMessage(_("Torrent at {0} was not valid", urlify(_url)) + ": " + ioe.getMessage());
|
||||
} catch (OutOfMemoryError oom) {
|
||||
_mgr.addMessage(_("ERROR - Out of memory, cannot create torrent from {0}", urlify(_url)) + ": " + oom.getMessage());
|
||||
} finally {
|
||||
try { if (in != null) in.close(); } catch (IOException ioe) {}
|
||||
}
|
||||
}
|
||||
|
||||
// Snark overrides so all the buttons and stats on the web page work
|
||||
|
||||
@Override
|
||||
public synchronized void startTorrent() {
|
||||
if (_isRunning)
|
||||
return;
|
||||
// reset counters in case starting a second time
|
||||
_remaining = -1;
|
||||
// leave the total if we knew it before
|
||||
//_total = -1;
|
||||
_transferred = 0;
|
||||
_failCause = null;
|
||||
_started = _ctx.clock().now();
|
||||
_isRunning = true;
|
||||
_active = false;
|
||||
_thread = new I2PAppThread(this, "Torrent File EepGet", true);
|
||||
_thread.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void stopTorrent() {
|
||||
if (_thread != null && _isRunning) {
|
||||
if (_eepGet != null)
|
||||
_eepGet.stopFetching();
|
||||
_thread.interrupt();
|
||||
}
|
||||
_isRunning = false;
|
||||
_active = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStopped() {
|
||||
return !_isRunning;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return _name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBaseName() {
|
||||
return _name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getInfoHash() {
|
||||
return _fakeHash;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return torrent file size or -1
|
||||
*/
|
||||
@Override
|
||||
public long getTotalLength() {
|
||||
return _total;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return torrent file bytes remaining or -1
|
||||
*/
|
||||
@Override
|
||||
public long getRemainingLength() {
|
||||
return _remaining;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return torrent file bytes remaining or -1
|
||||
*/
|
||||
@Override
|
||||
public long getNeededLength() {
|
||||
return _remaining;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getDownloadRate() {
|
||||
if (_isRunning && _active) {
|
||||
long time = _ctx.clock().now() - _started;
|
||||
if (time > 1000) {
|
||||
long rv = (_transferred * 1000) / time;
|
||||
if (rv >= 100)
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getDownloaded() {
|
||||
return _total - _remaining;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPeerCount() {
|
||||
return (_isRunning && _active && _transferred > 0) ? 1 : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTrackerSeenPeers() {
|
||||
return (_transferred > 0) ? 1 : 0;
|
||||
}
|
||||
|
||||
// End Snark overrides
|
||||
|
||||
// EepGet status listeners to maintain the state for the web page
|
||||
|
||||
public void attemptFailed(String url, long bytesTransferred, long bytesRemaining, int currentAttempt, int numRetries, Exception cause) {
|
||||
if (bytesRemaining >= 0) {
|
||||
_remaining = bytesRemaining;
|
||||
}
|
||||
_transferred = bytesTransferred;
|
||||
if (cause != null)
|
||||
_failCause = cause.toString();
|
||||
_active = false;
|
||||
}
|
||||
|
||||
public void bytesTransferred(long alreadyTransferred, int currentWrite, long bytesTransferred, long bytesRemaining, String url) {
|
||||
if (bytesRemaining >= 0) {
|
||||
_remaining = bytesRemaining;
|
||||
_total = bytesRemaining + currentWrite + alreadyTransferred;
|
||||
}
|
||||
_transferred = bytesTransferred;
|
||||
_active = true;
|
||||
}
|
||||
|
||||
public void transferComplete(long alreadyTransferred, long bytesTransferred, long bytesRemaining, String url, String outputFile, boolean notModified) {
|
||||
if (bytesRemaining >= 0) {
|
||||
_remaining = bytesRemaining;
|
||||
_total = bytesRemaining + alreadyTransferred;
|
||||
}
|
||||
_transferred = bytesTransferred;
|
||||
_active = false;
|
||||
}
|
||||
|
||||
public void transferFailed(String url, long bytesTransferred, long bytesRemaining, int currentAttempt) {
|
||||
if (bytesRemaining >= 0) {
|
||||
_remaining = bytesRemaining;
|
||||
}
|
||||
_transferred = bytesTransferred;
|
||||
_active = false;
|
||||
}
|
||||
|
||||
public void headerReceived(String url, int attemptNum, String key, String val) {}
|
||||
|
||||
public void attempting(String url) {}
|
||||
|
||||
// End of EepGet status listeners
|
||||
|
||||
private String _(String s) {
|
||||
return _mgr.util().getString(s);
|
||||
}
|
||||
|
||||
private String _(String s, String o) {
|
||||
return _mgr.util().getString(s, o);
|
||||
}
|
||||
|
||||
private static String urlify(String s) {
|
||||
return I2PSnarkServlet.urlify(s);
|
||||
}
|
||||
}
|
@ -540,11 +540,8 @@ public class I2PSnarkServlet extends DefaultServlet {
|
||||
*****/
|
||||
if (newURL != null) {
|
||||
if (newURL.startsWith("http://")) {
|
||||
if (!_manager.util().connected())
|
||||
_manager.addMessage(_("Opening the I2P tunnel"));
|
||||
_manager.addMessage(_("Fetching {0}", urlify(newURL)));
|
||||
I2PAppThread fetch = new I2PAppThread(new FetchAndAdd(_manager, newURL), "Fetch and add", true);
|
||||
fetch.start();
|
||||
FetchAndAdd fetch = new FetchAndAdd(_context, _manager, newURL);
|
||||
_manager.addDownloader(fetch);
|
||||
} else if (newURL.startsWith(MAGNET) || newURL.startsWith(MAGGOT)) {
|
||||
addMagnet(newURL);
|
||||
} else if (newURL.length() == 40 && newURL.replaceAll("[a-fA-F0-9]", "").length() == 0) {
|
||||
@ -880,7 +877,17 @@ public class I2PSnarkServlet extends DefaultServlet {
|
||||
*/
|
||||
private class TorrentNameComparator implements Comparator<String> {
|
||||
private final Comparator collator = Collator.getInstance();
|
||||
private final String skip = _manager.getDataDir().getAbsolutePath() + File.separator;
|
||||
private final String skip;
|
||||
|
||||
public TorrentNameComparator() {
|
||||
String s;
|
||||
try {
|
||||
s = _manager.getDataDir().getCanonicalPath();
|
||||
} catch (IOException ioe) {
|
||||
s = _manager.getDataDir().getAbsolutePath();
|
||||
}
|
||||
skip = s + File.separator;
|
||||
}
|
||||
|
||||
public int compare(String l, String r) {
|
||||
if (l.startsWith(skip))
|
||||
@ -916,8 +923,12 @@ public class I2PSnarkServlet extends DefaultServlet {
|
||||
private void displaySnark(PrintWriter out, Snark snark, String uri, int row, long stats[], boolean showPeers,
|
||||
boolean isDegraded, boolean noThinsp, boolean showDebug) throws IOException {
|
||||
String filename = snark.getName();
|
||||
File f = new File(filename);
|
||||
filename = f.getName(); // the torrent may be the canonical name, so lets just grab the local name
|
||||
if (snark.getMetaInfo() != null) {
|
||||
// Only do this if not a magnet or torrent download
|
||||
// Strip full path down to the local name
|
||||
File f = new File(filename);
|
||||
filename = f.getName();
|
||||
}
|
||||
int i = filename.lastIndexOf(".torrent");
|
||||
if (i > 0)
|
||||
filename = filename.substring(0, i);
|
||||
@ -1076,6 +1087,8 @@ public class I2PSnarkServlet extends DefaultServlet {
|
||||
icon = "folder";
|
||||
else if (isValid)
|
||||
icon = toIcon(meta.getName());
|
||||
else if (snark instanceof FetchAndAdd)
|
||||
icon = "arrow_down";
|
||||
else
|
||||
icon = "magnet";
|
||||
if (isValid) {
|
||||
@ -1724,7 +1737,7 @@ public class I2PSnarkServlet extends DefaultServlet {
|
||||
}
|
||||
ihash = xt.substring("urn:btih:".length());
|
||||
trackerURL = getTrackerParam(url);
|
||||
name = "Magnet " + ihash;
|
||||
name = "* " + _("Magnet") + ' ' + ihash;
|
||||
String dn = getParam("dn", url);
|
||||
if (dn != null)
|
||||
name += " (" + Storage.filterName(dn) + ')';
|
||||
@ -1734,7 +1747,7 @@ public class I2PSnarkServlet extends DefaultServlet {
|
||||
int col = ihash.indexOf(':');
|
||||
if (col >= 0)
|
||||
ihash = ihash.substring(0, col);
|
||||
name = "Maggot " + ihash;
|
||||
name = "* " + _("Magnet") + ' ' + ihash;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
@ -1941,7 +1954,7 @@ public class I2PSnarkServlet extends DefaultServlet {
|
||||
}
|
||||
|
||||
/** @since 0.7.14 */
|
||||
private static String urlify(String s) {
|
||||
static String urlify(String s) {
|
||||
return urlify(s, 100);
|
||||
}
|
||||
|
||||
@ -2357,83 +2370,4 @@ public class I2PSnarkServlet extends DefaultServlet {
|
||||
snark.updatePiecePriorities();
|
||||
_manager.saveTorrentStatus(snark.getMetaInfo(), storage.getBitField(), storage.getFilePriorities());
|
||||
}
|
||||
|
||||
|
||||
/** inner class, don't bother reindenting */
|
||||
private static class FetchAndAdd implements Runnable {
|
||||
private SnarkManager _manager;
|
||||
private String _url;
|
||||
public FetchAndAdd(SnarkManager mgr, String url) {
|
||||
_manager = mgr;
|
||||
_url = url;
|
||||
}
|
||||
public void run() {
|
||||
_url = _url.trim();
|
||||
// 3 retries
|
||||
File file = _manager.util().get(_url, false, 3);
|
||||
try {
|
||||
if ( (file != null) && (file.exists()) && (file.length() > 0) ) {
|
||||
_manager.addMessage(_("Torrent fetched from {0}", urlify(_url)));
|
||||
FileInputStream in = null;
|
||||
try {
|
||||
in = new FileInputStream(file);
|
||||
byte[] fileInfoHash = new byte[20];
|
||||
String name = MetaInfo.getNameAndInfoHash(in, fileInfoHash);
|
||||
try { in.close(); } catch (IOException ioe) {}
|
||||
Snark snark = _manager.getTorrentByInfoHash(fileInfoHash);
|
||||
if (snark != null) {
|
||||
_manager.addMessage(_("Torrent with this info hash is already running: {0}", snark.getBaseName()));
|
||||
return;
|
||||
}
|
||||
|
||||
name = Storage.filterName(name);
|
||||
name = name + ".torrent";
|
||||
File torrentFile = new File(_manager.getDataDir(), name);
|
||||
|
||||
String canonical = torrentFile.getCanonicalPath();
|
||||
|
||||
if (torrentFile.exists()) {
|
||||
if (_manager.getTorrent(canonical) != null)
|
||||
_manager.addMessage(_("Torrent already running: {0}", name));
|
||||
else
|
||||
_manager.addMessage(_("Torrent already in the queue: {0}", name));
|
||||
} else {
|
||||
// This may take a LONG time to create the storage.
|
||||
_manager.copyAndAddTorrent(file, canonical);
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
_manager.addMessage(_("Torrent at {0} was not valid", urlify(_url)) + ": " + ioe.getMessage());
|
||||
} catch (OutOfMemoryError oom) {
|
||||
_manager.addMessage(_("ERROR - Out of memory, cannot create torrent from {0}", urlify(_url)) + ": " + oom.getMessage());
|
||||
} finally {
|
||||
try { if (in != null) in.close(); } catch (IOException ioe) {}
|
||||
}
|
||||
} else {
|
||||
// Generate a retry link, but sadly can't have a form inside a table
|
||||
// So make this an ugly GET
|
||||
StringBuilder buf = new StringBuilder(1024);
|
||||
// FIXME don't lose peer setting
|
||||
//String peerParam = req.getParameter("p");
|
||||
//if (peerParam != null)
|
||||
// buf.append("<input type=\"hidden\" name=\"p\" value=\"").append(peerParam).append("\" >\n");
|
||||
buf.append(_("Torrent was not retrieved from {0}", urlify(_url)));
|
||||
/**** FIXME ticket #575
|
||||
String link = urlEncode(_url).replace(":", "%3A").replace("/", "%2F");
|
||||
buf.append(" - [<a href=\"/i2psnark/?newURL=").append(link).append("#add\" >");
|
||||
buf.append(_("Retry"));
|
||||
buf.append("</a>]");
|
||||
****/
|
||||
_manager.addMessage(buf.toString());
|
||||
}
|
||||
} finally {
|
||||
if (file != null) file.delete();
|
||||
}
|
||||
}
|
||||
|
||||
private String _(String s, String o) {
|
||||
return _manager.util().getString(s, o);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user