Skip to content

Instantly share code, notes, and snippets.

@cloverstd
Created March 29, 2020 07:25

Revisions

  1. cloverstd created this gist Mar 29, 2020.
    100 changes: 100 additions & 0 deletions recover.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,100 @@
    function getParams() {
    const pairs = window.location.hash.substr(1).split('::');
    if (!pairs) {
    throw new Error('取不到参数');
    }
    return {
    sndId: pairs[1].split('=')[1],
    sndMagic: pairs[2].split('=')[1]
    };
    }

    function now() {
    return +new Date();
    }

    async function getEvents(marker) {
    const params = getParams();
    if (marker) {
    params['marker'] = marker;
    }
    const qs = new URLSearchParams();
    for (const key of Object.keys(params)) {
    qs.set(key, params[key]);
    }
    const response = await fetch(`https://www.jianguoyun.com/d/ajax/getEvents?${qs.toString()}`);
    if (response.status >= 400) {
    const data = await response.body();
    console.error(data);
    throw new Error(`get events failed: ${marker}, ${data}`);
    }
    return response.json();
    }

    async function unDoEvents({ opType, path, isdel, isdir, version }) {
    const formData = new URLSearchParams();
    formData.append('optype', opType);
    formData.append('path', path);
    formData.append('deleted', isdel);
    formData.append('dir', isdir);
    formData.append('version', version);
    const params = getParams();
    const response = await fetch(
    `https://www.jianguoyun.com/d/ajax/fileops/undoEvents?sndId=${params.sndId}&sndMagic=${params.sndMagic}`,
    {
    method: 'POST',
    body: formData.toString(),
    headers: {
    'Content-Type': 'application/x-www-form-urlencoded'
    }
    }
    );
    if (response.status >= 400) {
    const data = await response.json();
    if (response.status === 403) {
    if (data.errorCode === 'DirectoryNotEmpty') {
    // 如果是新增,并且文件夹为空时,就是这个错误,一般情况下可以忽略
    return;
    }
    }
    console.error(JSON.stringify(data));
    throw new Error(`unDoEvents error: ${JSON.stringify(data)}`);
    }
    }

    async function recover() {
    const startTs = +new Date(prompt('请输入要恢复的开始时间,时间格式示例:2020-12-12 2:22:22'));
    const endTs = +new Date(prompt('请输入要恢复的目标时间,时间格式示例:2020-12-12 03:03:03'));
    const editorAccount = prompt('请输入要恢复的操作人的邮箱');
    if (
    !confirm(
    `将会开始恢复下列信息,${new Date(endTs)}${new Date(startTs)} 时间内 ${
    editorAccount ? editorAccount : '任意操作人'
    } 的操作 `
    )
    ) {
    return;
    }
    let marker, events;
    ({ marker, events } = await getEvents());
    while (true) {
    console.log(`marker: ${marker}`);
    for (const event of events) {
    if (event.timestamp > startTs) {
    console.log('未到操作时间,跳过');
    continue;
    }
    if (editorAccount && editorAccount !== event.editorAccount) {
    console.log(`操作人 ${event.editorAccount} 不是目标操作人 ${editorAccount},跳过`);
    continue
    }
    if (event.timestamp < endTs) {
    console.log('finish');
    return;
    }
    console.log(`event: ${event.id} ${event.opType}, ${event.path}, ${new Date(event.timestamp)}`);
    await unDoEvents(event);
    }
    ({ marker, events } = await getEvents(marker));
    }
    }