Skip to content

Commit

Permalink
Merge pull request #11 from No1412lee/leezl
Browse files Browse the repository at this point in the history
Merge
  • Loading branch information
yangkghjh authored Nov 25, 2023
2 parents f708e75 + 2d096ef commit d971c37
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 57 deletions.
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
node_modules
config.js
/node_modules/
/config.json

files*
37 changes: 27 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,33 @@
- 思维导图
- 幻灯片

## Usage
## Usage with exe

1. 下载 shimoExporter.exe
2. 下载 config.example.json, 并重命名为 config.json
3. 在浏览器中登录石墨文档, 并使用 F12(开发者模式) 获取网页 Cookie
4. 将网页 Cookie 粘贴到 config.json 的"Cookie"字段中
5. 修改 config.json 的"Path"字段为导出文档的保存路径
6. 运行 shimoExporter.exe

## Usage with NodeJS

填写配置文件

```shell
cp config.example.js config.js
cp config.example.json config.json
```

```js
export const config = {
Cookie: 'xxx', // 从浏览器中获取石墨文档的 Cookie
Path: 'files', // 存放导出文档的位置
Folder: '', // 需要导出的文件夹 ID,从浏览器地址栏获取,https://shimo.im/folder/xxx 中 xxx,全部导出则留空
Recursive: false, // 是否导出子目录
Sleep: 1000 // 导出两个文档间的时间间隔,必须设置,否则会服务器忙,单位 ms
};
```config.json
{
"@Cookie": "从浏览器中获取石墨文档的 Cookie",
"@Path": "存放导出文档的位置",
"@Folder": "需要导出的文件夹 ID,从浏览器地址栏获取,https://shimo.im/folder/xxx 中 xxx,全部导出则留空",
"@Recursive": "是否导出子目录",
"@Sleep": "导出两个文档间的时间间隔,必须设置,否则会服务器忙,单位 ms",
"@Lasttime": "timeship you copy file(run this tool) last time, default 0 means to copy all files this time.",
"@Retry": "重试次数",
}
```

安装依赖
Expand All @@ -37,6 +48,12 @@ yarn // or npm install
node index.js
```

导出可执行文件

```shell
npm run build
```

## 依赖

