Deluge WebUI remote torrent adder

This script adds a Deluge icon next to torrent and magnet links. Clicking on it adds the torrent to the WebUI without leaving the page.

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name           Deluge WebUI remote torrent adder
// @description    This script adds a Deluge icon next to torrent and magnet links. Clicking on it adds the torrent to the WebUI without leaving the page.
// @namespace      http://deluge-torrent.info/
// @include        *
// @grant          GM.xmlHttpRequest
// @version        1.7.0
// ==/UserScript==

// Version : 1.7.0

// Author :
// First version by Martijn Voncken ; [email protected].
// Re-write and Deluge 1.2+ support : aidos
// Updated by Adam Rogers ([email protected]) on 2018-02-12: Adapted for GreaseMonkey 4 compatibility, changed XHR content type, code cleanup, changed script name, changed version to 1.7.0
// Original script name: Quickly add torrent files to Deluge 1.2+ WebUI

// Contributors :
// Url-based submit and parsing based on : "Add Torrents To utorrent" by Julien Couvreur
// Cookie support by Aqtrans


// ******************************************************************
// /!\ These parameters need to be edited before using the script /!\
// ******************************************************************

// URL format : http(s)://HOST:PORT

var deluge_password = '';
var deluge_url = '';		// For example: 'https://example.net:8081'

//*******************************************************************


if (deluge_url == '') { alert ('You need to edit this user script with your Deluge parameters before using it.'); }

/* Image number:
	0 = deluge (blue)
	1 = downloading (green)
	2 = active (blue+green)
	3 = seeding (blue)
	4 = loading
	5 = error
*/

