diff --git a/deluge/core/core.py b/deluge/core/core.py index 6c22b1232..832872e62 100644 --- a/deluge/core/core.py +++ b/deluge/core/core.py @@ -237,7 +237,7 @@ class Core(component.Component): :returns: a Deferred which returns the torrent_id as a str or None """ log.info("Attempting to add url %s", url) - def on_get_file(filename): + def on_download_success(filename): # We got the file, so add it to the session f = open(filename, "rb") data = f.read() @@ -248,15 +248,20 @@ class Core(component.Component): log.warning("Couldn't remove temp file: %s", e) return self.add_torrent_file(filename, base64.encodestring(data), options) - def on_get_file_error(failure): - # Log the error and pass the failure onto the client - log.error("Error occured downloading torrent from %s", url) - log.error("Reason: %s", failure.getErrorMessage()) - return failure + def on_download_fail(failure): + if failure.check(twisted.web.client.PartialDownloadError): + result = download_file(url, tempfile.mkstemp()[1], headers=headers, force_filename=True, + allow_compression=False) + result.addCallbacks(on_download_success, on_download_fail) + else: + # Log the error and pass the failure onto the client + log.error("Error occured downloading torrent from %s", url) + log.error("Reason: %s", failure.getErrorMessage()) + result = failure + return result d = download_file(url, tempfile.mkstemp()[1], headers=headers, force_filename=True) - d.addCallback(on_get_file) - d.addErrback(on_get_file_error) + d.addCallbacks(on_download_success, on_download_fail) return d @export diff --git a/deluge/ui/gtkui/addtorrentdialog.py b/deluge/ui/gtkui/addtorrentdialog.py index 62e769de8..cb50cb344 100644 --- a/deluge/ui/gtkui/addtorrentdialog.py +++ b/deluge/ui/gtkui/addtorrentdialog.py @@ -44,7 +44,9 @@ import os import pkg_resources +import twisted.web.client from deluge.ui.client import client +from deluge.httpdownloader import download_file import deluge.component as component import listview from deluge.configmanager import ConfigManager @@ -651,14 +653,18 @@ class AddTorrentDialog(component.Component): dialog.destroy() def on_download_fail(result): - log.debug("Download failed: %s", result) - dialog.destroy() - dialogs.ErrorDialog(_("Download Failed"), _("Failed to download : %s" % url), details=result.getErrorMessage(), parent=self.dialog).run() + if result.check(twisted.web.client.PartialDownloadError): + result = download_file(url, tmp_file, on_part, allow_compression=False) + result.addCallbacks(on_download_success, on_download_fail) + else: + log.debug("Download failed: %s", result) + dialog.destroy() + dialogs.ErrorDialog(_("Download Failed"), _("Failed to download : %s" % url), + details=result.getErrorMessage(), parent=self.dialog).run() + return result - import deluge.httpdownloader - d = deluge.httpdownloader.download_file(url, tmp_file, on_part) - d.addCallback(on_download_success) - d.addErrback(on_download_fail) + d = download_file(url, tmp_file, on_part) + d.addCallbacks(on_download_success, on_download_fail) def _on_button_hash_clicked(self, widget): log.debug("_on_button_hash_clicked") diff --git a/deluge/ui/web/json_api.py b/deluge/ui/web/json_api.py index 7be0316b3..984c178ef 100644 --- a/deluge/ui/web/json_api.py +++ b/deluge/ui/web/json_api.py @@ -45,6 +45,7 @@ from types import FunctionType from twisted.internet import reactor from twisted.internet.defer import Deferred, DeferredList from twisted.web import http, resource, server +import twisted.web.client from deluge import common, component, httpdownloader from deluge.configmanager import ConfigManager, get_config_dir @@ -639,13 +640,29 @@ class WebApi(JSONComponent): :rtype: string """ + def on_download_success(result): + log.debug("Successfully downloaded %s to %s", url, result) + return result + + def on_download_fail(result): + if result.check(twisted.web.client.PartialDownloadError): + result = httpdownloader.download_file(url, tmp_file, headers=headers, + allow_compression=False) + result.addCallbacks(on_download_success, on_download_fail) + else: + log.error("Error occured downloading torrent from %s", url) + log.error("Reason: %s", result.getErrorMessage()) + return result + tmp_file = os.path.join(tempfile.gettempdir(), url.split("/")[-1]) log.debug("filename: %s", tmp_file) headers = {} if cookie: headers["Cookie"] = cookie log.debug("cookie: %s", cookie) - return httpdownloader.download_file(url, tmp_file, headers=headers) + d = httpdownloader.download_file(url, tmp_file, headers=headers) + d.addCallbacks(on_download_success, on_download_fail) + return d @export def get_torrent_info(self, filename): diff --git a/tests/test_core.py b/tests/test_core.py index 1a2cb5698..ce7f666ba 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -52,7 +52,7 @@ class CoreTestCase(unittest.TestCase): return d def test_add_torrent_url_with_cookie(self): - url = "http://deluge-torrent.org/test_torrent.php" + url = "http://deluge-torrent.org/test_torrent.php?test=cookie" options = {} headers = { "Cookie" : "password=deluge" } info_hash = "60d5d82328b4547511fdeac9bf4d0112daa0ce00" @@ -65,6 +65,16 @@ class CoreTestCase(unittest.TestCase): return d + def test_add_torrent_url_with_partial_download(self): + url = "http://deluge-torrent.org/test_torrent.php?test=partial" + options = {} + info_hash = "60d5d82328b4547511fdeac9bf4d0112daa0ce00" + + d = self.core.add_torrent_url(url, options) + d.addCallback(self.assertEquals, info_hash) + + return d + def test_add_magnet(self): info_hash = "60d5d82328b4547511fdeac9bf4d0112daa0ce00" import deluge.common