From f7944c6d0f84b00229b0749db43318fa1722cbf5 Mon Sep 17 00:00:00 2001 From: lizelin Date: Mon, 13 Nov 2023 17:34:48 +0800 Subject: [PATCH 1/5] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=90=8E=E7=BC=80?= =?UTF-8?q?=E4=B8=BAdocx=E3=80=81pptx=E7=9A=84=E4=B8=8B=E8=BD=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.js | 65 +++++++++++++++++++++++++++++++++----------------------- 1 file changed, 39 insertions(+), 26 deletions(-) diff --git a/index.js b/index.js index c21f8e0..8472465 100644 --- a/index.js +++ b/index.js @@ -58,42 +58,55 @@ 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') + { + 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') { + type = 'pptx'; + } else if (item.type == 'mindmap') { + type = 'xmind'; + } else { + console.error('unsupport 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.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(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); return 3; From 8ce1b5a227d658271e51864714644d3266e23cfd Mon Sep 17 00:00:00 2001 From: leezl0828 Date: Thu, 23 Nov 2023 17:09:02 +0800 Subject: [PATCH 2/5] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=9B=B4=E6=8E=A5?= =?UTF-8?q?=E5=AF=BC=E5=87=BA=E6=A0=B9=E7=9B=AE=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config.example.js | 4 ++-- index.js | 9 +++++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/config.example.js b/config.example.js index 027a2b6..efea55d 100644 --- a/config.example.js +++ b/config.example.js @@ -1,8 +1,8 @@ module.exports = { Cookie: 'xxx', // 从浏览器中获取石墨文档的 Cookie - Path: 'files', // 存放导出文档的位置 + Path: 'F:/shimoExport', // 存放导出文档的位置 Folder: '', // 需要导出的文件夹 ID,从浏览器地址栏获取,https://shimo.im/folder/xxx 中 xxx,全部导出则留空 - Recursive: false, // 是否导出子目录 + Recursive: true, // 是否导出子目录 Sleep: 1000, // 导出两个文档间的时间间隔,必须设置,否则会服务器忙,单位 ms Lasttime: 0, // timeship you copy file(run this tool) last time, default 0 means to copy all files this time. Retry: 3 // 重试次数 diff --git a/index.js b/index.js index 8472465..13d9972 100644 --- a/index.js +++ b/index.js @@ -7,14 +7,19 @@ 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++) { From 55f2181762388b171f89aa17412c94d31bfed88f Mon Sep 17 00:00:00 2001 From: leezl0828 Date: Thu, 23 Nov 2023 17:54:52 +0800 Subject: [PATCH 3/5] =?UTF-8?q?=E6=94=AF=E6=8C=81pdf=EF=BC=8C=E9=81=87?= =?UTF-8?q?=E5=88=B0=E4=B8=8D=E6=94=AF=E6=8C=81=E7=B1=BB=E5=9E=8B=E6=97=B6?= =?UTF-8?q?=E4=B8=8DRetry=EF=BC=8C=E9=BB=98=E8=AE=A4=E5=AF=BC=E5=87=BA?= =?UTF-8?q?=E6=97=B6=E9=97=B4=E9=97=B4=E9=9A=94=E6=94=B9=E4=B8=BA0.5s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config.example.js | 4 ++-- index.js | 26 ++++++++++++++++---------- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/config.example.js b/config.example.js index efea55d..f81e130 100644 --- a/config.example.js +++ b/config.example.js @@ -1,9 +1,9 @@ module.exports = { Cookie: 'xxx', // 从浏览器中获取石墨文档的 Cookie - Path: 'F:/shimoExport', // 存放导出文档的位置 + Path: 'F:/shimoExport/Export', // 存放导出文档的位置 Folder: '', // 需要导出的文件夹 ID,从浏览器地址栏获取,https://shimo.im/folder/xxx 中 xxx,全部导出则留空 Recursive: true, // 是否导出子目录 - Sleep: 1000, // 导出两个文档间的时间间隔,必须设置,否则会服务器忙,单位 ms + Sleep: 500, // 导出两个文档间的时间间隔,必须设置,否则会服务器忙,单位 ms Lasttime: 0, // timeship you copy file(run this tool) last time, default 0 means to copy all files this time. Retry: 3 // 重试次数 }; diff --git a/index.js b/index.js index 13d9972..1661baa 100644 --- a/index.js +++ b/index.js @@ -34,15 +34,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)); @@ -55,7 +60,7 @@ async function getFileList(folder = '', basePath = '') { } } } catch (error) { - console.error(error); + console.error('[Error] ' + error); } } @@ -65,7 +70,8 @@ async function createExportTask(item, basePath = '') { const name = replaceBadChar(item.name); let downloadUrl = ''; if (item.type == 'docx' || item.type == 'doc' || - item.type == 'pptx' || item.type == 'ppt') + item.type == 'pptx' || item.type == 'ppt' || + item.type == 'pdf') { downloadUrl = 'https://shimo.im/lizard-api/files/' + item.guid + '/download'; } @@ -75,12 +81,12 @@ async function createExportTask(item, basePath = '') { type = 'docx'; } else if (item.type == 'sheet' || item.type == 'mosheet' || item.type == 'spreadsheet') { type = 'xlsx'; - } else if (item.type == 'slide') { + } else if (item.type == 'slide' || item.type == 'presentation') { type = 'pptx'; } else if (item.type == 'mindmap') { type = 'xmind'; } else { - console.error('unsupport type: ' + item.type); + console.error('[Error] ' + item.name + ' has unsupported type: ' + item.type); return 1; } @@ -105,7 +111,7 @@ async function createExportTask(item, basePath = '') { } } if (!downloadUrl) { - console.error(item.name + ' failed, error: ', response.data); + console.error('[Error] ' + item.name + ' failed, error: ', response.data); return 2; } const options = { @@ -113,7 +119,7 @@ async function createExportTask(item, basePath = '') { }; 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; From c1c9d363d7428b853fd462609f79a4c1064aab04 Mon Sep 17 00:00:00 2001 From: lizelin Date: Fri, 24 Nov 2023 17:30:46 +0800 Subject: [PATCH 4/5] =?UTF-8?q?=E6=94=B9=E7=94=A8json=E4=BD=9C=E4=B8=BA?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6=EF=BC=8C=E5=AF=BC=E5=87=BA?= =?UTF-8?q?exe?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 4 ++-- README.md | 26 +++++++++++++++++--------- config.example.js | 9 --------- config.example.json | 16 ++++++++++++++++ index.js | 13 ++++++++++++- package.json | 3 +++ 6 files changed, 50 insertions(+), 21 deletions(-) delete mode 100644 config.example.js create mode 100644 config.example.json diff --git a/.gitignore b/.gitignore index dcefdef..1b44f68 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -node_modules -config.js +/node_modules/ +/config.json files* diff --git a/README.md b/README.md index 2b3f36b..26b4e05 100644 --- a/README.md +++ b/README.md @@ -12,17 +12,19 @@ 填写配置文件 ```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": "重试次数", +} ``` 安装依赖 @@ -37,6 +39,12 @@ yarn // or npm install node index.js ``` +导出可执行文件 + +```shell +npm run build +``` + ## 依赖 ``` diff --git a/config.example.js b/config.example.js deleted file mode 100644 index f81e130..0000000 --- a/config.example.js +++ /dev/null @@ -1,9 +0,0 @@ -module.exports = { - Cookie: 'xxx', // 从浏览器中获取石墨文档的 Cookie - Path: 'F:/shimoExport/Export', // 存放导出文档的位置 - Folder: '', // 需要导出的文件夹 ID,从浏览器地址栏获取,https://shimo.im/folder/xxx 中 xxx,全部导出则留空 - Recursive: true, // 是否导出子目录 - Sleep: 500, // 导出两个文档间的时间间隔,必须设置,否则会服务器忙,单位 ms - Lasttime: 0, // timeship you copy file(run this tool) last time, default 0 means to copy all files this time. - Retry: 3 // 重试次数 -}; diff --git a/config.example.json b/config.example.json new file mode 100644 index 0000000..c994a4d --- /dev/null +++ b/config.example.json @@ -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 +} diff --git a/index.js b/index.js index 1661baa..8be6208 100644 --- a/index.js +++ b/index.js @@ -2,7 +2,18 @@ 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', diff --git a/package.json b/package.json index 95b11cb..4c6c764 100644 --- a/package.json +++ b/package.json @@ -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", From 2d096ef21e47d2bd32f5b3d0dc8062a338a16c0c Mon Sep 17 00:00:00 2001 From: lizelin Date: Fri, 24 Nov 2023 17:31:27 +0800 Subject: [PATCH 5/5] =?UTF-8?q?=E6=B7=BB=E5=8A=A0shimoExporter.exe?= =?UTF-8?q?=E7=9A=84=E4=BD=BF=E7=94=A8=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 26b4e05..0de37f2 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,16 @@ - 思维导图 - 幻灯片 -## 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 填写配置文件