您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Add torrents to Deluge via Web API (requires patched deluge-web and ViolentMonkey)
当前为
- // ==UserScript==
- // @description Add torrents to Deluge via Web API (requires patched deluge-web and ViolentMonkey)
- // @grant GM.xmlHttpRequest
- // @homepageURL https://github.com/lalbornoz/AddTorrentsDelugeTransmission
- // @include *
- // @license MIT
- // @name Add torrents to Deluge via Web API
- // @namespace https://greasyfork.org/users/467795
- // @supportURL https://github.com/lalbornoz/AddTorrentsDelugeTransmission
- // @version 1.6
- // ==/UserScript==
- /*
- * Tunables
- */
- let debug = false;
- let delugeDownloadDir = {
- "": "/var/lib/deluge/downloads"
- };
- let delugeHostId = "";
- let delugeHttpAuthPassword = ""; // (optional)
- let delugeHttpAuthUsername = ""; // (optional)
- let delugeTorrentDirectory = "/var/lib/deluge/torrents";
- let delugeWebPassword = "";
- let delugeWebUrl = "protocol://hostname[:port]/deluge";
- let linkOpacity = 0.5;
- // {{{ Module variables
- let delugeRequestId = 0;
- // }}}
- // {{{ function basename(url)
- function basename(url) {
- let url_ = url.split("/");
- return url_[url_.length - 1];
- };
- // }}}
- // {{{ function delugeWebRequest(method, onLoadCb, params)
- function delugeWebRequest(method, onLoadCb, params) {
- let headers = {"Content-type": "application/json"};
- let paramsJson = JSON.stringify(params);
- let xhrParams = {
- anonymous: false,
- data: '\{"method":"' + method + '","params":' + paramsJson + ',"id":' + (delugeRequestId++) + '\}',
- headers: headers,
- method: "POST",
- onload: function (xhr) {
- let response = null;
- try {
- response = JSON.parse(xhr.responseText);
- }
- catch (error) {
- logError("Error parsing response from server as JSON: "
- + xhr.responseText);
- };
- if (response.error === null) {
- logDebug("Asynchronous `" + method
- + "' Web API request succeeded w/ response="
- + JSON.stringify(response));
- } else {
- logError("Asynchronous `" + method
- + "' Web API request failed: " + response.error.message
- + " (code " + response.error.code.toString() + ")");
- };
- onLoadCb(response, xhr);
- },
- synchronous: false,
- url: delugeWebUrl + "/json"
- };
- if ((delugeHttpAuthPassword !== "")
- && (delugeHttpAuthUsername !== "")) {
- xhrParams["password"] = delugeHttpAuthPassword;
- xhrParams["user"] = delugeHttpAuthUsername;
- };
- logDebug("POSTing asynchronous `" + method + "' Web API request to " + xhrParams["url"]
- + " (JSON-encoded parameters: " + paramsJson + ")");
- GM.xmlHttpRequest(xhrParams);
- };
- // }}}
- // {{{ function isMagnetLink(url)
- function isMagnetLink(url) {
- if (url.match(/^magnet:/i)) {
- return true;
- } else {
- return false;
- };
- };
- // }}}
- // {{{ function isTorrentLink(url)
- function isTorrentLink(url) {
- if (url.match(/\.torrent(\?.*|)$/i)) {
- return true;
- } else {
- return false;
- };
- };
- // }}}
- // {{{ function JavaScriptIsFuckingGarbage(SodOff)
- function JavaScriptIsFuckingGarbage(SodOff) {
- return decodeURI(SodOff).replace(/\+/g, " ");
- };
- // }}}
- // {{{ function JavaScriptIsFuckingRubbish()
- function JavaScriptIsFuckingRubbish() {
- if(window.Prototype) {
- logDebug("Prototype.js detected, deleting possibly broken {Object,Array,Hash,String}.prototype.toJSON() functions");
- delete Object.prototype.toJSON;
- delete Array.prototype.toJSON;
- delete Hash.prototype.toJSON;
- delete String.prototype.toJSON;
- };
- };
- // }}}
- // {{{ function JavaScriptIsFuckingWorthless(FuckYou)
- function JavaScriptIsFuckingWorthless(FuckYou) {
- return btoa(new Uint8Array(FuckYou).reduce(
- function(data, byte) {
- return data + String.fromCharCode(byte);
- }, ""));
- };
- // }}}
- // {{{ function logDebug(msg)
- function logDebug(msg) {
- if (debug) {
- console.log("[Deluge] " + msg);
- };
- };
- // }}}
- // {{{ function logError(msg)
- function logError(msg) {
- logDebug(msg);
- alert("[Deluge] " + msg);
- };
- // }}}
- // {{{ function logInfo(msg)
- function logInfo(msg) {
- logDebug(msg);
- alert("[Deluge] " + msg);
- };
- // }}}
- // {{{ function matchHostDict(dict, host)
- function matchHostDict(dict, host) {
- let hostDomain = host.split(".").slice(-2);
- if (host in dict) {
- return dict[host];
- } else if (hostDomain in dict) {
- return dict[hostDomain];
- } else {
- return dict[""];
- };
- };
- // }}}
- // {{{ function cbClickMagnet(e)
- function cbClickMagnet(e) {
- let torrentUrl = this.href;
- if (e.ctrlKey) {
- logDebug("Ignoring " + torrentUrl + " due to <Ctrl> modifier.");
- } else {
- e.stopPropagation(); e.preventDefault();
- let torrentName = torrentUrl.match(/dn=([^&]+)/);
- if (torrentName === null) {
- logError("Invalid Magnet URI (missing Display Name)");
- } else {
- torrentName = JavaScriptIsFuckingGarbage(torrentName[1]);
- delugeWebRequest("auth.login",
- function (response, xhr_) {
- cbWebLoginResponse(response, null, delugeDownloadDir[""],
- torrentName, torrentUrl, null, xhr_);
- }, [delugeWebPassword]);
- };
- };
- };
- // }}}
- // {{{ function cbClickTorrent(e)
- function cbClickTorrent(e) {
- let torrentUrl = this.href;
- if (e.ctrlKey) {
- logDebug("Ignoring " + torrentUrl + " due to <Ctrl> modifier.");
- } else {
- e.stopPropagation(); e.preventDefault();
- let torrentUrlHost = torrentUrl.match(new RegExp("^[^:]+://(?:[^:]+:[^@]+@)?([^/:]+)"));
- if (torrentUrlHost === null) {
- logDebug("Failed to obtain hostname from BitTorrent URL " + torrentUrl);
- } else {
- torrentUrlHost = torrentUrlHost[1];
- let torrentDownloadDir = "";
- if ((torrentDownloadDir = matchHostDict(delugeDownloadDir, torrentUrlHost)) === null) {
- torrentDownloadDir = delugeDownloadDir[""];
- };
- logDebug("Sending asynchronous GET request for " + torrentUrl);
- GM.xmlHttpRequest({
- method: "GET",
- onreadystatechange: function (xhr) {
- cbClickResponse(xhr.response, torrentDownloadDir,
- basename(torrentUrl), torrentUrl,
- torrentUrlHost, xhr);
- },
- responseType: "arraybuffer",
- synchronous: false,
- url: torrentUrl
- });
- };
- };
- };
- // }}}
- // {{{ function cbClickResponse(torrent, torrentDownloadDir, torrentName, torrentUrl, torrentUrlHost, xhr)
- function cbClickResponse(torrent, torrentDownloadDir, torrentName, torrentUrl, torrentUrlHost, xhr) {
- logDebug("Asynchronous GET request for " + torrentUrl
- + " readyState=" + xhr.readyState + " status=" + xhr.status);
- if (xhr.readyState === 4) {
- if (xhr.status === 200) {
- delugeWebRequest("auth.login",
- function (response, xhr_) {
- cbWebLoginResponse(response, torrent, torrentDownloadDir,
- torrentName, torrentUrl, torrentUrlHost, xhr_);
- }, [delugeWebPassword]);
- } else {
- logDebug("Asynchronous GET request for " + torrentUrl
- + " failed w/ status=" + xhr.status);
- };
- };
- };
- // }}}
- // {{{ function cbWebLoginResponse(response, torrent, torrentDownloadDir, torrentName, torrentUrl, torrentUrlHost, xhr)
- function cbWebLoginResponse(response, torrent, torrentDownloadDir, torrentName, torrentUrl, torrentUrlHost, xhr) {
- if (response.error === null) {
- delugeWebRequest("web.connect",
- function (response_, xhr_) {
- cbWebConnectResponse(response_, torrent, torrentDownloadDir,
- torrentName, torrentUrl, xhr_);
- }, [delugeHostId]);
- };
- };
- // }}}
- // {{{ function cbWebConnectResponse(response, torrent, torrentDownloadDir, torrentName, torrentUrl, torrentUrlHost, xhr)
- function cbWebConnectResponse(response, torrent, torrentDownloadDir, torrentName, torrentUrl, torrentUrlHost, xhr) {
- if (response.error === null) {
- delugeWebRequest("web.get_config",
- function (response_, xhr_) {
- cbWebGetConfigResponse(response_, torrent, torrentDownloadDir,
- torrentName, torrentUrl, xhr_);
- }, []);
- };
- };
- // }}}
- // {{{ function cbWebGetConfigResponse(response, torrent, torrentDownloadDir, torrentName, torrentUrl, torrentUrlHost, xhr)
- function cbWebGetConfigResponse(response, torrent, torrentDownloadDir, torrentName, torrentUrl, torrentUrlHost, xhr) {
- if (response.error === null) {
- let params = [{options: {"download_location": torrentDownloadDir}}];
- if (isMagnetLink(torrentUrl)) {
- params[0]["path"] = torrentUrl;
- } else {
- params[0]["data"] = JavaScriptIsFuckingWorthless(torrent);
- params[0]["path"] = delugeTorrentDirectory + "/" + torrentName;
- };
- delugeWebRequest("web.add_torrents",
- function (response_, xhr_) {
- cbWebAddTorrentsResponse(response_, torrent, torrentDownloadDir,
- torrentName, torrentUrl, torrentUrlHost, xhr_);
- }, [params]);
- };
- };
- // }}}
- // {{{ function cbWebAddTorrentsResponse(response, torrent, torrentDownloadDir, torrentName, torrentUrl, torrentUrlHost, xhr)
- function cbWebAddTorrentsResponse(response, torrent, torrentDownloadDir, torrentName, torrentUrl, torrentUrlHost, xhr) {
- if (response.error === null) {
- logInfo("Torrent `" + torrentName + "' added successfully.");
- };
- };
- // }}}
- function main() {
- logDebug("Entry point");
- JavaScriptIsFuckingRubbish();
- for (let link of document.links) {
- if (isMagnetLink(link.href)) {
- link.addEventListener("click", cbClickMagnet, true);
- link.style.opacity = linkOpacity;
- logDebug("Registered Magnet link " + link.href);
- } else if (isTorrentLink(link.href)) {
- link.addEventListener("click", cbClickTorrent, true);
- link.style.opacity = linkOpacity;
- logDebug("Registered BitTorrent link " + link.href);
- };
- };
- };
- main();
- // vim:expandtab fileformat=dos sw=2 ts=2