var images = {
	0 : 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAAB3RJTUUH1wkPFjUNUreV2QAAAnRJREFUOI19k0toE1EUhv/Mncykd5pMMtNkTDQKGrEWC5ZqXVQ36sJSqAvJztdKUItu3HTXhYggWLBFdyIiihQ3XYgLRUVKfUCpVFrow7TW2k7StGmSmUxmJhk3FmyT9Czv+c7HOefeC2wT3T397dd7Bo5tx7hqJS7cuie0Hdw/zbndZGxivvHR3Wtr1TimlqDBJz3RbSaslUkosjs6VIurKujqfhjn/cq5JY1A1Vkw9f7jN/pe367Gkq0HJ670hWU59PbbeIJX1VW44MAkdZAksT3Scnb4x4cXidqC3l4mVpDH56YTIT91QxQIbNMAjCxyBhhlh9xB955+mvjyStsoYf+vP5qQBspY33O4MYKQ7AMXUACWwjLyWF1cgJokweiu0HMAp6ruwM+7LvMsQbhBRNOhJuyMRqGEAggEFQSiMZTzabCEOXnm5rPzFYJ9Xb2xfC5f5xV4iKKAcESBInkh+Si8lAetF+ARZazkDMiScLVCIFLaCgCGZQOOg6DkheynEOo4uFkChnGBpSJMqwzbto5UjuAq6wAwv7iGpVQGVkGH4OFAGAaO48AulWHaJZiWDccqkng8TjYJkqo6CgCrWQ2zCyt4934E6XQaRdOCXrRg2yUwcEDZEpyiPjU4OFjadI3ZxGfuQFvnxYJh1v9WM8hkNaRTKeTWM7BtC2WHgW5YEEkRk18/3v8zOzq89R3QvFb8tTvW3Onh3WRBzWBqTsVycg3LS0msp5NgS0XMTHx/MzL0oB9ACqj8TEEx1NjS2nHpDu8RmnOawVGPGx6ecwpWKfdzcuzl7KfHfQBmAFjVBBvBAfABoP+6NADkAeS2gn8Blu/uY7RdIbMAAAAASUVORK5CYII=',
	1 : 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAQCAYAAAAiYZ4HAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAFBAAABQQBQWt8+gAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAITSURBVCiRfZLLaxNRFMa/O3PnkaST1zjURixY66IQH+DCgksXLnTXdiOIQSmoy0G3/gmpiDsRI6Ib3bhw40IQXAk1C9NGCoEWS2JNmqSZZJJ5HhexoYngdzmLe8/5cc/5OIyIcFT5Uk5RxOhrJ7BvmdlCDxPikw8xnlyLy/qS5TUJwMpkXjh6ebxx52qUa3drdgWyoC4/3bx3fxJghy3lSzldVzLltls3AvLAwKCrJ9zGYHfRzBaK//wwJaVeOoFtBOQBAAiEA7cup5WZ9/lSLjEGPNlYXZUF9VrHacFq9EfRs3twgv5JTUq/OQTE+PK2nlSmP7bdPWlnvYm55HloMKDBwPZmFZFMiJiUOPNl793uJeN6UYjy+JIXOpGQQjDGMDs/MwpZGZp44NYRl9KP8qUcF6Z4cqXrtyfNGFNIAQIKZiVBuSn45F0gCv8LAEDHa0CT0qYAsA4RUHxbheqnxoriio6fnwf4XbFAw8O4yMQWY8Dc5TRi/eQYML8why7bh3Fag8RkBKG/L4hM2mFMQCKjwlJr+L5eHg7aslAsf4WxoAIAIjwOJ+xtsWc/zHNckL81nZoIAO1qH/iVwEBq4/jZ6N9iDZxJFctrXmREhOdbD29wJr/o+i3ZCWw4tg8lyqGIUcR4Aj55nY7bWDSzhfJol9ZKt0+llOkHAhOvhBQeA6AG5H/quPVXBPpgZgs2APwB/4Li9aLgn7EAAAAASUVORK5CYII=',
	2 : 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAQCAYAAAAiYZ4HAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAFBAAABQQBQWt8+gAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAJCSURBVCiRZZJfSFNxFMc/v7u7ee/+ubk7M53TEqPhi4KU9pAPURFKEeogCHxKorfovXqqp+ipHkZBQSYNoiKIiqDA0kJDLKjAQkSb26xN3a7747y3B9Fsfd/OOZ8v53zhCNM02a5whAqHjSG9yEB0EJ0yyeUNr53rmpPelI4J9JfPpe3FqVscdSucnU6CYqVv4A7nyg1i86RwBF/Ay9fECv61dRACAh6Kc2k6ooNM/rehysFdvbABA5gmJDPYaj08CUeo/Mdw+jZnVCvd6VUorsTgR5R8fIpCCfQC9T4H9zcNli+1l301lbxcWMaaX/6J3/jO/q5ubMYS8ViMdWUHHjvNw+PMn2xjUqpU6c2XUHPpOfzGNK37ugCo37WXUJ2VXPwTyQxoTi6GI8iy107/TCLH0tQ9fC3tmKaBEBvR8rksRuINkj+Fp0oNSs7VS+J81FycT6NJ0hr5hWf0HGrC4dKpsKUYHXtEbXtxI6ywYDda8nJ98KFNaxzn8+OPhJrqqAt0IiQBgM+tMD+SwXBlaWyrxhSmkJyOmKyocUJHNGRZ3oIBdjc3sm4pEGz1IQsbhZKUl4ySPymEhNNXgRzMMvp6HIDldJaxD29pOOAGQJVdZHJyXJqNtQx4bDsBcGkKlkCGV09HeD/xjmDHXziXd60t/g4etowM3Zx98S1b6XfrnQYlLKqJUmPiDSooFgdum4ZpqOZMLHTi2rG+ia1fuvD8wcEGLXfDoab2CItuhZLI5KrjibRr2Fz1XLnac/wXwB8VGdb/8OWcaQAAAABJRU5ErkJggg==',
	3 : 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAQCAYAAAAiYZ4HAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAFBAAABQQBQWt8+gAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAHhSURBVCiRjZK9TxNxGMc/v+vd9dpiX2wbCFoSjCS6GIwJsnVwcGAySKNGw2SjxomwuBj+A/eqUaNg0s3BxRj/AY0EB0kEBhFKWywtvV6vvfbu52CoWE30uz0vnzzP880jpJQcViaHP6SzaDnM5rNY9EntT8SCPEgMML1nIYGZ/rpyOLj6iIthg1trZTA0Ls8+5U4/IA5WyuSIH4+xWqqT7LggBKRiOJt7TOazLP8x4WiIZ1b7ZzOAlFCqow9HeZXJEfkNuP6YmwGNqWoTnHoBNvK0iiu0u2A7pOIhlg4A3+fhhfhQhDc7+2it/W2S3jrn01PoXo1ioUDXP0gsyNjSe7YunWVZiQSYbnUJ2NVvJL01xifSAKRGT3H6mIZd/ETJhMQA9zM5VCUWZOZ7zaa28gLP7SCl13OkZTdwNt9iltZxPUYMjRtKx2VcqAEG0/coWEfodpwesLNrEZmYI5g8SdmEeIg5RQjq/V7/TVKCBKH4BNX/AfwqdFwqiqbyVRH/BsIBsNp8EbcX5Rm/ysftGj633cDc+tBrMqIjGPEThA3QVDYqDc4JKSV3X3LNr/KkYqE3f91MSIdoEByX+q7JZD7Lau+XrjxkdCjCvKpwwfVIAEbX413Z5LmUvM5naQL8AFjEu4EoxfZeAAAAAElFTkSuQmCC',
	4 : 'data:image/gif;base64,R0lGODlhEAAQAPMAAP///wAAAAAAAIKCgnJycqioqLy8vM7Ozt7e3pSUlOjo6GhoaAAAAAAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCgAAACwAAAAAEAAQAAAEKxDISau9OE/Bu//cQBTGgWDhWJ5XSpqoIL6s5a7xjLeyCvOgIEdDLBqPlAgAIfkECQoAAAAsAAAAABAAEAAABCsQyEmrvThPwbv/XJEMxIFg4VieV0qaqCC+rOWu8Yy3sgrzoCBHQywaj5QIACH5BAkKAAAALAAAAAAQABAAAAQrEMhJq704T8G7/9xhFMlAYOFYnldKmqggvqzlrvGMt7IK86AgR0MsGo+UCAAh+QQJCgAAACwAAAAAEAAQAAAEMRDISau9OE/Bu/+cghxGkQyEFY7lmVYraaKqIMpufbc0bLOzFyXGE25AyI5myWw6KREAIfkECQoAAAAsAAAAABAAEAAABDYQyEmrvThPwbv/nKQgh1EkA0GFwFie6SqIpImq29zWMC6xLlssR3vdZEWhDwBqejTQqHRKiQAAIfkECQoAAAAsAAAAABAAEAAABDYQyEmrvThPwbv/HKUgh1EkAyGF01ie6SqIpImqACu5dpzPrRoMpwPwhjLa6yYDOYuaqHRKjQAAIfkECQoAAAAsAAAAABAAEAAABDEQyEmrvThPwbv/nKUgh1EkAxFWY3mmK9WaqCqIJA3fbP7aOFctNpn9QEiPZslsOikRACH5BAkKAAAALAAAAAAQABAAAAQrEMhJq704T8G7/xymIIexEOE1lmdqrSYqiGTsVnA7q7VOszKQ8KYpGo/ICAAh+QQJCgAAACwAAAAAEAAQAAAEJhDISau9OE/Bu/+cthBDEmZjeWKpKYikC6svGq9XC+6e5v/AICUCACH5BAkKAAAALAAAAAAQABAAAAQrEMhJq704T8G7/xy2EENSGOE1lmdqrSYqiGTsVnA7q7VOszKQ8KYpGo/ICAAh+QQJCgAAACwAAAAAEAAQAAAEMRDISau9OE/Bu/+ctRBDUhgHElZjeaYr1ZqoKogkDd9s/to4Vy02mf1ASI9myWw6KREAIfkECQoAAAAsAAAAABAAEAAABDYQyEmrvThPwbv/HLUQQ1IYByKF01ie6SqIpImqACu5dpzPrRoMpwPwhjLa6yYDOYuaqHRKjQAAIfkECQoAAAAsAAAAABAAEAAABDYQyEmrvThPwbv/nLQQQ1IYB0KFwFie6SqIpImq29zWMC6xLlssR3vdZEWhDwBqejTQqHRKiQAAIfkECQoAAAAsAAAAABAAEAAABDEQyEmrvThPwbv/3EIMSWEciBWO5ZlWK2miqiDKbn23NGyzsxclxhNuQMiOZslsOikRADsAAAAAAAAAAAA=',
	5 : 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACp0lEQVR42n2Tz2vUVxTFP++9mQwZDTHqIEQqNYuCXWtxE2NW7twF2l3Joj+Stg6FMlD/gk6hJTJNd0MXLgV/oFa6EAQ3dVtNFokFM9IZkpnvzCSTmXy/3/fu7SKJhIjezV3cc849F+4xqsrhmrW2ABhAAN3vVZHOYaw5LHC9UFg4curUl0dHRxHvVUJAvKfX7TLodv/4KYq+fqfA9ZMnb3w0NTX3WankQq3G8sOHhMGADycniYH7N2+Gf1+8+L3c6Xz7lsCPJ05Uzl2+/NWnxaLj6VP+fvCA8ZkZVJX1W7c4d+ECzZER/rx3L6ytrlZ+7vWKAJk98uLH09NfzMzPO330CEkSGBtj4soVADrPnhG6XUaaTabOn3d/RdHcd87FN0Io2Vlrjw0fP/75zPy8M3fuEFotQqdD0mgQ4hg/GBAtLZE0m+wsLZG7fZuLExPZ4VxubtbaQgYw+Xxew8oK1Gr4Vgvf7zO0tkavXkdCQJaX2V5dJajiRbD1OjlrAUwGsIiQvnqFPHlCUCWocjRJaL98SUgSxozBqxJECKokcYyEoIBkACNxLMn6OkZ1F6jKiLVs1mpIknDEWoLIm5lPEkQEQHcdhEC6s4M9sMUA3ZUVMmlKZo+4f0K664B9B7q1uUl8+jRZY94Am97TjyKMcwy8Z/SAi573xCIGUFsV2dhqtxfv372bbl29ijcGL0JUKDBdLjNdLjM4c4YgQqrKf/k8z3u9NFWtVkU6GYBfvS8VnbMhSa5NXrqUHX78GNdus/n6NdY50kaDVJVGPs8/29tpS6RSUf3+rVcuOvfLB+Pj33xy9myWep2NKEK8Z9gYtkPgeb+ftkQWflP94Z1huubcQm5oaDZrjKoIiKAiJhYhUV2sqJbem8a9OB/bi7M90LUqsnEY+z8wyrjddZe8zwAAAABJRU5ErkJggg=='
};
var counter = 0;


