-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathweread.cjs
281 lines (269 loc) · 9.05 KB
/
weread.cjs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
const fs = require('fs')
const path = require('path')
const cheerio = require('cheerio')
const {pinyin} = require('pinyin')
const wereadConfig = require('./weread.config.cjs')
function zhToPinyin(zh) {
return pinyin(zh, {
style: pinyin.STYLE_NORMAL,
}).join('')
}
/**
* 批量解析微信读书笔记html,并转换成对应的vue文件
*/
/**
* 实现思路
* 1、遍历src下的所有文件并解析,找到src/*.html, 解析其文件名,在当前目录找到其对应的子目录(资源文件)
* 3、获取html内容(id为js_content)的内容,获取对应子目录(资源文件)下所有的图片
* 4、将内容追加到html模版里,并写到dist下
* 5、拷贝对应的资源文件至dist下
* 6、clean 删除 src下已经处理过的源文件及其依赖的资源文件
* @type {string}
*/
const filePath = wereadConfig.src //path.resolve(__dirname + '/data/');
const fileWhiteList = ['html', 'jpg']
/**
* 根据文件路径获取文件后缀(文件类型)
* @param filePath
* @returns {string}
*/
function getFileExt(filePath) {
//获取最后一个.的位置
let index = filePath.lastIndexOf('.')
//获取后缀
return filePath.substr(index + 1)
}
// 递归创建目录 异步方法
// function mkdirs(dirname, callback) {
// fs.exists(dirname, function (exists) {
// if (exists) {
// callback();
// } else {
// // console.log(path.dirname(dirname));
// mkdirs(path.dirname(dirname), function () {
// fs.mkdir(dirname, callback);
// console.log('在' + path.dirname(dirname) + '目录创建好' + dirname +'目录');
// });
// }
// });
// }
/**
* 递归创建目录 同步方法
* @param dirname
* @returns {boolean}
*/
function mkdirsSync(dirname) {
if (fs.existsSync(dirname)) {
return true
} else {
if (mkdirsSync(path.dirname(dirname))) {
fs.mkdirSync(dirname)
return true
}
}
}
/**
* 递归删除文件夹及其下子目录
* @param filePath
* @param callback
*/
function rmdir(filePath, callback) {
// 先判断当前filePath的类型(文件还是文件夹,如果是文件直接删除, 如果是文件夹, 去取当前文件夹下的内容, 拿到每一个递归)
fs.stat(filePath, function (err, stat) {
if (err) return console.log(err)
if (stat.isFile()) {
fs.unlink(filePath, callback)
} else {
fs.readdir(filePath, function (err, data) {
if (err) return console.log(err)
let dirs = data.map(dir => path.join(filePath, dir))
let index = 0
!(function next() {
// 此处递归删除掉所有子文件 后删除当前 文件夹
if (index === dirs.length) {
fs.rmdir(filePath, callback)
} else {
rmdir(dirs[index++], next)
}
})()
})
}
})
}
let bookList = []
/**
*
* @param fileOrDirPath {String} 文件或文件夹路径
* @param fileDir {String} 文件或文件夹上级路径
* @param filename
* @param filePath
* @param isDir
* @param isFile
* @param dirLevel
* @param fileType
*/
async function parse(
fileOrDirPath,
{
fileDir, //文件所在文件夹
filename,
filePath, //文件绝对路径
isDir,
isFile,
dirLevel = 0,
fileType,
} = {}
) {
if (fileOrDirPath) {
let isDirDef = isDir // true || false 判断是不是文件夹
let isFileDef = isFile // true || false 判断是不是文件夹
if (!filePath) {
let lstatSync = fs.lstatSync(fileOrDirPath)
isDirDef = lstatSync.isDirectory()
isFileDef = lstatSync.isFile()
}
if (isDirDef) {
//根据文件路径读取文件,返回文件列表
fs.readdir(fileOrDirPath, function (err, files) {
if (err) {
console.warn(err)
} else {
//遍历读取到的文件列表
// console.log('files:', files)
dirLevel++
files.forEach(function (filename) {
//获取当前文件的绝对路径
const filePath = path.join(fileOrDirPath, filename)
const stat = fs.lstatSync(filePath)
const isDir = stat.isDirectory() // true || false 判断是不是文件夹
const isFile = stat.isFile() // true || false 判断是不是文件夹
//获取后缀
const fileType = getFileExt(filePath)
const encoding = 'utf-8'
const fileInfo = {
fileDir: fileOrDirPath,
filename,
filePath,
isDir,
isFile,
dirLevel,
fileType,
encoding,
}
if (isDir || (isFile && (fileWhiteList.includes(fileType) || fileType === filePath))) {
parse(filePath, fileInfo) //递归,如果是文件夹,就继续遍历该文件夹下面的文件
}
})
}
})
} else if (isFileDef) {
let fileList = filePath.split(wereadConfig.outRootDirName /*'data'*/)
fileList.splice(0, 1)
let fileDistDir = fileList.join(wereadConfig.outRootDirName /*'data'*/)
// mkdirsSync(wereadConfig.outputDir/*'./dist'*/ + fileDistDir.split(filename)[0])
console.log('filePath:' + filePath)
console.log('fileDistDir:' + fileDistDir)
console.log('fileType:' + fileType)
let imgName = ''
if (fileType === 'html' && dirLevel < 2) {
let file = fs.readFileSync(filePath, 'utf8')
let $ = cheerio.load(file)
let imgUrl = $('.wr_bookCover_img').attr('src')
console.log($('.wr_bookCover_img').attr('src'))
imgName = imgUrl ? imgUrl.split('/').pop() : ''
let js_content = $('.readerNoteList').html()
if (!js_content) {
return false
}
js_content = js_content.replace(/<!---->/g, '')
let ary = fileDistDir.split('/')[1].split('.html')[0].split('-')
let bookName = ary[0]
let author = ary[1]
console.log('bookName:' + bookName)
console.log('author:' + author)
let bookNamePinyin = zhToPinyin(bookName)
bookNamePinyin = bookNamePinyin.replace(/:/g, '')
let newVue = `<template>
<div class="container">
<h1 class="title">${bookName}</h1>
<h5 class="author">${author}</h5>
<img src="./img/${bookNamePinyin}/${imgName}" alt="written" class="written">
<div class="wr_macOS wr_Desktop wr_page_reader wr_whiteTheme">
${js_content}
</div>
<!-- <footer class="footer">-->
<!-- <img src="./img/${bookNamePinyin}/qr.png" alt="qr">-->
<!-- <p>扫码阅读本书</p>-->
<!-- </footer>-->
</div>
</template>
<script>
export default {
name: '${bookNamePinyin}'
}
</script>
<style lang="scss" scoped>
@import '~@/assets/css/weread.css';
@import '~@/assets/scss/readnotes';
</style>`
let vueFile = fileDistDir
.replace('.html', '.vue')
.replace('-微信读书', '')
.replace('-' + author, '')
.replace(/:/g, '')
console.log('vueFile:' + vueFile)
vueFile = zhToPinyin(vueFile)
fs.writeFile(wereadConfig.outputDir /*'./dist'*/ + vueFile, newVue, 'utf8', function (err) {
if (err) return console.log(err)
bookList.push({
bookImg: bookNamePinyin + '/written.jpg',
author: author,
bookName: bookName,
bookUrl: '/read-notes/' + bookNamePinyin,
})
})
} else {
if (fileWhiteList.includes(fileType)) {
let file = fs.readFileSync(filePath, 'binary')
console.log('file:' + fileDistDir)
let dirName = fileDistDir.split('/')[1]
let imgFile = fileDistDir.replace(dirName, 'img')
let bookName = dirName.split('-')[0]
let bookNamePinyin = zhToPinyin(bookName)
bookNamePinyin = bookNamePinyin.replace(/:/g, '')
console.log('bookNamePinyin:' + bookNamePinyin)
console.log('imgFile:' + imgFile)
let imgName = imgFile.split('/').pop()
// await mkdirsSync('./dist/img/'+ bookNamePinyin)
console.log('imgName:' + imgName)
await mkdirsSync(wereadConfig.outputDir + '/img/' + bookNamePinyin)
try {
//同步写入文件
let fileSrc = wereadConfig.outputDir + '/img/' + bookNamePinyin + '/' + imgName
console.log('fileSrc:' + fileSrc)
fs.writeFileSync(fileSrc, file, 'binary')
} catch (err) {
console.error(err)
}
}
}
}
}
}
mkdirsSync(wereadConfig.outputDir /*'./dist'*/)
rmdir(wereadConfig.outputDir + '/' /*'./dist/'*/, function () {
console.log('dist删除成功')
mkdirsSync(wereadConfig.outputDir + '/img' /*./dist/img*/)
console.log('mkdirsSync ' + wereadConfig.outputDir + '/img success')
console.log('parsing...')
parse(filePath)
setTimeout(function () {
console.log('bookList:')
console.log(bookList)
// const oldBookList = require('./src/views/ReadNotes/bookList.json')
// let file = `export default =
// ${JSON.stringify(oldBookList.concat(bookList))}`
// console.log(file)
// const data = fs.writeFileSync(__dirname+'/src/views/ReadNotes/bookList.js', file, 'binary')
}, 3000)
})