🏠 Home 

Greasy Fork is available in English.

Aria2 RPC

Aria2 RPC Library

สคริปต์นี้ไม่ควรถูกติดตั้งโดยตรง มันเป็นคลังสำหรับสคริปต์อื่น ๆ เพื่อบรรจุด้วยคำสั่งเมทา // @require https://update.greasyfork.org/scripts/5672/933444/Aria2%20RPC.js

  1. // ==UserScript==
  2. // @name Aria2 RPC
  3. // @namespace moe.jixun
  4. // @version 0.1
  5. // @license MIT
  6. // ==/UserScript==
  7. // Public Class Aria2 ( options )
  8. var Aria2 = (function (_isGM, _arrFn, _merge, _format, _isFunction) {
  9. var jsonrpc_ver = '2.0';
  10. if (_isGM) {
  11. var doRequest = function ( opts ) {
  12. console.warn ([
  13. 'Warning: You are now using an simple implementation of GM_xmlhttpRequest',
  14. 'Cross-domain request are not avilible unless configured correctly @ target server.',
  15. '',
  16. 'Some of its features are not avilible, such as `username` and `password` field.'
  17. ].join('\n'));
  18. var oReq = new XMLHttpRequest ();
  19. var cbCommon = function (cb) {
  20. return (function () {
  21. cb ({
  22. readyState: oReq.readyState,
  23. responseHeaders: opts.getHeader ? oReq.getAllResponseHeaders() : null,
  24. getHeader: oReq.getResponseHeader.bind (oReq),
  25. responseText: oReq.responseText,
  26. status: oReq.status,
  27. statusText: oReq.statusText
  28. });
  29. }).bind (opts);
  30. };
  31. if (opts.onload) oReq.onload = cbCommon (opts.onload);
  32. if (opts.onerror) oReq.onerror = cbCommon (opts.onerror);
  33. oReq.open(opts.method || 'GET', opts.url, !opts.synchronous);
  34. if (opts.headers) {
  35. Object.keys(opts.headers).forEach (function (key) {
  36. oReq.setRequestHeader (key, opts.headers[key]);
  37. });
  38. }
  39. return oReq.send(opts.data || null);
  40. };
  41. } else {
  42. var doRequest = GM_xmlhttpRequest;
  43. }
  44. var AriaBase = function ( options ) {
  45. this.options = _merge ({
  46. auth: {
  47. type: AriaBase.AUTH.noAuth,
  48. user: '',
  49. pass: ''
  50. },
  51. host: '127.0.0.1',
  52. port: 6800
  53. }, options || {});
  54. this.id = parseInt (options, 10) || (+ new Date());
  55. };
  56. // 静态常量
  57. AriaBase.AUTH = {
  58. noAuth: 0,
  59. basic: 1,
  60. secret: 2
  61. };
  62. // public 函数
  63. AriaBase.prototype = {
  64. getBasicAuth: function () {
  65. return btoa (_format('%s:%s', this.options.auth.user, this.options.auth.pass));
  66. },
  67. send: function ( bIsDataBatch, data, cbSuccess, cbError ) {
  68. var srcTaskObj = { jsonrpc: jsonrpc_ver, id: this.id };
  69. var payload = {
  70. method: 'POST',
  71. url: _format('http://%s:%s/jsonrpc', this.options.host, this.options.port),
  72. headers: {
  73. 'Content-Type': 'application/json; charset=UTF-8'
  74. },
  75. data: bIsDataBatch
  76. ? data.map (function (e) { return _merge ({}, srcTaskObj, e); })
  77. : _merge ({}, srcTaskObj, data),
  78. onload: function (r) {
  79. var repData = JSON.parse (r.responseText);
  80. if (repData.error) {
  81. cbError && cbError (false, repData);
  82. } else {
  83. cbSuccess && cbSuccess (repData);
  84. }
  85. },
  86. onerror: cbError ? cbError.bind(null, false) : null
  87. };
  88. switch ( parseInt (this.options.auth.type, 10) ) {
  89. case AriaBase.AUTH.noAuth:
  90. // DO NOTHING
  91. break;
  92. case AriaBase.AUTH.basic:
  93. payload.headers.Authorization = 'Basic ' + this.getBasicAuth();
  94. break;
  95. case AriaBase.AUTH.secret:
  96. (function (sToken) {
  97. if (bIsDataBatch) {
  98. for (var i = 0; i < payload.data.length; i++) {
  99. payload.data[i].params.splice(0, 0, sToken);
  100. }
  101. } else {
  102. if (!payload.data.params)
  103. payload.data.params = [];
  104. payload.data.params.splice(0, 0, sToken);
  105. }
  106. })(_format('token:%s', this.options.auth.pass));
  107. break;
  108. default:
  109. throw new Error('Undefined auth type: ' + this.options.auth.type);
  110. }
  111. payload.data = JSON.stringify ( payload.data );
  112. return doRequest (payload);
  113. },
  114. // batchAddUri ( foo, { uri: 'http://example.com/xxx', options: { ... } } )
  115. batchAddUri: function (fCallback) {
  116. console.warn (
  117. 'This function [%s] has deprecated! Consider use %s instead.',
  118. 'batchAddUri', 'AriaBase.BATCH'
  119. );
  120. // { url, name }
  121. var payload = [].slice.call (arguments, 1).map (function (arg) {
  122. return {
  123. method: 'aria2.addUri',
  124. params: [ arg.uri.map ? arg.uri : [ arg.uri ] ].concat (arg.options || [])
  125. };
  126. });
  127. return this.send (true, payload, fCallback, fCallback);
  128. }
  129. };
  130. // 添加各类函数
  131. AriaBase.fn = {};
  132. _arrFn.forEach (function (sMethod) {
  133. // 函数链表
  134. AriaBase.fn[sMethod] = sMethod;
  135. // arg1, arg2, ... , [cbSuccess, [cbError]]
  136. AriaBase.prototype[sMethod] = function ( ) {
  137. var args = [].slice.call (arguments);
  138. var cbSuccess, cbError;
  139. if (args.length && _isFunction(args[args.length - 1])) {
  140. cbSuccess = args[args.length - 1];
  141. args.splice (-1, 1);
  142. if (args.length && _isFunction(args[args.length - 1])) {
  143. cbError = cbSuccess;
  144. cbSuccess = args[args.length - 1];
  145. args.splice (-1, 1);
  146. }
  147. }
  148. return this.send (false, {
  149. method: 'aria2.' + sMethod,
  150. params: args
  151. }, cbSuccess, cbError);
  152. };
  153. });
  154. AriaBase.BATCH = function ( parent, cbSuccess, cbFail ) {
  155. if (!(parent instanceof AriaBase))
  156. throw new Error ('Parent is not AriaBase!');
  157. this.parent = parent;
  158. this.data = [];
  159. this.onSuccess = cbSuccess;
  160. this.onFail = cbFail;
  161. };
  162. AriaBase.BATCH.prototype = {
  163. addRaw: function (fn, args) {
  164. this.data.push ({
  165. method: 'aria2.' + fn,
  166. params: args
  167. });
  168. return this;
  169. },
  170. add: function (fn) {
  171. // People can add more without edit source.
  172. if (!AriaBase.fn[fn])
  173. throw new Error ('Unknown function: ' + fn + ', please check if you had a typo.');
  174. return this.addRaw (fn, [].slice.call(arguments, 1));
  175. },
  176. send: function () {
  177. // bIsDataBatch, data, cbSuccess, cbError
  178. var ret = this.parent.send ( true, this.data, this.onSuccess, this.onFail );
  179. this.reset ();
  180. return ret;
  181. },
  182. getActions: function () {
  183. return this.data.slice();
  184. },
  185. setActions: function (actions) {
  186. if (!actions || !actions.map) return ;
  187. this.data = actions;
  188. },
  189. reset: function () {
  190. this.onSuccess = this.onFail = null;
  191. this.setActions ( [] );
  192. }
  193. };
  194. return AriaBase;
  195. })
  196. // const 变量
  197. ('undefined' == typeof GM_xmlhttpRequest, [
  198. "addUri", "addTorrent", "addMetalink", "remove", "forceRemove",
  199. "pause", "pauseAll", "forcePause", "forcePauseAll", "unpause",
  200. "unpauseAll", "tellStatus", "getUris", "getFiles", "getPeers",
  201. "getServers", "tellActive", "tellWaiting", "tellStopped",
  202. "changePosition", "changeUri", "getOption", "changeOption",
  203. "getGlobalOption", "changeGlobalOption", "getGlobalStat",
  204. "purgeDownloadR###lt", "removeDownloadR###lt", "getVersion",
  205. "getSessionInfo", "shutdown", "forceShutdown", "saveSession"
  206. ],
  207. // private 函数
  208. (function (base) {
  209. var _isObject = function (obj) {
  210. return obj instanceof Object;
  211. };
  212. var _merge = function (base) {
  213. var args = arguments,
  214. argL = args.length;
  215. for ( var i = 1; i < argL; i++ ) {
  216. Object.keys (args[i]).forEach (function (key) {
  217. if (_isObject(args[i][key]) && _isObject(base[key])) {
  218. base[key] = _merge (base[key], args[i][key]);
  219. } else {
  220. base[key] = args[i][key];
  221. }
  222. });
  223. }
  224. return base;
  225. };
  226. return _merge;
  227. })(), function (src) {
  228. var args = arguments,
  229. argL = args.length;
  230. var ret = src.slice ();
  231. for ( var i = 1; i < argL; i++ )
  232. ret = ret.replace ('%s', args[i]);
  233. return ret;
  234. }, function (foo) {
  235. return typeof foo === 'function'
  236. });