function makeTorrentLink (link, url, i)
{
	var torrentLink = document.createElement ('a');
	var id = 'deluge_link' + i;

	torrentLink.setAttribute ('href', url);
	torrentLink.setAttribute ('id', id);
	torrentLink.style.paddingLeft = '2px';
	torrentLink.innerHTML = '<img src="' + images[0] + '" style="border: 0px" id="image_' + id + '" />';
	link.parentNode.insertBefore (torrentLink, link.nextSibling);

	var domLink = document.getElementById (id);
	domLink.addEventListener ('click', evt_callback_factory (url, id), false);
}


function changeImageSrc (linkId, status, msg)
{
	if (typeof (msg) == 'undefined')
		msg = '';

	var imgIdx = 2;
	if (status == 'ready')
		imgIdx = 0;
	else if (status == 'loading')
		imgIdx = 4;
	else if (status == 'done')
		imgIdx = 1;
	else if (status == 'error')
		imgIdx = 5;

	img = document.getElementById ('image_' + linkId);
	img.src = images[imgIdx];
	img.title = msg;
}


function evt_callback_factory (url, linkId)
{
	function send_request (method, params, onsuccess)	// extra args get passed to onsuccess
	{
		var extra_args = new Array();
		for (var i = 3; i < arguments.length; i++)
			extra_args.push (arguments[i]);

		GM.xmlHttpRequest (
		{
			method :	'POST',
			url :		deluge_url + '/json',
			headers :	{ 'Content-type' : 'application/json' },
			data :		'{"method":"' + method + '","params":' + JSON.stringify (params) + ',"id":' + (counter++) + '}',

			onload : function (xhr)
			{
				res = JSON.parse (xhr.responseText);
				if (res.error == null)
				{
					extra_args.unshift (res);
					onsuccess.apply (null, extra_args);
				}
				else
					changeImageSrc (linkId, 'error', 'Error in response to ' + method + ':\n' + xhr.responseText);
			},

			onerror : function (xhr)
			{
				changeImageSrc (linkId, 'error', 'Error while calling ' + method);
			}
		});
	}//send_request


	function evt_torrent_submit (evt)
	{
		changeImageSrc (linkId, 'loading', 'Authenticating...');
		var params = [ deluge_password ];
		send_request ('auth.login', params, get_download_path);
		if (evt.preventDefault)
			evt.preventDefault();
	}


	function get_download_path (res)
	{
		changeImageSrc (linkId, 'loading', 'Getting download directory...');
		var params = [];
		if (url.match(/^magnet:/i))
			send_request ('core.get_config', params, add_magnet);
		else
			send_request ('core.get_config', params, get_torrent);
	}


	function get_torrent (res)
	{
		changeImageSrc (linkId, 'loading', 'Downloading torrent...');
		var remote_download_dir = res.result.download_location;
		var params = [url, document.cookie];
		send_request ('web.download_torrent_from_url', params, add_torrent, remote_download_dir);
	}


	function add_magnet (res)
	{
		changeImageSrc (linkId, 'loading', 'Adding magnet...');
		var remote_download_dir = res.result.download_location;
		var params = [url, { download_location : remote_download_dir }];
		send_request ('core.add_torrent_magnet', params, after_add);
	}


	function add_torrent (res, remote_download_dir)
	{
		changeImageSrc (linkId, 'loading', 'Adding torrent...');
		var path = res.result;
		var params = [[{ path : path, options : { download_location : remote_download_dir } }]];
		send_request ('web.add_torrents', params, after_add);
	}


	function after_add (res)
	{
		changeImageSrc (linkId, 'done', 'Successfully added:\n' + url + '\n');
	}


	function debug_request (res)
	{
		alert (res.result);
	}


	return (evt_torrent_submit);
}//evt_callback_factory


