btsync 1.4.111 批量添加 Key

在添加Key左边增加一个按钮,功能为批量添加Key

目前为 2022-01-27 提交的版本。查看 最新版本

// ==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_批量添加行();
// })()