Created
March 29, 2020 07:25
-
-
Save cloverstd/fbf26c2ee96ca70e4e23cc5417d0065c to your computer and use it in GitHub Desktop.
坚果云恢复文件
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment