Skip to content

Commit 14537c9

Browse files
committed
refactor: optimize generate-data script
1 parent 8630ef9 commit 14537c9

File tree

3 files changed

+121
-55
lines changed

3 files changed

+121
-55
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
node_modules
22
miniprogram_npm
3-
package-lock.json
3+
package-lock.json
4+
/config.js

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,10 @@
2424
"marked": "^4.0.12"
2525
},
2626
"devDependencies": {
27+
"axios": "^0.26.1",
28+
"cli-progress": "^3.10.0",
2729
"commonmark": "^0.30.0",
30+
"form-data": "^4.0.0",
2831
"md5": "^2.3.0"
2932
}
3033
}

script/index.js

Lines changed: 116 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -4,65 +4,70 @@ const glob = require('glob')
44
const {marked} = require('marked')
55
const MagicString = require('magic-string')
66
const md5 = require('md5')
7+
const axios = require('axios')
8+
const FormData = require('form-data');
9+
const cliProgress = require('cli-progress');
710

8-
const flattenToken = (token) => {
9-
const { type, tokens, text, href } = token
10-
switch(type) {
11-
case 'list':
12-
const items = token.items.map(item => flattenToken(item))
13-
return { type, items }
14-
case 'list_item':
15-
if (tokens.length == 1 && tokens[0].tokens.length == 1) {
16-
const final = tokens[0].tokens[0];
17-
return final.type == 'text' ? text : flattenToken(final);
18-
}
19-
if (tokens.length == 1) {
20-
return flattenToken(tokens[0])
21-
}
22-
// console.log(token);
23-
return tokens.map(item => flattenToken(item))
24-
case 'row':
25-
return { type, row: token.rows }
26-
case 'text':
27-
case 'paragraph':
28-
if (!tokens) return text
29-
if (tokens.length == 1) {
30-
return tokens[0].type == 'text' ? text : flattenToken(tokens[0])
31-
}
32-
return tokens.map(item => flattenToken(item))
33-
case 'strong':
34-
case 'codespan':
35-
case 'em':
36-
return { type, text }
37-
case 'html':
38-
const ans = /<img.+src="([\w\.\/-]+)"/.exec(text)
39-
if (ans) {
40-
return { type: 'image', href: ans[1], text: '图片' }
41-
}
42-
return ''
43-
case 'image':
44-
// todo upload image
45-
// token.href
46-
return { type, text, href }
47-
case 'link':
48-
return { type, text, href }
49-
case 'space':
50-
return ''
51-
case 'blockquote':
52-
return text
53-
default:
54-
console.log(token)
11+
const config = require('../config')
12+
13+
const bar = new cliProgress.SingleBar({}, cliProgress.Presets.shades_classic);
14+
15+
let accessToken = ''
16+
const getAccessToken = async() => {
17+
if (accessToken) return accessToken
18+
19+
const { data } = await axios.get('https://api.weixin.qq.com/cgi-bin/token', {
20+
params: {
21+
grant_type: 'client_credential',
22+
appid: config.appid,
23+
secret: config.secret
24+
}
25+
})
26+
if (data.access_token) {
27+
accessToken = data.access_token
28+
return accessToken
5529
}
56-
return token
30+
throw new TypeError(data)
5731
}
5832

59-
glob(path.resolve(__dirname, '../HowToCook/dishes/**/*.md'), {}, (err, files) => {
33+
34+
const uploadImage = async (filePath) => {
35+
const cloudPath = 'cookbook'
36+
const token = await getAccessToken()
37+
const url = 'https://api.weixin.qq.com/tcb/uploadfile?access_token=' + token
38+
const { data } = await axios.post(url, {
39+
env: config.cloudEnvId,
40+
path: cloudPath
41+
})
42+
if (data.errcode == 0) {
43+
const { url, token, authorization, file_id, cos_file_id} = data;
44+
const form = new FormData()
45+
46+
form.append('key', authorization);
47+
form.append('Signature', authorization);
48+
form.append('x-cos-security-token', token);
49+
form.append('x-cos-meta-fileid', cos_file_id);
50+
form.append('file', fs.createReadStream(filePath));
51+
52+
return new Promise((resolve, reject) => {
53+
form.submit(url, (err) => {
54+
if (err) reject(err)
55+
resolve(file_id.replace(cloudPath, '') + authorization)
56+
})
57+
})
58+
} else {
59+
throw new TypeError(data.errmsg)
60+
}
61+
}
62+
63+
glob(path.resolve(__dirname, '../HowToCook/dishes/**/*.md'), {}, async (err, files) => {
6064
if (err) {
6165
console.log(err)
6266
}
6367
const dishes = []
6468
let no = 0
6569

70+
bar.start(files.length, 0);
6671
for(let p of files) {
6772
const { name, dir } = path.parse(p)
6873
const [ ,category ] = /dishes\/([\w-]+)\//g.exec(p)
@@ -75,14 +80,68 @@ glob(path.resolve(__dirname, '../HowToCook/dishes/**/*.md'), {}, (err, files) =>
7580
detail: [],
7681
desc: []
7782
}
83+
const flattenToken = async (token) => {
84+
const { type, tokens, text, href } = token
85+
switch(type) {
86+
case 'list':
87+
const items = await Promise.all(token.items.map(async item => await flattenToken(item)))
88+
return { type, items }
89+
case 'list_item':
90+
if (tokens.length == 1 && tokens[0].tokens.length == 1) {
91+
const final = tokens[0].tokens[0];
92+
return final.type == 'text' ? text : await flattenToken(final);
93+
}
94+
if (tokens.length == 1) {
95+
return await flattenToken(tokens[0])
96+
}
97+
// console.log(token);
98+
return await Promise.all(tokens.map(async item => await flattenToken(item)))
99+
case 'row':
100+
return { type, row: token.rows }
101+
case 'text':
102+
case 'paragraph':
103+
if (!tokens) return text
104+
if (tokens.length == 1) {
105+
return tokens[0].type == 'text' ? text : await flattenToken(tokens[0])
106+
}
107+
return await await Promise.all(tokens.map(async item => await flattenToken(item)))
108+
case 'strong':
109+
case 'codespan':
110+
case 'em':
111+
return { type, text }
112+
case 'html':
113+
const ans = /<img.+src="([\w\.\/-]+)"/.exec(text)
114+
if (ans) {
115+
const data = await uploadImage(path.resolve(dir, ans[1]))
116+
return { type: 'image', href: data, text: '图片' }
117+
}
118+
return ''
119+
case 'image':
120+
// todo upload image
121+
// token.href
122+
const data = await uploadImage(path.resolve(dir, href))
123+
return { type, text, href: data }
124+
case 'link':
125+
return { type, text, href }
126+
case 'space':
127+
return ''
128+
case 'blockquote':
129+
return text
130+
default:
131+
console.log(token)
132+
}
133+
return token
134+
}
78135

79136
no++;
80137
target = null;
81138

82-
marked.lexer(content, {
139+
const tokens = marked.lexer(content, {
83140
baseUrl: dir,
84141
xhtml: true
85-
}).forEach((token) => {
142+
});
143+
144+
for (let token of tokens) {
86145
const { text, type, depth } = token;
87146

88147
if (type == 'heading') {
@@ -105,15 +164,18 @@ glob(path.resolve(__dirname, '../HowToCook/dishes/**/*.md'), {}, (err, files) =>
105164
}
106165
} else if (type !== 'space') {
107166
if (target == null) {
108-
menu.desc.push(flattenToken(token))
167+
menu.desc.push(await flattenToken(token))
109168
} else {
110-
const tmp = flattenToken(token)
169+
const tmp = await flattenToken(token)
111170
target.push(tmp)
112171
}
113172
}
114-
})
173+
}
174+
bar.update(no)
115175
dishes.push(menu)
116176
}
177+
178+
bar.stop()
117179

118180
const jsonData = new MagicString('');
119181
const s = new MagicString(JSON.stringify(dishes, null, 2))

0 commit comments

Comments
 (0)