function match (url)
{
	var ret = { isValid : false, torrentUrl : url };

	if (   url.match (/^magnet:\?.*xt=urn:btih:[a-f0-9]{40}.*/i)								// magnet link
		|| url.match (/\.torrent$/)																// torrent file
/*		|| url.match (/^http(s?):\/\/.*isohunt\.com\/download\//i)								// isohunt format
		|| url.match (/^http(s?):\/\/dl\.torrentreactor\.net\/download.php\?/i)					// TorrentReactor
		|| url.match (/^http(s?):\/\/www\.mininova\.org\/get\//i)								// Mininova
		|| url.match (/^http(s?):\/\/ts\.searching\.com\/download\.asp\?/i)						// TorrentSpy
		|| url.match (/^http(s?):\/\/www\.torrentspy\.com\/download.asp\?/i)					// TorrentSpy
		|| url.match (/^http(s?):\/\/.*seedler\.org\/download\.x\?/i)							// Seedler
		|| url.match (/^http(s?):\/\/.*\/torrents\.php\?action\=download/i)						// Gazelle : (what.cd etc...)
		|| url.match (/^http(s?):\/\/.*legaltorrents\.com\/get\//i)								// Legal torrents
		|| url.match (/^http(s?):\/\/www\.demonoid\.com\/files\/download\/HTTP\//i)				// Demonoid format (from userscripts comments)
		|| url.match (/^http(s?):\/\/www\.demonoid\.com\/files\/download\//i)					// Demonoid format II (from userscripts comments)
		|| url.match (/^http(s?):\/\/bitsnoop\.com\/get\//i)									// BitSnoop
		|| url.match (/^http(s?):\/\/torcache\.net\/torrent\//i)								// TorCache
		|| url.match (/^http(s?):\/\/re\.zoink\.it\/.+/i)										// Twitter eztv.it
*/
	   )
	{
		ret.isValid = true;
	}
/*	else if (url.match (/^http(s?):\/\/www\.bt-chat\.com\/download[0-9]?\.php\?id=([0-9]+)/i))	// bt-chat format
	{
		ret.isValid = true;
		ret.torrentUrl = url + '&type=torrent';
	}
*/

	return (ret);
}


function getLinks()
{
	var doc_links = document.links;
	var links = new Array();
	for (var i = 0; i < doc_links.length; i++)
	{
		links.push (doc_links[i]);
	}
	return (links);
}


function scanLinks()
{
	// duplicate link list, so we don't forever loop when we will be adding our owns
	var links = getLinks();

	for (var i = 0; i < links.length; i++)
	{
		var link = links[i];
		var matchObj = match (link.href);
		if (matchObj.isValid)
			makeTorrentLink (link, matchObj.torrentUrl, i);
	}
}


scanLinks();