From f897f03227f6bf7c4459a1d410e74a8a324d9378 Mon Sep 17 00:00:00 2001 From: Calum Lind Date: Sat, 18 Feb 2012 00:39:24 +0000 Subject: [PATCH] Add magnet uri support to Add Url in Webui --- deluge/ui/web/js/deluge-all/add/AddWindow.js | 3 +- .../ui/web/js/deluge-all/add/OptionsPanel.js | 45 ++++++++------ deluge/ui/web/js/deluge-all/add/UrlWindow.js | 22 +++++-- deluge/ui/web/json_api.py | 59 ++++++++++++++++--- 4 files changed, 96 insertions(+), 33 deletions(-) diff --git a/deluge/ui/web/js/deluge-all/add/AddWindow.js b/deluge/ui/web/js/deluge-all/add/AddWindow.js index 0f270de2a..d3eba5819 100644 --- a/deluge/ui/web/js/deluge-all/add/AddWindow.js +++ b/deluge/ui/web/js/deluge-all/add/AddWindow.js @@ -174,8 +174,6 @@ Deluge.add.AddWindow = Ext.extend(Deluge.add.Window, { if (selections.length) { var record = this.list.getRecord(selections[0]); this.optionsPanel.setTorrent(record.get('info_hash')); - this.optionsPanel.files.setDisabled(false); - this.optionsPanel.form.setDisabled(false); } else { this.optionsPanel.files.setDisabled(true); this.optionsPanel.form.setDisabled(true); @@ -220,6 +218,7 @@ Deluge.add.AddWindow = Ext.extend(Deluge.add.Window, { r.set('text', info['name']); this.list.getStore().commitChanges(); this.optionsPanel.addTorrent(info); + this.list.select(r); } }, diff --git a/deluge/ui/web/js/deluge-all/add/OptionsPanel.js b/deluge/ui/web/js/deluge-all/add/OptionsPanel.js index 5578a4520..629c46d85 100644 --- a/deluge/ui/web/js/deluge-all/add/OptionsPanel.js +++ b/deluge/ui/web/js/deluge-all/add/OptionsPanel.js @@ -1,6 +1,6 @@ /*! * Deluge.add.OptionsPanel.js - * + * * Copyright (c) Damien Churchill 2009-2010 * * This program is free software; you can redistribute it and/or modify @@ -61,7 +61,7 @@ Deluge.add.OptionsPanel = Ext.extend(Ext.TabPanel, { Ext.each(Ext.keys(fileIndexes), function(index) { priorities[index] = fileIndexes[index]; }); - + var oldId = this.form.optionsManager.changeId(torrent['info_hash'], true); this.form.optionsManager.setDefault('file_priorities', priorities); this.form.optionsManager.changeId(oldId, true); @@ -91,23 +91,34 @@ Deluge.add.OptionsPanel = Ext.extend(Ext.TabPanel, { this.torrentId = torrentId; this.form.optionsManager.changeId(torrentId); - + this.files.clearFiles(); var root = this.files.getRootNode(); var priorities = this.form.optionsManager.get('file_priorities'); - this.walkFileTree(this.torrents[torrentId]['files_tree'], function(filename, type, entry, parentNode) { - var node = new Ext.tree.TreeNode({ - download: (entry.index) ? priorities[entry.index] : true, - filename: filename, - fileindex: entry.index, - leaf: type != 'dir', - size: entry.length - }); - parentNode.appendChild(node); - if (type == 'dir') return node; - }, this, root); - root.firstChild.expand(); + this.form.setDisabled(false); + + if (this.torrents[torrentId]['files_tree']) { + this.walkFileTree(this.torrents[torrentId]['files_tree'], function(filename, type, entry, parentNode) { + var node = new Ext.tree.TreeNode({ + download: (entry.index) ? priorities[entry.index] : true, + filename: filename, + fileindex: entry.index, + leaf: type != 'dir', + size: entry.length + }); + parentNode.appendChild(node); + if (type == 'dir') return node; + }, this, root); + root.firstChild.expand(); + this.files.setDisabled(false); + this.files.show(); + } else { + // Files tab is empty so show options tab + this.form.show(); + this.files.setDisabled(true); + } + }, walkFileTree: function(files, callback, scope, parentNode) { @@ -120,7 +131,7 @@ Deluge.add.OptionsPanel = Ext.extend(Ext.TabPanel, { } else { var ret = callback(filename, type, entry, parentNode); } - + if (type == 'dir') this.walkFileTree(entry, callback, scope, ret); } }, @@ -142,7 +153,7 @@ Deluge.add.OptionsPanel = Ext.extend(Ext.TabPanel, { }, this); } else { this.files.setDownload(nodes[0], oldValue, true); - } + } }, scope: this, icon: Ext.MessageBox.QUESTION diff --git a/deluge/ui/web/js/deluge-all/add/UrlWindow.js b/deluge/ui/web/js/deluge-all/add/UrlWindow.js index 2fa8199d6..3aba36c1f 100644 --- a/deluge/ui/web/js/deluge-all/add/UrlWindow.js +++ b/deluge/ui/web/js/deluge-all/add/UrlWindow.js @@ -81,17 +81,27 @@ Deluge.add.UrlWindow = Ext.extend(Deluge.add.Window, { var cookies = this.cookieField.getValue(); var torrentId = this.createTorrentId(); - deluge.client.web.download_torrent_from_url(url, cookies, { - success: this.onDownload, - scope: this, - torrentId: torrentId - }); + if (url.substring(0,20) == 'magnet:?xt=urn:btih:') { + deluge.client.web.get_magnet_info(url, { + success: this.onGotInfo, + scope: this, + filename: url, + torrentId: torrentId + }); + } else { + deluge.client.web.download_torrent_from_url(url, cookies, { + success: this.onDownload, + scope: this, + torrentId: torrentId + }); + } + this.hide(); + this.urlField.setValue(''); this.fireEvent('beforeadd', torrentId, url); }, onDownload: function(filename, obj, resp, req) { - this.urlField.setValue(''); deluge.client.web.get_torrent_info(filename, { success: this.onGotInfo, scope: this, diff --git a/deluge/ui/web/json_api.py b/deluge/ui/web/json_api.py index f3ea05e10..497bcb6af 100644 --- a/deluge/ui/web/json_api.py +++ b/deluge/ui/web/json_api.py @@ -41,6 +41,7 @@ import logging import hashlib import tempfile from urlparse import urljoin +from urllib import unquote_plus from types import FunctionType from twisted.internet import reactor @@ -683,10 +684,8 @@ class WebApi(JSONComponent): :: { - "filename": the torrent file, "name": the torrent name, - "size": the total size of the torrent, - "files": the files the torrent contains, + "files_tree": the files the torrent contains, "info_hash" the torrents info_hash } @@ -699,6 +698,45 @@ class WebApi(JSONComponent): log.exception(e) return False + @export + def get_magnet_info(self, uri): + """ + Return information about a magnet link. + + :param uri: the magnet link + :type uri: string + + :returns: information about the magnet link: + + :: + + { + "name": the torrent name, + "info_hash": the torrents info_hash, + "files_tree": empty value for magnet links + } + + :rtype: dictionary + """ + try: + s = uri.split("&")[0][20:] + if len(s) == 32: + info_hash = base64.b32decode(s).encode("hex") + elif len(s) == 40: + info_hash = s + else: + return False + name = None + for i in uri.split("&")[1:]: + if i[:3] == "dn=": + name = unquote_plus(i.split("=")[1]) + if not name: + name = info_hash + return {"name":name, "info_hash":info_hash, "files_tree":''} + except Exception, e: + log.exception(e) + return False + @export def add_torrents(self, torrents): """ @@ -717,11 +755,16 @@ class WebApi(JSONComponent): """ for torrent in torrents: - filename = os.path.basename(torrent["path"]) - fdump = base64.encodestring(open(torrent["path"], "rb").read()) - log.info("Adding torrent from file `%s` with options `%r`", - filename, torrent["options"]) - client.core.add_torrent_file(filename, fdump, torrent["options"]) + if common.is_magnet(torrent["path"]): + log.info("Adding torrent from magnet uri `%s` with options `%r`", + torrent["path"], torrent["options"]) + client.core.add_torrent_magnet(torrent["path"], torrent["options"]) + else: + filename = os.path.basename(torrent["path"]) + fdump = base64.encodestring(open(torrent["path"], "rb").read()) + log.info("Adding torrent from file `%s` with options `%r`", + filename, torrent["options"]) + client.core.add_torrent_file(filename, fdump, torrent["options"]) return True @export