Skip to content

Instantly share code, notes, and snippets.

@cloverstd
Created March 29, 2020 07:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cloverstd/fbf26c2ee96ca70e4e23cc5417d0065c to your computer and use it in GitHub Desktop.
Save cloverstd/fbf26c2ee96ca70e4e23cc5417d0065c to your computer and use it in GitHub Desktop.
坚果云恢复文件
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