transmission.js 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. // transmission RPC 操作类
  2. // 栽培者
  3. var transmission = {
  4. SessionId: "",
  5. isInitialized: false,
  6. host: "",
  7. port: "9091",
  8. path: "/transmission/rpc",
  9. rpcpath: "../rpc",
  10. fullpath: "",
  11. on: {
  12. torrentCountChange: null,
  13. postError: null
  14. },
  15. username: "",
  16. password: "",
  17. // 种子状态
  18. _status: {
  19. stopped: 0,
  20. checkwait: 1,
  21. check: 2,
  22. downloadwait: 3,
  23. download: 4,
  24. seedwait: 5,
  25. seed: 6,
  26. // 自定义状态
  27. actively: 101
  28. },
  29. // TrackerStats' announceState
  30. _trackerStatus: {
  31. inactive: 0,
  32. waiting: 1,
  33. queued: 2,
  34. active: 3
  35. },
  36. options: {
  37. getFolders: true,
  38. getTarckers: true
  39. },
  40. headers: {},
  41. trackers: {},
  42. islocal: false,
  43. // The list of directories that currently exist
  44. downloadDirs: new Array(),
  45. getSessionId: function(me, callback) {
  46. var settings = {
  47. type: "POST",
  48. url: this.fullpath,
  49. error: function(request, event, settings) {
  50. var SessionId = "";
  51. if (request.status === 409 && (SessionId = request.getResponseHeader('X-Transmission-Session-Id'))) {
  52. me.isInitialized = true;
  53. me.SessionId = SessionId;
  54. me.headers["X-Transmission-Session-Id"] = SessionId;
  55. if (callback) {
  56. callback();
  57. }
  58. }
  59. },
  60. headers: this.headers
  61. };
  62. jQuery.ajax(settings);
  63. },
  64. init: function(config, callback) {
  65. jQuery.extend(this, config);
  66. /*
  67. if (this.fullpath=="")
  68. {
  69. this.fullpath = this.host + (this.port?":"+this.port:"") + this.path;
  70. }*/
  71. if (this.username && this.password) {
  72. this.headers["Authorization"] = "Basic " + (new Base64()).encode(this.username + ":" + this.password);
  73. }
  74. this.fullpath = this.rpcpath;
  75. this.getSessionId(this, callback);
  76. },
  77. /**
  78. * 执行指定的命令
  79. * @param {[type]} config [description]
  80. * @param {Function} callback [description]
  81. * @param {[type]} tags [description]
  82. * @return {[type]} [description]
  83. */
  84. exec: function(config, callback, tags) {
  85. if (!this.isInitialized) {
  86. return false;
  87. }
  88. var data = {
  89. method: "",
  90. arguments: {},
  91. tag: ""
  92. };
  93. jQuery.extend(data, config);
  94. var settings = {
  95. type: "POST",
  96. url: this.fullpath,
  97. dataType: 'json',
  98. data: JSON.stringify(data),
  99. success: function(resultData, textStatus) {
  100. if (callback) {
  101. callback(resultData, tags);
  102. }
  103. },
  104. error: function(request, event, page) {
  105. var SessionId = "";
  106. if (request.status === 409 && (SessionId = request.getResponseHeader('X-Transmission-Session-Id'))) {
  107. transmission.SessionId = SessionId;
  108. transmission.headers["X-Transmission-Session-Id"] = SessionId;
  109. jQuery.ajax(settings);
  110. } else {
  111. if (transmission.on.postError) {
  112. transmission.on.postError(request);
  113. }
  114. }
  115. },
  116. headers: this.headers
  117. };
  118. jQuery.ajax(settings);
  119. },
  120. getStatus: function(callback) {
  121. this.exec({
  122. method: "session-stats"
  123. }, function(data) {
  124. if (data.result == "success") {
  125. if (callback) {
  126. callback(data.arguments);
  127. }
  128. if (transmission.torrents.count != data.arguments.torrentCount || transmission.torrents.activeTorrentCount != data.arguments.activeTorrentCount || transmission.torrents.pausedTorrentCount != data.arguments.pausedTorrentCount) {
  129. // Current total number of torrents
  130. transmission.torrents.count = data.arguments.torrentCount;
  131. transmission.torrents.activeTorrentCount = data.arguments.activeTorrentCount;
  132. transmission.torrents.pausedTorrentCount = data.arguments.pausedTorrentCount;
  133. transmission._onTorrentCountChange();
  134. }
  135. }
  136. });
  137. },
  138. getSession: function(callback) {
  139. this.exec({
  140. method: "session-get"
  141. }, function(data) {
  142. if (data.result == "success") {
  143. if (callback) {
  144. callback(data.arguments);
  145. }
  146. }
  147. });
  148. },
  149. // 添加种子
  150. addTorrentFromUrl: function(url, savepath, autostart, callback) {
  151. // 磁性连接(代码来自原版WEBUI)
  152. if (url.match(/^[0-9a-f]{40}$/i)) {
  153. url = 'magnet:?xt=urn:btih:' + url;
  154. }
  155. var options = {
  156. method: "torrent-add",
  157. arguments: {
  158. filename: url,
  159. paused: (!autostart)
  160. }
  161. };
  162. if (savepath) {
  163. options.arguments["download-dir"] = savepath;
  164. }
  165. this.exec(options, function(data) {
  166. switch (data.result) {
  167. // 添加成功
  168. case "success":
  169. if (callback) {
  170. if (data.arguments["torrent-added"]) {
  171. callback(data.arguments["torrent-added"]);
  172. }
  173. // 重复的种子
  174. else if (data.arguments["torrent-duplicate"]) {
  175. callback({
  176. status: "duplicate",
  177. torrent: data.arguments["torrent-duplicate"]
  178. });
  179. }
  180. }
  181. break;
  182. // 重复的种子
  183. case "duplicate torrent":
  184. default:
  185. if (callback) {
  186. callback(data.result);
  187. }
  188. break;
  189. }
  190. });
  191. },
  192. // 从文件内容增加种子
  193. addTorrentFromFile: function(file, savePath, paused, callback, filecount) {
  194. var fileReader = new FileReader();
  195. fileReader.onload = function(e) {
  196. var contents = e.target.result;
  197. var key = "base64,";
  198. var index = contents.indexOf(key);
  199. if (index == -1) {
  200. return;
  201. }
  202. var metainfo = contents.substring(index + key.length);
  203. transmission.exec({
  204. method: "torrent-add",
  205. arguments: {
  206. metainfo: metainfo,
  207. "download-dir": savePath,
  208. paused: paused
  209. }
  210. }, function(data) {
  211. switch (data.result) {
  212. // 添加成功
  213. case "success":
  214. if (callback) {
  215. if(data.arguments["torrent-added"] != null)
  216. callback(data.arguments["torrent-added"], filecount);
  217. else if (data.arguments["torrent-duplicate"] != null)
  218. callback({
  219. status: "duplicate",
  220. torrent: data.arguments["torrent-duplicate"]
  221. }, filecount);
  222. else
  223. callback("error");
  224. }
  225. break;
  226. // 重复的种子
  227. case "duplicate torrent":
  228. if (callback) {
  229. callback("duplicate");
  230. }
  231. break;
  232. }
  233. });
  234. }
  235. fileReader.readAsDataURL(file);
  236. },
  237. _onTorrentCountChange: function() {
  238. this.torrents.loadSimpleInfo = false;
  239. if (this.on.torrentCountChange) {
  240. this.on.torrentCountChange();
  241. }
  242. },
  243. // 删除种子
  244. removeTorrent: function(ids, removeData, callback) {
  245. this.exec({
  246. method: "torrent-remove",
  247. arguments: {
  248. ids: ids,
  249. "delete-local-data": removeData
  250. }
  251. }, function(data) {
  252. if (callback)
  253. callback(data.result);
  254. });
  255. },
  256. // 獲取指定目錄的大小
  257. getFreeSpace: function(path, callback) {
  258. this.exec({
  259. method: "free-space",
  260. arguments: {
  261. "path": path
  262. }
  263. }, function(result) {
  264. if (callback)
  265. callback(result);
  266. });
  267. },
  268. // 更新黑名單
  269. updateBlocklist: function(callback) {
  270. this.exec({
  271. method: "blocklist-update"
  272. }, function(data) {
  273. if (callback)
  274. callback(data.result);
  275. });
  276. },
  277. // 重命名指定的种子文件/目录名称
  278. // torrentId 只能指定一个
  279. // oldpath 原文件路径或目录,如:opencd/info.txt 或 opencd/cd1
  280. // newname 新的文件或目录名,如:into1.txt 或 disc1
  281. renameTorrent: function(torrentId, oldpath, newname, callback) {
  282. var torrent = this.torrents.all[torrentId];
  283. if (!torrent)
  284. return false;
  285. this.exec({
  286. method: "torrent-rename-path",
  287. arguments: {
  288. ids: [torrentId],
  289. path: oldpath || torrent.name,
  290. name: newname
  291. }
  292. }, function(data) {
  293. if (callback)
  294. callback(data);
  295. });
  296. },
  297. // 关闭连接?
  298. closeSession: function(callback) {
  299. this.exec({
  300. method: "session-close"
  301. }, function(result) {
  302. if (callback)
  303. callback(result);
  304. });
  305. }
  306. };
  307. /*
  308. (function($){
  309. var items = $("script");
  310. var index = -1;
  311. for (var i=0;i<items.length ;i++ )
  312. {
  313. var src = items[i].src.toLowerCase();
  314. index = src.indexOf("min/transmission.js");
  315. if (index!=-1)
  316. {
  317. // 种子相关信息
  318. $.getScript("script/min/transmission.torrents.js");
  319. break;
  320. }
  321. }
  322. if (index==-1)
  323. {
  324. $.getScript("script/transmission.torrents.js");
  325. }
  326. })(jQuery);
  327. */