Skip to content

Commit

Permalink
Merge pull request #13 from webkong/master
Browse files Browse the repository at this point in the history
feat: Update or skip based on local documentation
  • Loading branch information
yangkghjh authored Dec 17, 2023
2 parents d971c37 + 4d1148d commit 55f1588
Show file tree
Hide file tree
Showing 6 changed files with 3,138 additions and 346 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@
/config.json

files*
.vscode
shimo
config*.json
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,19 @@ node index.js
npm run build
```

导出 markdown 文档

如果想导出 markdown 文档,将`index.js``type = 'docx'` 改为 `type = 'md'`即可

多配置文件

如果有多个目录需要导出,可以配置多个配置文件。运行时指定配置文件即可。

```shell
# config-xx.json
node index.js -c config-xx.json
```

## 依赖

```
Expand Down
295 changes: 185 additions & 110 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,141 +3,216 @@ const Path = require('path');
const download = require('download');
const sleep = require('await-sleep');
const fs = require('fs');
const fse = require('fs-extra');
let config = {};
let fileData = fs.readFileSync('config.json', 'utf8');
let fileData = '';
// 读取node命令行参数
const args = process.argv.splice(2);

if (args[1]) {
fileData = fs.readFileSync(args[1], 'utf8');
} else {
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);
config = JSON.parse(fileData);
console.log('config: ', config);
} catch (err) {
console.error('解析配置文件出错:', err);
console.error('解析配置文件出错:', err);
}
// const config = require('./config.js');
const headersOptions = {
Cookie: config.Cookie,
Referer: 'https://shimo.im/folder/123',
Cookie: config.Cookie,
Referer: 'https://shimo.im/folder/123',
};
const desktopHeadersOptions = {
Cookie: config.Cookie,
Referer: 'https://shimo.im/desktop',
Cookie: config.Cookie,
Referer: 'https://shimo.im/desktop',
};

const localFileLists = getLocalFileList(Path.join(config.Path));
// console.log('🚀 ~ file: index.js:27 ~ localFileLists:', localFileLists);
localStr = localFileLists.join('');

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: paramsOptions,
headers: folder ? headersOptions : desktopHeadersOptions
});
try {
const paramsOptions = folder
? { collaboratorCount: 'true', folder: folder }
: { collaboratorCount: 'true' };
const response = await axios.get('https://shimo.im/lizard-api/files', {
params: paramsOptions,
headers: folder ? headersOptions : desktopHeadersOptions,
});

for (let i = 0; i < response.data.length; i++) {
await sleep(config.Sleep);
let item = response.data[i];
let atime = new Date(item.updatedAt).getTime();
//console.log(atime);
if (atime > config.Lasttime) {
//console.log('i love you baby!');
//if(item.updatedAt == '2021-10-20T09:52:40.000Z'){
//console.log(item.updatedAt,'chenggonglelelelelelelelelelel');
// }
console.log(item.name, item.type, item.updatedAt);
if (item.is_folder != 1) {
let res = -1;
for (let j = 0; j <= config.Retry; j++) {
if (j > 0) {
console.error("retry " + j + " times...");
await sleep(config.Sleep * 2);
}
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));
}
}
// process.exit();
for (let i = 0; i < response.data.length; i++) {
let item = response.data[i];
let atime = new Date(item.updatedAt).getTime();
if (atime > config.Lasttime) {
if (item.is_folder != 1) {
// console.log(item.name, item.type, item.updatedAt);
const name = item.name;
const type = getType(item);
const localFilePath = Path.join(basePath, `${name}.${type}`);
// 如果type为1,表示不支持导出,跳过
if (type === 1) {
continue;
}
// 判断本地是否存在
if (localStr.indexOf(localFilePath) > -1) {
const stat = fs.statSync(localFilePath);
// 本地文件更新时间小于石墨文件更新时间
if (new Date(item.updated_at).getTime() > new Date(stat.ctime).getTime()) {
console.log('更新:', localFilePath);
} else {
console.log('the end');
process.exit();
console.log('跳过:', localFilePath);
continue;
}
}
await sleep(config.Sleep);

let res = -1;
for (let j = 0; j <= config.Retry; j++) {
if (j > 0) {
console.error('retry ' + j + ' times...');
await sleep(config.Sleep * 2);
}
res = await createExportTask(item, basePath);
console.log('开始下载:', localFilePath);
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));
}
}
} catch (error) {
console.error('[Error] ' + error);
} else {
console.log('the end');
process.exit();
}
}
} catch (error) {
console.error('[Error] ' + error);
}
}

async function createExportTask(item, basePath = '') {
try {
let type = '';
const name = replaceBadChar(item.name);
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;
}
try {
let type = '';
const name = replaceBadChar(item.name);
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 {
type = getType(item);

const url = 'https://shimo.im/lizard-api/files/' + item.guid + '/export';
const url = 'https://shimo.im/lizard-api/files/' + item.guid + '/export';
// https://shimo.im/lizard-api/office-gw/files/export?fileGuid=2wAldGvJNGFbl9AP&type=md

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));
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(downloadUrl, basePath, options);
} catch (error) {
console.error('[Error] ' + item.name + ' failed, error: ' + error.message);
return 3;
//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;
}
return 0;
const options = {
headers: headersOptions,
};
await download(downloadUrl, basePath, options);
} catch (error) {
console.error('[Error] ' + item.name + ' failed, error: ' + error.message);
return 3;
}
return 0;
}

function replaceBadChar(fileName) {
// 去掉文件名中的无效字符,如 \ / : * ? " < > |
fileName = fileName.replace(/[\'\"\\\/\b\f\n\r\t]/g, '_');
return fileName;
// 去掉文件名中的无效字符,如 \ / : * ? " < > |
fileName = fileName.replace(/[\'\"\\\/\b\f\n\r\t]/g, '_');
return fileName;
}

function getType(item) {
let type = '';
const normalType = ['docx', 'doc', 'pptx', 'ppt', 'pdf'];
if (normalType.indexOf(item.type) > -1) {
return item.type;
}

if (item.type == 'newdoc' || item.type == 'document' || item.type == 'modoc') {
type = 'md'; //如果想导出word文档,将type改成 docx
} else if (
item.type == 'sheet' ||
item.type == 'mosheet' ||
item.type == 'spreadsheet' ||
item.type == 'table'
) {
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;
}
return type;
}

// 获取本地文件列表
function getLocalFileList(dirPath) {
try {
let filesPath = [];
const getFile = (dir) => {
fse.ensureDirSync(dir);
const files = fs.readdirSync(dir);
for (let i = 0; i < files.length; i++) {
const file = files[i];
// 过滤隐藏文件
if (/^\./.test(file)) {
continue;
}
//拼接获取路径
let subPath = Path.join(dir, file);
let stat = fs.statSync(subPath);
if (stat.isFile()) {
filesPath.push(subPath);
} else {
getFile(subPath);
}
}
};
getFile(dirPath);
return filesPath;
} catch (err) {
console.log(err);
}
}
Loading

0 comments on commit 55f1588

Please sign in to comment.