🏠 返回首頁 

Greasy Fork is available in English.

迅雷云盘

获取迅雷云盘的文件链接,可利用本地播放器看视频;可将播放列表导入坚果云;可利用其他工具下载(如idm,curl,Xdown,Motrix,Aria2);添加隐藏回收站功能,可自由彻底删除、还原。


安装此脚本?
作者推荐脚本

您可能也喜欢壁垒搜索


安装此脚本
  1. // ==UserScript==
  2. // @name 迅雷云盘
  3. // @namespace http://tampermonkey.net/
  4. // @version 2.0.3
  5. // @description 获取迅雷云盘的文件链接,可利用本地播放器看视频;可将播放列表导入坚果云;可利用其他工具下载(如idm,curl,Xdown,Motrix,Aria2);添加隐藏回收站功能,可自由彻底删除、还原。
  6. // @author bleu
  7. // @compatible edge Tampermonkey
  8. // @compatible chrome Tampermonkey
  9. // @compatible firefox Tampermonkey
  10. // @license MIT
  11. // @icon https://fastly.jsdelivr.net/gh/Bleu404/PRPO@latest/png/xunlei.png
  12. // @supportURL https://greasyfork.org/zh-CN/scripts/431256/feedback
  13. // @match https://pan.xunlei.com/*
  14. // @grant GM_xmlhttpRequest
  15. // @grant GM_download
  16. // @grant GM_registerMenuCommand
  17. // @connect *
  18. // @connect localhost
  19. // @connect 127.0.0.1
  20. // @connect xunlei.com
  21. // @connect dav.jianguoyun.com
  22. // @require https://fastly.jsdelivr.net/npm/sweetalert2@11.1.0/dist/sweetalert2.all.min.js
  23. // @require https://fastly.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.min.js
  24. // @require https://fastly.jsdelivr.net/npm/clipboard@2.0.8/dist/clipboard.min.js
  25. // ==/UserScript==
  26. (function () {
  27. 'use strict';
  28. const originFetch = fetch;
  29. let linkConfig, reqHeaders, fil###RL,arryIndex,fileArry,filetxt,temp_path,OSflag;
  30. let running = {
  31. 'runStatus': false,
  32. 'successNum': 0,
  33. 'failNum': 0,
  34. 'exit': false,
  35. 'r###ltNum': 0,
  36. }
  37. let $BleuButton,$deleteBut;
  38. isResetConfig();
  39. //退出配置保存数据
  40. function swalCloseFunc() {
  41. let local_path = $('#config_path').val().trim();
  42. let aria2 = {
  43. 'ip': $('#config_ip').val().trim(),
  44. 'port': $('#config_port').val().trim(),
  45. 'token': $('#config_token').val().trim(),
  46. };
  47. let jgy = {
  48. 'path': $('#jgy_path').val().trim(),
  49. 'account': $('#jgy_account').val().trim(),
  50. 'password': $('#jgy_password').val().trim(),
  51. };
  52. let qualityAry = $('#bleu_select').val();
  53. qualityAry = qualityAry === 'highlow' ? ['selected', ''] : ['', 'selected'];
  54. let checkAry = [],
  55. autoClick = {
  56. state: false,
  57. itemIndex: 0
  58. },
  59. itemcount = 0;
  60. $('.td-checkbox__inner.bleu').each((index, item) => {
  61. checkAry[index] = '';
  62. if (item.checked) {
  63. checkAry[index] = 'checked';
  64. autoClick.itemIndex = index;
  65. itemcount++;
  66. }
  67. if (index === $('.td-checkbox__inner.bleu').length - 1 && itemcount === 1) {
  68. autoClick.state = true;
  69. }
  70. })
  71. $('.td-checkbox__inner.bleucb').each((index, item) => {
  72. checkAry[item.getAttribute('index')] = '';
  73. if (item.checked) {
  74. checkAry[item.getAttribute('index')] = 'checked';
  75. }
  76. })
  77. localStorage.setItem("linkConfig", JSON.stringify({
  78. 'local_path': local_path,
  79. 'displays': checkAry,
  80. 'aria2': aria2,
  81. 'jgy': jgy,
  82. 'quality': qualityAry,
  83. 'autoClick': autoClick,
  84. }));
  85. if (local_path.indexOf("/") >= 0) {
  86. OSflag = "/";
  87. }
  88. window.ariaNgUI && window.ariaNgUI.close();
  89. }
  90. //初始或者取配置json
  91. function isResetConfig() {
  92. linkConfig = JSON.parse(localStorage.getItem("linkConfig")) || {
  93. 'local_path': 'D:\\Downloads',
  94. 'displays': ['checked', 'checked', 'checked', 'checked', 'checked', 'checked', '', ''],
  95. 'aria2': {
  96. 'ip': 'http://localhost',
  97. 'port': '16800',
  98. 'token': ''
  99. },
  100. 'jgy': {
  101. 'path': 'ThunderPlaylist',
  102. 'account': '',
  103. 'password': ''
  104. },
  105. 'quality': ['selected', ''],
  106. };
  107. if (!linkConfig.jgy) {
  108. linkConfig.jgy = {
  109. 'path': 'ThunderPlaylist',
  110. 'account': '',
  111. 'password': ''
  112. }
  113. }
  114. }
  115. let main = {
  116. addCssStyle() {
  117. let style = document.createElement('style');
  118. style.innerHTML = tools.cssStyle;
  119. document.querySelector('head').appendChild(style);
  120. },
  121. addElements() {
  122. $BleuButton = $('<div id="bleu_btn" class="FileMenu__item--7MGwA active"><i class="xlpfont xlp-download"></i><span>直链</span></div>');
  123. $deleteBut = $('<li id="bleu_trash" class=""><p class="bar-box"><i class="xlpfont xlp-trash"></i> <span>回收站</span></p></li>');
  124. $('div.pan-wrapper-asider ul li').length == 5&&$('div.pan-wrapper-asider ul').append($deleteBut);
  125. $('div.pan-list-menu').length>0&&$('div.pan-list-menu')[0].innerText.indexOf('彻底删除')!=0&&$('div.pan-list-menu').prepend($BleuButton);
  126. $('.FileMenu__menu--XBFEH').length != 0 ? $('.FileMenu__menu--XBFEH').prepend($BleuButton) : $BleuButton;
  127. if(location.href.indexOf('https://pan.xunlei.com/?filter=trash')==0){
  128. $('#bleu_trash')[0].className = 'on';
  129. }
  130. $('div.pan-wrapper-asider ul li').on('click', ()=>{
  131. $('div.pan-list-menu').length>0&&$('div.pan-list-menu')[0].innerText.indexOf('彻底删除')!=0&&$('div.pan-list-menu').prepend($BleuButton);
  132. if(location.href.indexOf('https://pan.xunlei.com/?filter=trash')!=0){
  133. $('#bleu_trash')[0].className = '';
  134. }
  135. })
  136. },
  137. addButtonEvent() {
  138. $BleuButton.on('click', async function () {
  139. main.getHeaders();
  140. tools.swalForInfo('==获取直链中,请等待==', '', 'center');
  141. if (running.runStatus) {
  142. return
  143. }
  144. isResetConfig();
  145. try {
  146. await main.getAllInfo();
  147. } catch (error) {
  148. console.log(error);
  149. tools.swalForInfo('==请刷新页面重新尝试!==', '', 'center');
  150. running.runStatus = false;
  151. return;
  152. }
  153. let mainui = tools.swalForUI(`成功${running.successNum}条;失败${running.failNum}条`, tools.swalHtml(),400+'px');
  154. $('.btn_bleu').on('click', function (item) {
  155. let temp = item.target.defaultValue;
  156. main.getCollatedData(temp)
  157. })
  158. if (linkConfig.autoClick.state) {
  159. $('.btn_bleu')[linkConfig.autoClick.itemIndex].click();
  160. setTimeout(() => {
  161. mainui.close();
  162. }, 1000);
  163. }
  164. })
  165. GM_registerMenuCommand('直链配置', () => {
  166. isResetConfig();
  167. tools.swalForUI(`直链配置`, tools.swalConfig(),'400px').then(swalCloseFunc);
  168. })
  169. $deleteBut.on('click', function () {
  170. this.className='on';
  171. location.href ='https://pan.xunlei.com/?filter=trash&path=%2F';
  172. })
  173. },
  174. setInitValue() {
  175. arryIndex = 0;
  176. fileArry = [[]];
  177. filetxt = [];
  178. temp_path = '';
  179. running.runStatus = true;
  180. running.successNum = 0;
  181. running.failNum = 0;
  182. running.r###ltNum = 0;
  183. },
  184. async getAllInfo() {
  185. main.setInitValue();
  186. $('li.SourceListItem__item--XxpOC.SourceListItem__active--4U0f4').each((index,item) => {
  187. let temp = item.__vue__.info
  188. let itemInfo = {
  189. 'kind': temp.kind,
  190. 'id': temp.id,
  191. 'name': temp.name,
  192. 'phase': temp.phase,
  193. 'trashed': temp.trashed
  194. };
  195. fileArry[arryIndex].push(itemInfo);
  196. });
  197. await main.getAllFiles(fileArry[0]);
  198. running.runStatus = false;
  199. running.r###ltNum = running.successNum + running.failNum;
  200. },
  201. async getAllFiles(loopArry) {
  202. for (let index = 0; index < loopArry.length; index++) {
  203. if (loopArry[index]) {
  204. if (loopArry[index].kind === 'drive#file') {
  205. await main.getDirectLink(loopArry[index].id);
  206. }
  207. if (loopArry[index].kind === 'drive#folder') {
  208. temp_path += `${OSflag}${loopArry[index].name}`;
  209. await main.getFileSign(loopArry[index]);
  210. await main.getAllFiles(fileArry[arryIndex - 1]);
  211. }
  212. }
  213. }
  214. temp_path = temp_path.substring(0, temp_path.lastIndexOf(OSflag));
  215. },
  216. getFileSign(folder) {
  217. let runURL = `https://api-pan.xunlei.com/drive/v1/files?limit=100&parent_id=${folder.id}&filters={"phase":{"eq":"${folder.phase}"},"trashed":{"eq":${folder.trashed}}}&with_audit=true`;
  218. runURL = encodeURI(runURL);
  219. fileArry[arryIndex] = [];
  220. return tools.bleuAjax('get', runURL).then(value => {
  221. value.files.forEach((item) => {
  222. let temp = {
  223. 'kind': item.kind,
  224. 'id': item.id,
  225. 'name': item.name,
  226. 'phase': item.phase,
  227. 'trashed': item.trashed
  228. };
  229. fileArry[arryIndex].push(temp);
  230. });
  231. arryIndex++;
  232. }, reason => {
  233. runURL === fil###RL ? running.exit = true : running.exit = false;
  234. console.error(reason);
  235. });
  236. },
  237. getDirectLink(sign) {
  238. let URL = `https://api-pan.xunlei.com/drive/v1/files/${sign}`;
  239. return tools.bleuAjax('get', URL).then(value => {
  240. running.successNum++;
  241. let mediasLink = [];
  242. if (value.medias != []) {
  243. value.medias.forEach(function (item) {
  244. if (item.link != null) {
  245. mediasLink.push({
  246. 'name': item.media_name,
  247. 'url': item.media_name === '原始画质' ? value.web_content_link : item.link.url,
  248. })
  249. }
  250. })
  251. }
  252. filetxt.push({
  253. 'name': value.name,
  254. 'link': value.web_content_link,
  255. 'path': temp_path,
  256. 'medias': mediasLink
  257. });
  258. }, reason => {
  259. running.failNum++;
  260. console.log(reason);
  261. });
  262. },
  263. //整理发送到其他工具的数据
  264. async getCollatedData(dataType) {
  265. if (running.r###ltNum === 0) {
  266. return;
  267. }
  268. if (dataType.match('aria2')) {
  269. tools.swalForInfo('==基于aria2发送RPC任务中,请等待==', '', 'center');
  270. }
  271. let nameLinkTxt = '';
  272. let mediaIndex, selectedURL;
  273. if (dataType.match('播放')) {
  274. nameLinkTxt = '#EXTM3U\n'
  275. }
  276. filetxt.forEach(async (item) => {
  277. selectedURL = linkConfig.displays[6] == 'checked' && item.medias.length > 0 ? item.medias[0].url : item.link;
  278. if (dataType.match('aria2')) {
  279. return
  280. }
  281. if (dataType.match('文件链接')) {
  282. nameLinkTxt += `<div style="padding: 5px;"><a class="bleu_a" href=${selectedURL} download=${item.name.replace(/ /g,'_')}>${item.name}</a><span class="bleu_gm">浏览器下载</span></div>`;
  283. }
  284. if (dataType.match('idm')) {
  285. nameLinkTxt += `idman /d "${selectedURL}" /p "${linkConfig.local_path}${item.path}" /f "${item.name}" \nping 127.0.0.1 -n 2 >nul\n`;
  286. }
  287. if (dataType.match('curl')) {
  288. nameLinkTxt += `echo 正在下载这个文件:&echo "${linkConfig.local_path}${item.path}${OSflag}${item.name}"&curl -L "${selectedURL}" -o "${linkConfig.local_path}${item.path}${OSflag}${item.name}"\n\n`;
  289. }
  290. if (dataType.match('Xdown')) {
  291. nameLinkTxt += `aria2c "${selectedURL}" --dir "${linkConfig.local_path}${item.path}" --out "${item.name}"\n`;
  292. }
  293. if (dataType.match('播放')) {
  294. mediaIndex = linkConfig.quality[0] === '' ? item.medias.length - 1 : 0;
  295. nameLinkTxt += `#EXTINF:-1 ,${item.name}\n${item.medias[mediaIndex].url}\n`;
  296. }
  297. });
  298. if(dataType.match('显示')){
  299. tools.swalForUI('显示文件链接',nameLinkTxt,'550px');
  300. $('.bleu_gm').on('click', function (e) {
  301. GM_download({
  302. url: e.target.previousElementSibling.getAttribute('href'),
  303. name: e.target.previousElementSibling.getAttribute('download')
  304. });
  305. })
  306. }
  307. else if (dataType.match('复制')) {
  308. new ClipboardJS('.btn_bleu.xdown', {
  309. text: function () {
  310. return nameLinkTxt;
  311. }
  312. });
  313. tools.swalForInfo('复制链接成功!', 1000, 'top-end');
  314. } else if (dataType.match('aria2')) {
  315. main.sendDataToAria();
  316. } else {
  317. let filenam = `${dataType.replace('.txt','')}${(new Date()).valueOf()}.txt`;
  318. if (dataType.match('播放')) {
  319. main.putDataToJGY(filenam, nameLinkTxt);
  320. } else {
  321. tools._downFlie(filenam, nameLinkTxt);
  322. }
  323. }
  324. },
  325. async sendDataToAria() {
  326. let swalTitle = `导入成功,请到aria2客户端查看任务!`,selectedURL;
  327. for (let index = 0; index < filetxt.length; index++) {
  328. try {
  329. selectedURL = linkConfig.displays[6] == 'checked' && filetxt[index].medias.length > 0 ? filetxt[index].medias[0].url : filetxt[index].link;
  330. if (linkConfig.displays[7] == '') {
  331. await main.sendDataByRPC(index, selectedURL);
  332. } else { //使用ariaNg发送
  333. let timedelay = 100;
  334. if (!window.ariaNgUI || window.ariaNgUI.closed) {
  335. window.ariaNgUI = window.open(`http://ariang.js.org/#!/settings/rpc/set/${linkConfig.aria2.ip.split('://')[0]}/${linkConfig.aria2.ip.split('://')[1]}/${linkConfig.aria2.port}/jsonrpc/${btoa(linkConfig.aria2.token)}`, '_blank');
  336. timedelay = 2000; //不延迟,不能修改rpc配置
  337. }
  338. setTimeout(() => {
  339. window.ariaNgUI == null ? swalTitle = `导入失败,ariaNg页面被拦截了!` : swalTitle;
  340. window.ariaNgUI.location.href = `http://ariang.js.org/#!/new/task?url=${window.btoa(selectedURL)}&out=${encodeURIComponent(filetxt[index].name)}&dir=${encodeURIComponent(linkConfig.local_path)}${encodeURIComponent(filetxt[index].path)}`;
  341. }, timedelay)
  342. }
  343. } catch (error) {
  344. console.log(error.responseText);
  345. swalTitle.match('成功') ? swalTitle = `导入失败,确认配置aria2没问题!` : swalTitle;
  346. break;
  347. }
  348. }
  349. tools.swalForInfo(swalTitle, 3000, 'top-end');
  350. },
  351. sendDataByRPC(index, selectedURL) {
  352. let jsonData = {
  353. id: new Date().getTime(),
  354. jsonrpc: '2.0',
  355. method: 'aria2.addUri',
  356. params: [`token:${linkConfig.aria2.token}`, [selectedURL], {
  357. dir: linkConfig.local_path + filetxt[index].path,
  358. out: filetxt[index].name
  359. }]
  360. }
  361. jsonData = JSON.stringify(jsonData);
  362. return tools.bleuAjax('post', `${linkConfig.aria2.ip}:${linkConfig.aria2.port}/jsonrpc`, jsonData,'');
  363. },
  364. //将播放列表存入坚果云
  365. putDataToJGY(filenam, nameLinkTxt) {
  366. if (linkConfig.jgy.account == '') {
  367. filenam = `迅雷云盘播放列表.m3u`;
  368. tools._downFlie(filenam, nameLinkTxt);
  369. } else {
  370. let url = `https://dav.jianguoyun.com/dav/${linkConfig.jgy.path}/xlPlaylist.m3u`;
  371. let header = {"authorization": `Basic ${btoa(linkConfig.jgy.account+':'+linkConfig.jgy.password)}`};
  372. tools.bleuAjax('put',url , nameLinkTxt,header).then(
  373. (value)=>{
  374. value.status === 204?tools.swalForInfo("导入到坚果云成功!", 3000, 'top-end'):tools.swalForInfo("导入到坚果云失败!", 3000, 'top-end')
  375. },
  376. ()=>{tools.swalForInfo("导入到坚果云失败!", 3000, 'top-end')});
  377. }
  378. },
  379. hookFetch() {
  380. Object.defineProperty(unsafeWindow, "fetch", {
  381. configurable: true,
  382. enumerable: true,
  383. // writable: true,
  384. get() {
  385. return (url, options) => {
  386. if (url.indexOf('https://api-pan.xunlei.com/drive/v1/files?limit=100&') === 0) {
  387. fil###RL = url;
  388. reqHeaders = options.headers;
  389. }
  390. return originFetch(url, options)
  391. }
  392. }
  393. })
  394. },
  395. getHeaders() {
  396. reqHeaders={};
  397. reqHeaders.withCredentials = false;
  398. reqHeaders['content-type'] = 'application/json';
  399. for (let key in localStorage) {
  400. let temp = localStorage.getItem(key)
  401. if (key.indexOf('credentials') === 0) {
  402. reqHeaders.Authorization = JSON.parse(temp).token_type + ' ' + JSON.parse(temp).access_token;
  403. reqHeaders.clientid = key.substring(key.indexOf('_') + 1);
  404. }
  405. if (key.indexOf('captcha') === 0)
  406. reqHeaders['x-captcha-token'] = JSON.parse(temp).token
  407. if (key === 'deviceid')
  408. reqHeaders['x-device-id'] = temp.substring(temp.indexOf('.') + 1, 32 + temp.indexOf('.') + 1)
  409. }
  410. },
  411. initUI() {
  412. let observer = new MutationObserver(function (mutationsList) {
  413. for (let mutation of mutationsList) {
  414. if (mutation.type === 'childList') {
  415. if (mutation.target.querySelector('.pan-wrapper-asider') && $('#bleu_btn').length == 0) {
  416. main.addElements();
  417. main.addButtonEvent();
  418. break;
  419. }
  420. }
  421. }
  422. });
  423. observer.observe($('#__layout')[0], {
  424. childList: true,
  425. subtree: true,
  426. });
  427. if(location.href.indexOf('/s/')>0){
  428. tools.swalForInfo(`❗不支持此页面,请先保存到云盘`, '', 'top-end')
  429. }
  430. },
  431. }
  432. let tools = {
  433. cssStyle: `
  434. .btn_bleu{width: 250px;font-size: 20px;padding: 10px 25px;cursor: pointer;text-align: center;text-decoration: none;outline: none;color: #fff;background-color: #2670ea;border: none;border-radius: 100px;display:block;margin:12px auto}
  435. .btn_bleu:hover{background-color: #3F85FE;box-shadow: 2px 2px 2px 1px rgba(0, 0, 0, 0.2);}
  436. .btn_bleu:active{background-color: #3F85FE;box-shadow: 0 5px #666;transform: translateY(4px)}
  437. .bleu_sa_close {width: 30px;height: 30px;font-size: 30px;}
  438. .bleu_sa_title {font-size: 25px;}
  439. .bleu_sa_container{margin: 0;font-size: 20px;}
  440. .bleu_sa_popup {padding: 0 0 0;}
  441. .bleu_a{text-decoration: underline;font-size: 16px;white-space: nowrap;background: linear-gradient(to right, red, blue);-webkit-background-clip: text;color: transparent;display: inline-block;width: 400px;}
  442. .bleu_a:hover{color: #3F85FE}
  443. .bleu_sa_footer{margin: 0;padding-top: 20px;}
  444. .bleu_sa_title_min{font-size: 20px !important;padding: 0;}
  445. .bleu_sa_popup_min{padding: 0 0 0;width: auto;}
  446. .bleu_config{position: absolute;left: 5%;bottom: 10%;width: 60px;height: 60px;line-height: 60px;border-radius: 50%;cursor: pointer;font-size: 13px;background-color: #2670ea;color: #fff;text-align: center;}
  447. .bleu_config:hover{background-color: #3F85FE}
  448. .bleu_config_item{border-radius: 10px;font-size: 20px;margin: 12px 50px;color: #fff;background-color: #3F85FE;box-shadow: 2px 2px 2px 1px rgba(0, 0, 0, 0.2);}
  449. .bleu_config_item label{font-size: 15px}
  450. .bleu_config_item input.bleu_inp{margin: 0px 10px;font-size: 15px;}
  451. .bleu_config_item input.td-checkbox__inner{margin: 0px 10px 0px 0px}
  452. .bleu_inp{width:60%}
  453. .bleu_config_item p{text-align: left;margin: 0px 20px;}
  454. .bleu_gm{margin-left: 10px;font-size: 14px;background-color: #2670ea;color: white;border-radius: 5%;padding: 5px 10px;}
  455. .bleu_gm:hover{background-color: #3F85FE;box-shadow: 2px 2px 2px 1px rgba(0, 0, 0, 0.2);}
  456. .bleu_gm:active{background-color: #3F85FE;box-shadow: 0 5px #666;transform: translateY(4px)}
  457. #bleu_select{margin: 0px 10px;background-color: #3F85FE;font-size: 15px;border: none;}
  458. `,
  459. swalHtml: function () {
  460. return `<div><input type="button" style="display:${linkConfig.displays[0]==='checked'?'block':'none'}" class="btn_bleu" value="显示文件链接"></input></div>
  461. <div><input type="button" style="display:${linkConfig.displays[1]==='checked'?'block':'none'}" class="btn_bleu xdown" value="复制idm下载链接"></input></div>
  462. <div><input type="button" style="display:${linkConfig.displays[2]==='checked'?'block':'none'}" class="btn_bleu" value="curl下载.txt"></input></div>
  463. <div><input type="button" style="display:${linkConfig.displays[3]==='checked'?'block':'none'}" class="btn_bleu xdown" value="复制Xdown下载链接"></input></div>
  464. <div><input type="button" style="display:${linkConfig.displays[4]==='checked'?'block':'none'}" class="btn_bleu" value="基于aria2发送RPC任务"></input></div>
  465. <div><input type="button" style="display:${linkConfig.displays[5]==='checked'?'block':'none'}" class="btn_bleu" value="导出播放列表"></input></div>
  466. <a class="bleu_a" href="https://greasyfork.org/zh-CN/scripts/431256" target="_blank">按钮功能说明</a>
  467. `
  468. },
  469. swalConfig: function () {
  470. return `<div class="bleu_config_item"><b>本地下载路径</b>
  471. <p><label>目录</label><input type="text" class="bleu_inp" id="config_path" value="${linkConfig.local_path}"/></p>
  472. </div>
  473. <div class="bleu_config_item"><b>功能按钮显示</b>
  474. <p><input type="checkbox" ${linkConfig.displays[0]} class="td-checkbox__inner bleu"></input><label>显示“显示文件链接”</label></p>
  475. <p><input type="checkbox" ${linkConfig.displays[1]} class="td-checkbox__inner bleu"></input><label>显示“复制idm下载链接”</label></p>
  476. <p><input type="checkbox" ${linkConfig.displays[2]} class="td-checkbox__inner bleu"></input><label>显示“curl下载.txt”</label></p>
  477. <p><input type="checkbox" ${linkConfig.displays[3]} class="td-checkbox__inner bleu"></input><label>显示“复制Xdown下载链接”</label></p>
  478. <p><input type="checkbox" ${linkConfig.displays[4]} class="td-checkbox__inner bleu"></input><label>显示“基于aria2发送RPC任务”</label></p>
  479. <p><input type="checkbox" ${linkConfig.displays[5]} class="td-checkbox__inner bleu"></input><label>显示“导出播放列表”</label></p>
  480. </div>
  481. <div class="bleu_config_item"><b>配置aria2任务</b>
  482. <p><input type="checkbox" index="7" ${linkConfig.displays[7]} class="td-checkbox__inner bleucb"></input><label>通过ariaNg远程发送任务</label></p>
  483. <p><label>地址</label><input type="text" class="bleu_inp" id="config_ip" value="${linkConfig.aria2.ip}"/></p>
  484. <p><label>端口</label><input type="text" class="bleu_inp" id="config_port" value="${linkConfig.aria2.port}"/></p>
  485. <p><label>密钥</label><input type="text" class="bleu_inp" id="config_token" value="${linkConfig.aria2.token}"/></p>
  486. </div>
  487. <div class="bleu_config_item"><b>播放列表设置</b>
  488. <p><label>画质选择</label><select id="bleu_select">
  489. <option value="highlow" ${linkConfig.quality[0]}>从高到低</option>
  490. <option value="lowhigh" ${linkConfig.quality[1]}>从低到高</option>
  491. </select></p>
  492. <b>列表存坚果云</b>
  493. <p><label>文件夹</label><input type="text" class="bleu_inp" id="jgy_path" value="${linkConfig.jgy.path}"/></p>
  494. <p><label>账户</label><input type="text" class="bleu_inp" id="jgy_account" value="${linkConfig.jgy.account}"/></p>
  495. <p><label>授权密码</label><input type="text" class="bleu_inp" id="jgy_password" value="${linkConfig.jgy.password}"/></p>
  496. </div>
  497. <div class="bleu_config_item"><b>视频专用下载</b>
  498. <p><input type="checkbox" index="6" ${linkConfig.displays[6]} class="td-checkbox__inner bleucb"></input><label>勾选此项,不下载源文件,下载云播最高清晰度视频。</label></p>
  499. </div>`
  500. },
  501. swalForUI: function (title, html,width) {
  502. return swal.fire({
  503. title: title,
  504. html: html,
  505. width: width,
  506. showConfirmButton: false,
  507. showCloseButton: true,
  508. allowOutsideClick: false,
  509. footer: ' ',
  510. customClass: {
  511. title: 'bleu_sa_title',
  512. popup: 'bleu_sa_popup',
  513. closeButton: 'bleu_sa_close',
  514. htmlContainer: 'bleu_sa_container',
  515. footer: 'bleu_sa_footer'
  516. },
  517. })
  518. },
  519. swalForInfo: function (satitle, satime, saposition) {
  520. return Swal.fire({
  521. title: satitle,
  522. position: saposition,
  523. showConfirmButton: false,
  524. timer: satime,
  525. customClass: {
  526. title: 'bleu_sa_title_min',
  527. popup: 'bleu_sa_popup_min'
  528. }
  529. })
  530. },
  531. bleuAjax: function (TYPE, URL, DATA,HEADER) {
  532. return new Promise((resolve, reject) => {
  533. GM_xmlhttpRequest({
  534. method: TYPE,
  535. timeout: 2000,
  536. headers: HEADER||reqHeaders,
  537. url: URL,
  538. data: DATA,
  539. dataType: "json",
  540. onload: function (res) {
  541. resolve(JSON.parse(res.response||null)||res.response||res);
  542. },
  543. onerror: function (err) {
  544. reject(JSON.parse(err.response||null)||err.response||err);
  545. },
  546. ontimeout:function(err){
  547. reject(err);
  548. }
  549. });
  550. })
  551. },
  552. _downFlie(fnmae, data) {
  553. let elementA = document.createElement('a');
  554. elementA.download = fnmae;
  555. elementA.style.display = 'none';
  556. let blob = new Blob([data]);
  557. elementA.href = URL.createObjectURL(blob);
  558. document.body.appendChild(elementA);
  559. elementA.click();
  560. document.body.removeChild(elementA);
  561. },
  562. platform() {
  563. OSflag = "\\";
  564. if (linkConfig.local_path.indexOf("/") >= 0) {
  565. OSflag = "/";
  566. }
  567. }
  568. }
  569. window.onunload = () => {
  570. window.ariaNgUI && window.ariaNgUI.close();
  571. };
  572. //main.hookFetch();
  573. main.addCssStyle();
  574. tools.platform();
  575. main.initUI();
  576. })();