```
Expand Down
9 changes: 0 additions & 9 deletions config.example.js

This file was deleted.

16 changes: 16 additions & 0 deletions config.example.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"@Cookie": "从浏览器中获取石墨文档的 Cookie",
"Cookie": "xxx",
"@Path": "存放导出文档的位置",
"Path": "F:/shimoExport/Export",
"@Folder": "需要导出的文件夹 ID,从浏览器地址栏获取,https://shimo.im/folder/xxx 中 xxx,全部导出则留空",
"Folder": "",
"@Recursive": "是否导出子目录",
"Recursive": true,
"@Sleep": "导出两个文档间的时间间隔,必须设置,否则会服务器忙,单位 ms",
"Sleep": 500,
"@Lasttime": "timeship you copy file(run this tool) last time, default 0 means to copy all files this time.",
"Lasttime": 0,
"@Retry": "重试次数",
"Retry": 3
}
107 changes: 71 additions & 36 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,35 @@ const axios = require('axios');
const Path = require('path');
const download = require('download');
const sleep = require('await-sleep');
const config = require('./config.js');
const fs = require('fs');
let config = {};
let fileData = fs.readFileSync('config.json', 'utf8');
try {
config = JSON.parse(fileData);
// console.log('config: ', config);
console.log('Path: ', config.Path);
console.log('Folder: ', config.Folder);
} catch (err) {
console.error('解析配置文件出错:', err);
}
// const config = require('./config.js');
const headersOptions = {
Cookie: config.Cookie,
Referer: 'https://shimo.im/folder/123',
};
const desktopHeadersOptions = {
Cookie: config.Cookie,
Referer: 'https://shimo.im/desktop',
};

getFileList(config.Folder, config.Path);

async function getFileList(folder = '', basePath = '') {
try {
const paramsOptions = folder ? { collaboratorCount: 'true', folder: folder } : { collaboratorCount: 'true' };
const response = await axios.get('https://shimo.im/lizard-api/files', {
params: { collaboratorCount: 'true', folder: folder },
headers: headersOptions
params: paramsOptions,
headers: folder ? headersOptions : desktopHeadersOptions
});

for (let i = 0; i < response.data.length; i++) {
Expand All @@ -29,15 +45,20 @@ async function getFileList(folder = '', basePath = '') {
// }
console.log(item.name, item.type, item.updatedAt);
if (item.is_folder != 1) {
for (let j = 1; j <= config.Retry; j++) {
const res = await createExportTask(item, basePath);
if (res != 0) {
let res = -1;
for (let j = 0; j <= config.Retry; j++) {
if (j > 0) {
console.error("retry " + j + " times...");
await sleep(config.Sleep * 2);
} else {
}
res = await createExportTask(item, basePath);
if (res == 0 || res == 1) {
break;
}
}
if (res != 0) {
console.error('[Error] Failed to export: ' + item.name);
}
} else {
if (config.Recursive) {
await getFileList(item.guid, Path.join(basePath, item.name));
Expand All @@ -50,52 +71,66 @@ async function getFileList(folder = '', basePath = '') {
}
}
} catch (error) {
console.error(error);
console.error('[Error] ' + error);
}
}

async function createExportTask(item, basePath = '') {
try {
let type = '';
const name = replaceBadChar(item.name);
if (item.type == 'newdoc' || item.type == 'document') {
type = 'docx';
} else if (item.type == 'sheet' || item.type == 'mosheet' || item.type == 'spreadsheet') {
type = 'xlsx';
} else if (item.type == 'slide') {
type = 'pptx';
} else if (item.type == 'mindmap') {
type = 'xmind';
} else {
console.error('unsupport type: ' + item.type);
return 1;
let downloadUrl = '';
if (item.type == 'docx' || item.type == 'doc' ||
item.type == 'pptx' || item.type == 'ppt' ||
item.type == 'pdf')
{
downloadUrl = 'https://shimo.im/lizard-api/files/' + item.guid + '/download';
}
else
{
if (item.type == 'newdoc' || item.type == 'document' || item.type == 'modoc') {
type = 'docx';
} else if (item.type == 'sheet' || item.type == 'mosheet' || item.type == 'spreadsheet') {
type = 'xlsx';
} else if (item.type == 'slide' || item.type == 'presentation') {
type = 'pptx';
} else if (item.type == 'mindmap') {
type = 'xmind';
} else {
console.error('[Error] ' + item.name + ' has unsupported type: ' + item.type);
return 1;
}

const url = 'https://shimo.im/lizard-api/files/' + item.guid + '/export';
const url = 'https://shimo.im/lizard-api/files/' + item.guid + '/export';

const response = await axios.get(url, {
params: {
type: type,
file: item.guid,
returnJson: '1',
name: name,
isAsync: '0'
},
headers: headersOptions
});
const response = await axios.get(url, {
params: {
type: type,
file: item.guid,
returnJson: '1',
name: name,
isAsync: '0'
},
headers: headersOptions
});

// console.log(name, response.data)
// console.log(response.data.redirectUrl, Path.join(config.Path, basePath));
if (!response.data.redirectUrl) {
console.error(item.name + ' failed, error: ', response.data);
//console.log(name, response.data)
// console.log(response.data.redirectUrl, Path.join(config.Path, basePath));
downloadUrl = response.data.redirectUrl;
if (!downloadUrl) {
downloadUrl = response.data.data.downloadUrl;
}
}
if (!downloadUrl) {
console.error('[Error] ' + item.name + ' failed, error: ', response.data);
return 2;
}
const options = {
headers: headersOptions
};
await download(response.data.redirectUrl, basePath, options);
await download(downloadUrl, basePath, options);
} catch (error) {
console.error(item.name + ' failed, error: ' + error.message);
console.error('[Error] ' + item.name + ' failed, error: ' + error.message);
return 3;
}
return 0;
Expand Down
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
"name": "shimo",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"build": "pkg index.js --output shimoExporter"
},
"license": "MIT",
"dependencies": {
"await-sleep": "^0.0.1",
Expand Down

0 comments on commit d971c37

Please sign in to comment.