Guest User

BaiduPanDownloadHelper userscript

a guest
Aug 11th, 2017
111
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 19.14 KB | None | 0 0
  1. // ==UserScript==
  2. // @id baidupan@ywzhaiqi@gmail.com
  3. // @name BaiduPanDownloadHelper modify by ted423
  4. // @version 2016.12.13.0
  5. // @namespace https://github.com/ywzhaiqi
  6. // @author ywzhaiqi
  7. // @description 批量导出百度盘的下载链接
  8. // @grant GM_addStyle
  9. // @grant GM_setClipboard
  10. // @grant GM_openInTab
  11. // @grant GM_xmlhttpRequest
  12. // @homepageURL https://greasyfork.org/scripts/294/
  13. // @require http://code.jquery.com/jquery-2.1.4.min.js
  14. // 兼容 GM 1.x, 2.x
  15. // @require https://greasyfork.org/scripts/2599/code/gm2_port_v102.js
  16.  
  17.  
  18. // @license GPL version 3
  19. // @include http*://yun.baidu.com/share/*
  20. // @include http*://pan.baidu.com/share/*
  21. // @include http*://yun.baidu.com/s/*
  22. // @include http*://pan.baidu.com/s/*
  23. // @include http*://pan.baidu.com/wap/*
  24. // @include http*://yun.baidu.com/wap/*
  25. // @include http*://yun.baidu.com/pcloud/album/*
  26. // @include http*://pan.baidu.com/pcloud/album/*
  27. // @include http*://pan.baidu.com/disk/home*
  28. // @include http*://yun.baidu.com/disk/home*
  29. // @run-at document-start
  30. // ==/UserScript==
  31. (function() {
  32. // 下面的去除云管家,会对上传插件无法显示上传文件夹
  33.  
  34. var tmpScript = document.createElement('script');
  35. tmpScript.textContent = "navigator.__defineGetter__('platform', function() {return 'Linux x86';});navigator.__defineGetter__('userAgent', function() {return 'Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:48.0) Gecko/20100101 Firefox/48.0';});";
  36. document.head.appendChild(tmpScript);
  37. document.head.removeChild(tmpScript);
  38. //阻止百度网盘wap版自动跳转,来自https://greasyfork.org/zh-CN/scripts/13434
  39. document.addEventListener('beforescriptexecute', function(e) {
  40. if (e.target.id == 'platform') {
  41. e.preventDefault();
  42. }
  43. });
  44. })();
  45. document.onreadystatechange = function() {
  46. //alert(document.readyState);
  47. if (document.readyState == "interactive") {
  48. var isChrome = !!this.chrome;
  49.  
  50. function HttpSendRead(info) {
  51. if (info.contentType !== null) info.contentType = "application/x-www-form-urlencoded; charset=UTF-8";
  52. GM_xmlhttpRequest({
  53. method: info.type,
  54. url: info.url,
  55. dataType: info.dataType,
  56. onreadystatechange: function(response) {
  57. if (response.readyState == 4) {
  58. if ((response.status == 200 && response.status < 300) || response.status == 304) {
  59. clearTimeout(timeId);
  60. if (info.dataType == "json") {
  61. deferred.resolve(JSON.parse(response.responseText), response.status, response);
  62. } else if (info.dataType == "SCRIPT") {
  63. // eval(response.responseText);
  64. deferred.resolve(response.responseText, response.status, response);
  65. }
  66. } else {
  67. clearTimeout(timeId);
  68. deferred.reject(response, response.statusText, response.status);
  69. }
  70. }
  71. }
  72. });
  73. };
  74. var SetMessage = function(msg, type) {
  75. var Toast = require("common:widget/toast/toast.js");
  76. Toast.obtain.useToast(cloneInto({
  77. toastMode: Toast.obtain[type],
  78. msg: msg,
  79. sticky: false
  80. }, unsafeWindow));
  81. };
  82. function decode(url, i) {
  83. var newUrl;
  84. GM_xmlhttpRequest({
  85. method: 'get',
  86. url: url,
  87. headers: {
  88. "Referer": "http://pan.baidu.com/disk/home",
  89. "Range": "bytes=0-1",
  90. },
  91. onload: function(response) {
  92. var newUrl = response.finalUrl;
  93. debug(newUrl);
  94. $('.dlinks')[i].href = newUrl;
  95. $('.dlinks')[i].style.color = "red";
  96. }
  97. });
  98. };
  99. var Config = { // 默认的设置
  100. debug: false,
  101.  
  102. trim_titles: [ // Share Home 标题移除的文字广告
  103. "[v.BDpan.COM]"
  104. ],
  105. lineBreak: isChrome ? '\r' : '\n',
  106. };
  107.  
  108.  
  109. var debug = Config.debug ? console.debug.bind(console) : function() {};
  110. // 最新的改版,在个人主页页面已失效,改用下面的 require
  111. var FileUtils = unsafeWindow.FileUtils,
  112. Utilities = unsafeWindow.Utilities,
  113. disk = unsafeWindow.disk,
  114. Page = unsafeWindow.Page;
  115. // 个人主页存在,其它页面可能不存在
  116. var require = unsafeWindow.require;
  117.  
  118. var Utils = {
  119. r1: function(reg, str) {
  120. var m = str.match(reg);
  121. return m ? m[1] : null;
  122. },
  123. getParam: function(name, url) {
  124. var regexp = new RegExp("(?:^|\\?|#|&)" + name + "=([^&#]*)(?:$|&|#)", "i"),
  125. matches = regexp.exec(url || location.href);
  126. return matches ? decodeURIComponent(matches[1]) : "";
  127. },
  128. };
  129.  
  130. var mHome = (function() { // 个人主页
  131. if (!require) return;
  132. var downloadAll = function() {
  133. var context=require("system-core:context/context.js");
  134. var dlinkService=require("disk-system:widget/system/fileService/fileDownLoad/dlinkService.js");
  135. var downloadController=require("file-widget-1:download/controller/downloadController.js");
  136.  
  137. // 得到选中的条目,过滤文件夹
  138. var selected=context.prototype.list.getSelected();
  139. var fileList = [];
  140. $(selected).each(function(i, self) {
  141. var $self = $(self);
  142. if ($self.data('extname') === 'dir') return;
  143.  
  144. fileList.push({
  145. fs_id: $self[0].fs_id,
  146. server_filename: $self[0].server_filename,
  147. })
  148. });
  149.  
  150. if (fileList.length === 0) return;
  151.  
  152. var type = 'dlink',
  153. callback = function(result) {
  154. if (!result.dlink) return;
  155.  
  156. result.dlink.forEach(function(info) {
  157. for (var i = fileList.length - 1, file; i >= 0; i--) {
  158. file = fileList[i];
  159. if (file.fs_id == info.fs_id) {
  160. file.dlink = info.dlink;
  161. break;
  162. }
  163. }
  164. });
  165. Pan.checkedItems = fileList;
  166. Pan.showPanel(fileList);
  167. delete unsafeWindow.gm_pan_callback;
  168. };
  169.  
  170. // 兼容 Greasemonkey 2.0+
  171. exportFunction(callback, unsafeWindow, {
  172. defineAs: "gm_pan_callback"
  173. });
  174. dlinkService.getDlinkPan(dlinkService.getFsidListData(selected), type, unsafeWindow.gm_pan_callback);
  175. };
  176.  
  177. var setDocumentTitle = function() { // 设置页面标题,根据 hash 变化而变化,方便历史记录检索
  178. var path = Utils.getParam('dir/path') || Utils.getParam('path');
  179. if (path === "") {
  180. var key = Utils.getParam('key')
  181. if (key) {
  182. path = "搜索:" + key;
  183. }
  184. }
  185.  
  186. if (path) {
  187. // 不知道是否是百度盘的问题,需要 2 次 decodeURIComponent
  188. document.title = '百度云 网盘-' + decodeURIComponent(path);
  189. }
  190. };
  191.  
  192. var addButton = function() {
  193. $('<a class="icon-btn-download g-button"><span class="g-button-right"><em class="icon icon-offline-download" title="批量下载"></em><span style="width: auto;" class="text">批量下载</span></span></a>')
  194. .insertAfter('a.g-button[data-button-id="b13"]')
  195. .click(downloadAll);
  196. };
  197.  
  198. var init = function() {
  199. addButton();
  200.  
  201. setDocumentTitle();
  202. window.addEventListener('hashchange', setDocumentTitle, false);
  203.  
  204. };
  205.  
  206. return {
  207. init: init
  208. }
  209.  
  210. })();
  211. var Pan = {
  212. fetchCount: 0,
  213. init: function() {
  214. var pageType = this.determineCurrentPageType();
  215. debug('pageType is ', pageType);
  216. if (pageType !== null) {
  217. this.pageType = pageType;
  218. this.processPage(pageType);
  219. }
  220. },
  221. determineCurrentPageType: function() {
  222. var pageType = null;
  223. var loc = window.location.href.toLowerCase();
  224. if (loc.indexOf('/disk/home') != -1) pageType = 'diskHome';
  225. else if (loc.indexOf('/share/link') != -1 || loc.indexOf('/s/') != -1) {
  226. var type = unsafeWindow.yunData.SHAREPAGETYPE;
  227. if (type == 'multi_file') pageType = 'shareDir';
  228. else if (type == 'single_file_page') pageType = 'shareOne';
  229. } else if (loc.indexOf('/share/home') != -1) pageType = 'shareHome';
  230. else if (loc.indexOf('/pcloud/album/info') != -1) pageType = 'albumInfo';
  231. else if (loc.indexOf('/pcloud/album/file') != -1) pageType = 'albumFile';
  232. else if (loc.indexOf('/share/init?') != -1) pageType = 'shareInit';
  233. return pageType;
  234. },
  235. processPage: function(pageType) {
  236. if (pageType !== null) {
  237. var pageProcessor = pageType + 'PageProcessor';
  238.  
  239. this.pageType = pageType;
  240.  
  241. if (typeof(this[pageProcessor]) == 'function') {
  242. GM_addStyle(panelCSS);
  243. this[pageProcessor]();
  244. }
  245. }
  246. },
  247.  
  248. diskHomePageProcessor: function() { // 个人主页
  249. mHome.init();
  250. },
  251. shareDirPageProcessor: function() {
  252. var self = this;
  253. // 添加批量下载按钮
  254. $('<a class="bbtn" style="padding-left:10px"><b>批量下载</b></a>')
  255. .appendTo('.module-list-toolbar>.bar')[0].onclick = function(e) {
  256. self.downloadAll();
  257. };
  258. },
  259. shareOnePageProcessor: function() {
  260.  
  261. },
  262. shareHomePageProcessor: function() {
  263.  
  264. },
  265. albumInfoPageProcessor: function() {
  266. var self = this;
  267. var _mAlbumId, _mUk, _mPage;
  268.  
  269. _mAlbumId = (disk.ui.album.albuminfo && disk.ui.album.albuminfo.album_id) || disk.getParam("album_id");
  270. _mUk = (disk.ui.album.uinfo && disk.ui.album.uinfo.uk) || disk.getParam("uk") || disk.getParam("query_uk");
  271. _mPage = {
  272. count: 0,
  273. totalPage: 0,
  274. nowPage: 1,
  275. limit: 60,
  276. handle: false
  277. };
  278. var getList = function() {
  279. var nowPage = $('#albumPage .page-input-wrap > input').val();
  280. _mPage.nowPage = parseInt(nowPage);
  281. var restUrl = "/pcloud/album/listfile?album_id=" + _mAlbumId + "&query_uk=" + _mUk +
  282. "&start=" + (_mPage.nowPage - 1) * 60 + "&limit=" + _mPage.limit;
  283.  
  284. $.get(restUrl, function(result) {
  285. if (result && result.errno == 0 && result.list) {
  286. Pan.showPanel(result.list);
  287. Pan.toast.setVisible(false);
  288. } else {
  289. Pan.useToast("获取数据出错, " + restUrl);
  290. }
  291. });
  292. };
  293.  
  294. // 内容由 js 生成
  295. var clicked = function(e) {
  296. var $quickFileSave = $('#quickFileSave');
  297. if ($quickFileSave[0]) {
  298. $('<a class="bbutton" style="margin-left:10px;padding-left:5px;">\
  299. <b style="padding-right: 5px;">批量下载</b></a>')
  300. .insertAfter($quickFileSave)[0].onclick = getList;
  301.  
  302. $('body').unbind('click');
  303. }
  304. };
  305. $('body').bind('click', clicked);
  306. },
  307.  
  308. shareInitPageProcessor: function() {
  309.  
  310. },
  311. // --------------------
  312. downloadAll: function() {
  313. var self = this;
  314. var file_list = [];
  315. yunData=unsafeWindow.yunData;
  316. if (yunData.SHAREPAGETYPE == "single_file_page") {
  317. var fid_list = 'fid_list=' + JSON.stringify([yunData.FS_ID]);
  318. set_share_data(yunData, fid_list);
  319. } else {
  320. var File = require("common:widget/data-center/data-center.js");
  321. var Filename = File.get("selectedItemList");
  322. var file_info = File.get("selectedList");
  323. if (file_info.length == 0) {
  324. SetMessage("先选择一下你要下载的文件哦", "MODE_CAUTION");
  325. return;
  326. }
  327. var count=0;
  328. for (var i = 0; i < Filename.length; i++) {
  329. if (Filename[i].attr("data-extname") != "dir") {
  330. var lastFlag=false;
  331. fid_list = 'fid_list=' + JSON.stringify([Filename[i].attr("data-id")]);
  332. yunData["isdir"] = 0;
  333. set_share_data(yunData, fid_list, file_list);
  334. }
  335. }
  336. }
  337. function set_share_data(obj, fid_list, file_list) {
  338. var data = "encrypt=0&product=share&uk=" + yunData.SHARE_UK + "&primaryid=" + yunData.SHARE_ID + "&" + fid_list;
  339. if (yunData.SHARE_PUBLIC == 0) {
  340. var Service = require("common:widget/commonService/commonService.js");
  341. data = data + "&extra=" + encodeURIComponent(JSON.stringify({
  342. sekey: Service.getCookie("BDCLND")
  343. }));
  344. }
  345. if (obj.isdir == 1) {
  346. data = data + "&type=batch";
  347. }
  348. get_share_dlink(obj, data, file_list);
  349. }
  350. function get_share_dlink(obj, data, file_list) {
  351. var download = "http://" + window.location.host + "/api/sharedownload?channel=chunlei&clienttype=0&web=1&app_id=" + yunData.FILEINFO[0].app_id + "&timestamp=" + yunData.TIMESTAMP + "&sign=" + yunData.SIGN + "&bdstoken=" + yunData.MYBDSTOKEN;
  352. var pic = "http://" + window.location.host + "/api/getcaptcha?prod=share&channel=chunlei&clienttype=0&web=1&bdstoken=" + yunData.MYBDSTOKEN + "&app_id=" + yunData.FILEINFO[0].app_id;
  353. var parameter = {
  354. 'url': download,
  355. 'dataType': 'json',
  356. type: 'POST',
  357. 'data': data
  358. };
  359. $.ajax(parameter)
  360. .done(function(json, textStatus, jqXHR) {
  361. if (json.errno == -20) {
  362. $.ajax({
  363. 'url': pic,
  364. 'dataType': 'json',
  365. type: 'GET'
  366. })
  367. .done(function(json, textStatus, jqXHR) {
  368. if (data.indexOf("input") != -1) {
  369. json.auth = true;
  370. }
  371. SetMessage("需输入验证码,无法继续", "MODE_FAILURE");
  372. console.log('需输入验证码,无法继续');
  373. })
  374. .fail(function(json, textStatus, jqXHR) {
  375. SetMessage("获取验证码失败?", "MODE_FAILURE");
  376. });
  377.  
  378. } else if (json.errno == 0) {
  379.  
  380. if (obj.isdir == 1) {
  381. self.get_dir(JSON.stringify(json));
  382. return;
  383. } else {
  384. for (var i = 0; i < json.list.length; i++) {
  385. var list = json.list[i];
  386. file_list.push({
  387. server_filename: list.path.slice(yunData.PATH.lastIndexOf("/") + 1, list.path.length),
  388. dlink: list.dlink
  389. });
  390. }
  391. count++;
  392. debug(count,Filename.length);
  393. if(count==Filename.length)
  394. Pan.showPanel(file_list);
  395. }
  396. } else {
  397. debug(json);
  398. SetMessage("出现异常!", "MODE_FAILURE");
  399. }
  400.  
  401. })
  402. .fail(function(jqXHR, textStatus, errorThrown) {
  403. SetMessage("获取地址失败?", "MODE_FAILURE");
  404. });
  405. }
  406. },
  407.  
  408. getList: function(item) {
  409. var self = this;
  410. var dir, restUrl;
  411.  
  412. dir = item && item.path || disk.getParam('path');
  413. restUrl = this.API_URL + (dir ? '&dir=' + encodeURIComponent(dir) : '');
  414.  
  415. debug('获取数据', restUrl);
  416. $.get(restUrl, function(result) {
  417. self.fetchCount -= 1;
  418. if (result && result.errno == 0 && result.list) {
  419. if (item) {
  420. item.children = result.list;
  421. } else { // 专辑获取到的结果为 checkedItems
  422. self.checkedItems = result.list;
  423. }
  424. self.handleResult(result.list);
  425. } else {
  426. Pan.useToast("获取数据出错, " + restUrl);
  427. }
  428. });
  429. },
  430. handleResult: function() { // 全部获取完成
  431. if (this.fetchCount > 0) return;
  432.  
  433. var self = this;
  434.  
  435. debug('得到选择的数据', this.checkedItems);
  436. },
  437. showPanel: function(checkedItems, dlinkMap) {
  438. if (!this.panel) {
  439. this.panel = this.createPanel();
  440. }
  441. var linksHTML = this.createDLinksHtml(checkedItems, dlinkMap);
  442. $("#mDownload-links").html(linksHTML);
  443. this.panel.style.display = "block";
  444. $('.dlinks').each(function(i) {
  445. var temp=$('.dlinks')[i].href.replace("https","http");
  446. decode(temp, i);
  447. });
  448. },
  449. createPanel: function() {
  450. var self = this;
  451.  
  452. var container = document.createElement("div");
  453. container.id = "mDownload-container";
  454.  
  455. var links_div = document.createElement("div");
  456. links_div.id = "mDownload-links";
  457.  
  458. var closeButton = document.createElement("button");
  459. closeButton.id = "mDownload-close-button";
  460. closeButton.innerHTML = "关闭";
  461. closeButton.onclick = function() {
  462. container.style.display = "none";
  463. };
  464.  
  465. var exportButton = document.createElement("button");
  466. exportButton.id = "mDownload-export-button";
  467. exportButton.innerHTML = "导出";
  468. exportButton.onclick = function() {
  469. GM_openInTab('data:text/html;charset=utf-8,' + encodeURIComponent(links_div.innerHTML));
  470. };
  471.  
  472. var copyButton = document.createElement("button");
  473. copyButton.id = "mDownload-copy-button";
  474. copyButton.innerHTML = "复制";
  475. copyButton.onclick = function() {
  476. self.copyDlinks(null);
  477. };
  478.  
  479. container.appendChild(closeButton);
  480. container.appendChild(exportButton);
  481. container.appendChild(copyButton);
  482. container.appendChild(links_div);
  483. document.body.appendChild(container);
  484. return container;
  485. },
  486.  
  487. dir_tpl: "<b style='padding-left:{padding_left}'>{server_filename}</b>",
  488. dlinks_tpl: "<a class='dlinks' href={dlink} style='padding-left:{padding_left}'>{server_filename}</a>",
  489. createDLinksHtml: function(checkedItems, dlinkMap) {
  490. var self = this,
  491. htmls = [],
  492. isAdded = false;
  493.  
  494. checkedItems.forEach(function(item) {
  495. item.padding_left = "0px";
  496.  
  497. if (item.isdir == 1) {
  498. htmls.push(template(self.dir_tpl, item));
  499.  
  500. if (Array.isArray(item.children)) {
  501. item.children.forEach(function(i) {
  502. i.padding_left = "15px";
  503. if (dlinkMap) {
  504. i.dlink = dlinkMap[i.fs_id];
  505. }
  506. var tpl = i.dlink ? self.dlinks_tpl : self.dir_tpl;
  507. htmls.push(template(tpl, i));
  508. });
  509. }
  510. } else {
  511. if (!isAdded) {
  512. htmls.push("<b>---------------</b>");
  513. isAdded = true;
  514. }
  515. if (dlinkMap) {
  516. item.dlink = dlinkMap[item.fs_id];
  517. }
  518. htmls.push(template(self.dlinks_tpl, item));
  519. }
  520. });
  521. return htmls.join("<br>");
  522. },
  523. copyDlinks: function(items, type) {
  524. var arr = [];
  525. items = $('.dlinks');
  526. items.each(function(i) {
  527. arr.push(items[i].href);
  528. //console.log('copy+'+items[i].href)
  529. });
  530. this.copy(arr);
  531. },
  532. copy: function(arr, isDlink) {
  533. if (typeof isDlink == 'undefined') isDlink = true;
  534.  
  535. GM_setClipboard(arr.join(Config.lineBreak), 'text');
  536. Pan.useToast('已经复制 <b>' + arr.length + '</b> 条' + (isDlink ? '下载' : '') + '链接到剪贴板');
  537. },
  538.  
  539. useToast: function(msg, sticky) {
  540. // disk.ui.Toast.MODE_FAILURE 错误
  541. // disk.ui.Toast.MODE_CAUTION 警告
  542. // disk.ui.Toast.MODE_LOADING 载入
  543. // disk.ui.Toast.MODE_SUCCESS 正常
  544. if (Utilities) {
  545. return Utilities.useToast(cloneInto({
  546. toastMode: disk.ui.Toast.MODE_CAUTION,
  547. msg: msg,
  548. sticky: sticky || false
  549. }, unsafeWindow));
  550. } else if (require) {
  551. var Toast = require("common:widget/toast/toast.js");
  552. Toast.obtain.useToast(cloneInto({
  553. toastMode: Toast.obtain.MODE_CAUTION,
  554. msg: msg,
  555. sticky: sticky || false,
  556. }, unsafeWindow));
  557. }
  558. }
  559. };
  560.  
  561.  
  562. var panelCSS = "#mDownload-container{position:fixed;z-index:1000;left:314px;top:120px;background:white;padding:10px;border:1px solid rgb(153,153,153);box-shadow:0px 0px 9px rgb(153,153,153);}#mDownload-containerbutton{margin-right:10px;}#mDownload-links{margin-top:10px;max-height:400px;overflow:auto;}#mDownload-linksb{color:red;}#mDownload-containerbutton{color:black !important;}";
  563.  
  564.  
  565. function template(tpl, data) {
  566. return tpl.replace(/\{([\w\.]*)\}/g, function(str, key) {
  567. var keys = key.split('.'),
  568. value = data[keys.shift()];
  569. keys.forEach(function(key) {
  570. value = value[key];
  571. });
  572. return (value === null || value === undefined) ? '' : value;
  573. });
  574. }
  575. Pan.init();
  576. }
  577. };
Add Comment
Please, Sign In to add comment