您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
在添加Key左边增加一个按钮,功能为批量添加Key
当前为
// ==UserScript== // @name btsync 1.4.111 批量添加 Key // @namespace https://userscript.snomiao.com/ // @version 0.4 // @description 在添加Key左边增加一个按钮,功能为批量添加Key // @author [email protected] // @match http://localhost:8888/gui/ // @match http://127.0.0.1:8888/gui/ // @grant none // ==/UserScript== // (function() { // 'use strict'; // 'esversion: 6'; var 睡 = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); var 转WIN路径为WSL路径 = (path) => path.replace( /^([A-Z]):(.*)/, (a, disk, path) => '/mnt/' + disk.toLowerCase() + '/' + path .split('\\') .filter((e) => e) .join('/') ); var app = window.app; var 尝试到 = async (ms, fn) => { let ret, t = +new Date(); while (!(ret = await fn())) if (+new Date() > t + ms) throw 'TimeOut'; else await 睡(1); return ret; }; var 等元素 = async (ms, sel, el = document) => await 尝试到(ms, () => el.querySelector(sel)); var 等元素消失 = async (ms, sel, el = document) => await 尝试到(ms, () => !el.querySelector(sel)); var 绑定Click到元素 = (f, 元素) => (元素.addEventListener('click', f), 元素); var 新元素 = (innerHTML, attributes = {}) => Object.assign( Object.assign(document.createElement('div'), { innerHTML }).children[0], attributes ); var 解析行 = (line) => { var m = line.trim().match(/^(\S*?(\b[A|B][0-9A-Z]{32}\b))$/); m = m || line.trim().match(/^(\S*?)\s+#?(\b[A|B][0-9A-Z]{32}\b)$/); return (m && { path: 转WIN路径为WSL路径(m[1]), key: m[2] }) || null; }; var 异步循环 = async (fn, array) => { for (let index = 0; index < array.length; index++) { await fn(array[index], index, array); } }; var 批量添加行 = async (text) => { var lines = text.split(/\r?\n/).filter((e) => e); var objs = lines.map(解析行).filter((e) => e); console.debug('正在添加Keys:', objs); await 异步循环(模拟操作添加Key, objs); }; var 打开添加KeyPath窗口 = async () => { var enterKeyDialog = new app.view.EnterKey({ addFolderView: app.addFolderView, }); // we need to pass a reference to addFolderView to EnterKey var child = enterKeyDialog.insert(); child.open(); return await 尝试到(60e3, () => child.el); }; var 模拟操作添加Key = async ({ key, path }) => { console.log('正在添加:', key, path); console.debug('正在', 'await 等元素消失(60e3, `.modal-backdrop.fade.in`);'); await 等元素消失(60e3, `.modal-backdrop.fade.in`); console.debug( '正在', 'await 等元素消失(60e3, `#add-folder-dialog[aria-hidden="false"]`);' ); await 等元素消失(60e3, `#add-folder-dialog[aria-hidden="false"]`); console.debug( '正在', 'await 等元素消失(60e3, `#enter-key-dialog[aria-hidden="false"]`);' ); await 等元素消失(60e3, `#enter-key-dialog[aria-hidden="false"]`); // var panel = await 打开添加KeyPath窗口(); await 睡(200); console.debug( +new Date() / 1000, '正在', '(await 等元素(60e3, `#enter-link-button`)).click();' ); (await 等元素(60e3, `#enter-link-button`)).click(); await 睡(200); console.debug( +new Date() / 1000, '正在', '(await 等元素(60e3, `#enter-key-key`)).value = key;' ); (await 等元素(60e3, `#enter-key-key`)).value = key; await 睡(200); console.debug( +new Date() / 1000, '正在', '(await 等元素(60e3, `#enter-key-next`)).click();' ); (await 等元素(60e3, `#enter-key-next`)).click(); await 睡(200); console.debug( +new Date() / 1000, '正在', '(await 等元素(60e3, `#add-folder-dialog[aria-hidden="false"] #add-directory`)).value = path;' ); ( await 等元素( 60e3, `#add-folder-dialog[aria-hidden="false"] #add-directory` ) ).value = path; // await 睡(200); console.debug( +new Date() / 1000, '正在', '(await 等元素(60e3, `#add-folder-dialog[aria-hidden="false"] #add-ok.btn`)).click();' ); ( await 等元素( 60e3, `#add-folder-dialog[aria-hidden="false"] #add-ok.btn` ) ).click(); await 睡(200); await 睡(200); console.debug( +new Date() / 1000, '正在', 'const 错误提示元素 = (await 等元素(60e3, `#add-folder-dialog[aria-hidden="false"] #add-error`));' ); const 错误提示元素 = await 等元素( 60e3, `#add-folder-dialog[aria-hidden="false"] #add-error` ); const 错误 = await 尝试到(60e3, () => 错误提示元素.innerText); console.error('btsync-batch err:', 错误); await 睡(200); console.debug( +new Date() / 1000, '正在', '(await 等元素(60e3, `#add-folder-dialog[aria-hidden="false"] #add-cancel`)).click();' ); ( await 等元素( 60e3, `#add-folder-dialog[aria-hidden="false"] #add-cancel` ) ).click(); await 睡(200); console.debug( +new Date() / 1000, '正在', 'await 等元素消失(60e3, `#add-folder-dialog[aria-hidden="false"]`);' ); await 等元素消失(60e3, `#add-folder-dialog[aria-hidden="false"]`); return true; // var keyElement = await Promise.race([ // 等元素(60e3, `#confirm-dialog[aria-hidden="false"] #okButton`), // 等元素(60e3, `#add-folder-dialog[aria-hidden="false"] #add-error`), // ]); // console.log(keyElement) // if (keyElement.id == "add-error") { // } throw 'X'; // await 睡(200); // console.debug(+new Date() / 1000, '正在', 'const 错误提示元素 = (await 等元素(60e3, `#add-folder-dialog[aria-hidden="false"] #add-error`));'); // const 错误提示元素 = (await 等元素(60e3, `#add-folder-dialog[aria-hidden="false"] #add-error`)); // const 错误 = await 尝试到(60e3, () => 错误提示元素.innerText); // console.error("btsync-batch err:", 错误); // await 睡(200); // console.debug(+new Date() / 1000, '正在', '(await 等元素(60e3, `#add-folder-dialog[aria-hidden="false"] #add-cancel`)).click();'); // (await 等元素(60e3, `#add-folder-dialog[aria-hidden="false"] #add-cancel`)).click(); // await 睡(200); // console.debug(+new Date() / 1000, '正在', 'await 等元素消失(60e3, `#add-folder-dialog[aria-hidden="false"]`);'); // await 等元素消失(60e3, `#add-folder-dialog[aria-hidden="false"]`); // return true var re = await Promise.race([ (async () => { await 睡(100); console.debug( +new Date() / 1000, '正在', '(await 等元素(60e3, `#confirm-dialog[aria-hidden="false"] #okButton`)).click();' ); ( await 等元素( 60e3, `#confirm-dialog[aria-hidden="false"] #okButton` ) ).click(); console.info('已覆盖'); return true; })(), (async () => { await 睡(200); console.debug( +new Date() / 1000, '正在', 'const 错误提示元素 = (await 等元素(60e3, `#add-folder-dialog[aria-hidden="false"] #add-error`));' ); const 错误提示元素 = await 等元素( 60e3, `#add-folder-dialog[aria-hidden="false"] #add-error` ); const 错误 = await 尝试到(60e3, () => 错误提示元素.innerText); console.error('btsync-batch err:', 错误); await 睡(200); console.debug( +new Date() / 1000, '正在', '(await 等元素(60e3, `#add-folder-dialog[aria-hidden="false"] #add-cancel`)).click();' ); ( await 等元素( 60e3, `#add-folder-dialog[aria-hidden="false"] #add-cancel` ) ).click(); await 睡(200); console.debug( +new Date() / 1000, '正在', 'await 等元素消失(60e3, `#add-folder-dialog[aria-hidden="false"]`);' ); await 等元素消失(60e3, `#add-folder-dialog[aria-hidden="false"]`); return true; })(), // 睡(40000) ]); var ret = re || console.error('btsync-batch err: 超时 at', path); console.log(ret); return ret; }; var test_模拟操作添加Key = async () => { var obj = 解析行('C:\\s\\编程随想_管理#B3WNBTAAFFAODFR6FQ3E3L5BBSJAFNBSJ'); await 模拟操作添加Key(obj); }; // test_模拟操作添加Key() var openBatch添加KeyPath = async () => { var enterKeyDialog = new app.view.EnterKey({ addFolderView: app.addFolderView, }); // we need to pass a reference to addFolderView to EnterKey var child = enterKeyDialog.insert(); child.open(); var el = await 尝试到(60e3, () => child.el); ( await 等元素(60e3, '.modal-header h2', el) ).innerHTML = `Enter a group of /path #key`; (await 等元素(60e3, '.modal-body', el)).innerHTML = ` <div class="form-group"> <label for="keyInput">{{#}}</label> <div class="input-group"> <textarea id="enter-list-path-key" type="text" class="form-control"></textarea> <br> <br> <div class="input-group-btn"> <button id="enter-list-path-key-go" class="btn btn-primary" type="button" style="min-height: 40rem;">Go</button> </div> </div> </div>`; el.querySelector( '.modal-body label' ).innerHTML = `Input your /path #key split in lines`; var textarea = el.querySelector('.modal-body textarea'); textarea.style.lineHeight = '1em'; textarea.style.minHeight = '40rem'; textarea.style.fontSize = '1.2rem'; textarea.placeholder = ` #key is in path: /path/to/folder#AXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX /path/to/folder#BXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX /path/to/folder@AXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX /path/to/folder@BXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX C:\\path\\to\\folder#AXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX C:\\path\\to\\folder#BXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX C:\\path\\to\\folder@AXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX C:\\path\\to\\folder@BXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX #key is not in path: /path/to/folder AXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX /path/to/folder BXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX /path/to/folder #AXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX /path/to/folder #BXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX C:\\path\\to\\folder AXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX C:\\path\\to\\folder BXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX C:\\path\\to\\folder #AXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX C:\\path\\to\\folder #BXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX `.trim(); // var textarea = el.querySelector(".modal-body textarea"); (await 等元素(60e3, '.modal-body button', el)).addEventListener( 'click', async () => { (await 等元素(60e3, '.modal-header button.close', el)).click(); 批量添加行(textarea.value); } ); }; var addBatchAddButton = async () => { console.log('启动'); var 尝试移除元素 = (e) => e && e.parentElement.removeChild(e); 尝试移除元素(document.querySelector('#batch-enter-link-button')); var 栏 = await 等元素(60e3, '#topButtons'); var 单个添加按钮 = await 等元素(60e3, '#enter-link-button', 栏); var 批量添加按钮 = 新元素( ` <a id="batch-enter-link-button" role="button" class="btn btn-naked" title="" data-original-title="Enter a group of /path #key" style="background: repeating-linear-gradient(45deg, black, transparent 100px);"> <span class="mycon mycon-enterlink-naked"></span> </a>`, { onclick: openBatch添加KeyPath } ); 栏.insertBefore(批量添加按钮, 单个添加按钮); }; addBatchAddButton(); var test_批量添加行 = () => 批量添加行(` C:\\s\\编程随想_IT#BUPSDXFA3TP7KCMLHALRHLIX2FEJEUJFE C:\\s\\编程随想_管理#B3WNBTAAFFAODFR6FQ3E3L5BBSJAFNBSJ C:\\s\\编程随想_社会学#BZR4TTYHT25QWUIE6YNMAKWUGBHKSGLC6 C:\\s\\编程随想_心理学#BNZ6DOA6W577O6GUNH7C3MY6DWC6FTDQB C:\\s\\编程随想_政治#BRSSYZTSAC6UGYTUOJ22L4GCO7QESPPBD C:\\s\\编程随想_哲学#B6WWVBXPMZDI5IL4KED6AAHA5FO4UNKQF C:\\s\\编程随想_文艺#BMBB5YLBIJJAE5H6TP27OS7YCEUKCYHZK C:\\s\\编程随想_军事#BMWWZALG4P56LREF47EE2WSWHZEM4E6BL C:\\s\\编程随想_历史#BSH7FXJFVWJTKWGSX5GTWX7PHZZ2D2M7Q C:\\s\\编程随想_经济#B2FRYA6AXCDW6CF4YJVFWKH2HAXOFICOX C:\\s\\编程随想的翻墙软件#BTLZ4A4UD3PEWKPLLWEOKH3W7OQJKFPLG C:\\s\\编程随想离线博客#B7P64IMWOCXWEYOXIMBX6HN5MHEULFS4V `); test_批量添加行(); // })()