Greasy Fork is available in English.
在添加Key左边增加一个按钮,功能为批量添加Key
// ==UserScript==// @name btsync 1.4.111 批量添加 Key// @namespace https://userscript.snomiao.com/// @version 0.4.1// @description 在添加Key左边增加一个按钮,功能为批量添加Key// @author [email protected]// @match http://localhost:8888/gui/// @match http://127.0.0.1:8888/gui/// @grant none// ==/UserScript==function 睡(ms) {return new Promise((resolve) => setTimeout(resolve, ms));}function 转WIN路径为WSL路径(path) {return path.replace(/^([A-Z]):(.*)/,(a, disk, path) =>`/mnt/${disk.toLowerCase()}/${path.split("\\").filter((e) => e).join("/")}`);}var { app } = window;async function 尝试到(ms, fn) {let ret;const t = +new Date();while (!(ret = await fn()))if (+new Date() > t + ms) throw "TimeOut";else await 睡(1);return ret;}async function 等元素(ms, sel, el = document) {return await 尝试到(ms, () => el.querySelector(sel));}async function 等元素消失(ms, sel, el = document) {return await 尝试到(ms, () => !el.querySelector(sel));}// function 绑定Click到元素(f, 元素) {// return (元素.addEventListener("click", f), 元素);// }function 新元素(innerHTML, attributes = {}) {return Object.assign(Object.assign(document.createElement("div"), { innerHTML }).children[0],attributes);}function 解析行(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;}async function 异步循环(fn, array) {for (let index = 0; index < array.length; index++) {await fn(array[index], index, array);}}async function 批量添加行(text) {var lines = text.split(/\r?\n/).filter((e) => e);var objs = lines.map(解析行).filter((e) => e);console.debug("正在添加Keys:", objs);await 异步循环(模拟操作添加Key, objs);}// async function 打开添加KeyPath窗口() {// 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);// }async function 模拟操作添加Key({ 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;}// test_模拟操作添加Key()async function openBatch添加KeyPath() {var enterKeyDialog = new app.view.EnterKey({addFolderView: app.addFolderView,}); // we need to pass a reference to addFolderView to EnterKeyvar 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@BXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXC:\\path\\to\\folder#AXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXC:\\path\\to\\folder#BXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXC:\\path\\to\\folder@AXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXC:\\path\\to\\folder@BXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX#key is not in path:/path/to/folder AXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/path/to/folder BXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/path/to/folder #AXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/path/to/folder #BXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXC:\\path\\to\\folder AXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXC:\\path\\to\\folder BXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXC:\\path\\to\\folder #AXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXC:\\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);});}async function addBatchAddButton() {console.log("启动");function 尝试移除元素(e) {return 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();