picgo-plugin-gitee 2.0.4 → 2.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/readme.md +4 -0
- package/src/index.js +163 -155
package/package.json
CHANGED
package/readme.md
CHANGED
package/src/index.js
CHANGED
|
@@ -1,182 +1,190 @@
|
|
|
1
|
-
|
|
2
|
-
const
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
const defaultMsg = 'picgo commit'
|
|
1
|
+
const uploadedName = "gitee";
|
|
2
|
+
const domain = "https://gitee.com";
|
|
3
|
+
const urlParser = require("url");
|
|
4
|
+
const defaultMsg = "picgo commit";
|
|
6
5
|
|
|
7
6
|
module.exports = (ctx) => {
|
|
8
7
|
const register = () => {
|
|
9
8
|
ctx.helper.uploader.register(uploadedName, {
|
|
10
9
|
handle,
|
|
11
|
-
name:
|
|
12
|
-
config: config
|
|
13
|
-
})
|
|
10
|
+
name: "Gitee图床",
|
|
11
|
+
config: config,
|
|
12
|
+
});
|
|
14
13
|
|
|
15
|
-
ctx.on(
|
|
16
|
-
}
|
|
14
|
+
ctx.on("remove", onRemove);
|
|
15
|
+
};
|
|
17
16
|
|
|
18
17
|
const getHeaders = function () {
|
|
19
18
|
return {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
}
|
|
19
|
+
"Content-Type": "application/json;charset=UTF-8",
|
|
20
|
+
};
|
|
21
|
+
};
|
|
24
22
|
|
|
25
23
|
const getUserConfig = function () {
|
|
26
|
-
let userConfig = ctx.getConfig(
|
|
24
|
+
let userConfig = ctx.getConfig("picBed.gitee");
|
|
27
25
|
|
|
28
26
|
if (!userConfig) {
|
|
29
|
-
throw new Error(
|
|
27
|
+
throw new Error("Can't find uploader config");
|
|
30
28
|
}
|
|
31
29
|
|
|
32
|
-
userConfig[
|
|
33
|
-
|
|
30
|
+
userConfig["baseUrl"] =
|
|
31
|
+
domain + "/api/v5/repos/" + userConfig.owner + "/" + userConfig.repo;
|
|
32
|
+
userConfig["previewUrl"] =
|
|
33
|
+
domain +
|
|
34
|
+
"/" +
|
|
35
|
+
userConfig.owner +
|
|
36
|
+
"/" +
|
|
37
|
+
userConfig.repo +
|
|
38
|
+
"/raw/master" +
|
|
39
|
+
formatConfigPath(userConfig);
|
|
34
40
|
|
|
35
|
-
|
|
36
|
-
|
|
41
|
+
userConfig["message"] = userConfig.message || defaultMsg;
|
|
42
|
+
|
|
43
|
+
return userConfig;
|
|
44
|
+
};
|
|
37
45
|
|
|
38
46
|
// uploader
|
|
39
47
|
const handle = async function (ctx) {
|
|
40
|
-
let userConfig = getUserConfig()
|
|
48
|
+
let userConfig = getUserConfig();
|
|
41
49
|
|
|
42
|
-
const realUrl =
|
|
50
|
+
const realUrl =
|
|
51
|
+
userConfig.baseUrl + "/contents" + formatConfigPath(userConfig);
|
|
43
52
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
53
|
+
let imgList = ctx.output;
|
|
54
|
+
for (let i in imgList) {
|
|
55
|
+
let image = imgList[i].buffer;
|
|
56
|
+
if (!image && imgList[i].base64Image) {
|
|
57
|
+
image = Buffer.from(imgList[i].base64Image, "base64");
|
|
58
|
+
}
|
|
51
59
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
60
|
+
let perRealUrl = realUrl + "/" + imgList[i].fileName;
|
|
61
|
+
const postConfig = postOptions(perRealUrl, image);
|
|
62
|
+
|
|
63
|
+
try {
|
|
64
|
+
await ctx.Request.request(postConfig);
|
|
65
|
+
imgList[i]["imgUrl"] =
|
|
66
|
+
userConfig.previewUrl + "/" + imgList[i].fileName;
|
|
67
|
+
} catch (err) {
|
|
68
|
+
ctx.log.info("[上传操作]异常:" + err.message);
|
|
69
|
+
// duplicate file, so continue
|
|
70
|
+
if (checkIsDuplicateFile(err.message)) {
|
|
71
|
+
ctx.emit("notification", {
|
|
72
|
+
title: "上传失败",
|
|
73
|
+
body: "文件已经存在了",
|
|
74
|
+
});
|
|
75
|
+
continue;
|
|
76
|
+
} else {
|
|
77
|
+
ctx.emit("notification", {
|
|
78
|
+
title: "上传失败",
|
|
79
|
+
body: JSON.stringify(err),
|
|
80
|
+
});
|
|
81
|
+
}
|
|
61
82
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
ctx.emit('notification', {
|
|
67
|
-
title: '上传失败',
|
|
68
|
-
body: JSON.stringify(err)
|
|
69
|
-
})
|
|
83
|
+
|
|
84
|
+
delete imgList[i].base64Image;
|
|
85
|
+
delete imgList[i].buffer;
|
|
70
86
|
}
|
|
71
|
-
|
|
87
|
+
|
|
88
|
+
return ctx;
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
const checkIsDuplicateFile = (message) => {
|
|
92
|
+
return message.indexOf("A file with this name already exists") != -1;
|
|
93
|
+
};
|
|
72
94
|
|
|
73
95
|
const postOptions = (url, image) => {
|
|
74
|
-
let config = getUserConfig()
|
|
75
|
-
let headers = getHeaders()
|
|
96
|
+
let config = getUserConfig();
|
|
97
|
+
let headers = getHeaders();
|
|
76
98
|
let formData = {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
}
|
|
99
|
+
access_token: config.token,
|
|
100
|
+
content: image.toString("base64"),
|
|
101
|
+
message: config.message || defaultMsg,
|
|
102
|
+
};
|
|
81
103
|
const opts = {
|
|
82
|
-
method:
|
|
104
|
+
method: "POST",
|
|
83
105
|
url: encodeURI(url),
|
|
84
106
|
headers: headers,
|
|
85
|
-
formData: formData
|
|
86
|
-
}
|
|
87
|
-
return opts
|
|
88
|
-
}
|
|
107
|
+
formData: formData,
|
|
108
|
+
};
|
|
109
|
+
return opts;
|
|
110
|
+
};
|
|
89
111
|
|
|
90
112
|
// trigger delete file
|
|
91
113
|
const onRemove = async function (files) {
|
|
92
|
-
// log
|
|
93
|
-
const rms = files.filter(each => each.type === uploadedName)
|
|
114
|
+
// log request params
|
|
115
|
+
const rms = files.filter((each) => each.type === uploadedName);
|
|
94
116
|
if (rms.length === 0) {
|
|
95
|
-
return
|
|
96
|
-
}
|
|
97
|
-
const fail = []
|
|
98
|
-
for (let i = 0; i < rms.length; i++) {
|
|
99
|
-
const each = rms[i]
|
|
100
|
-
// delete gitee file
|
|
101
|
-
deleteFile(rms[i].imgUrl).catch((err) => {
|
|
102
|
-
ctx.log.info(JSON.stringify(err))
|
|
103
|
-
fail.push(each)
|
|
104
|
-
})
|
|
117
|
+
return;
|
|
105
118
|
}
|
|
106
119
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
120
|
+
ctx.log.info("删除个数:" + rms.length);
|
|
121
|
+
ctx.log.info("uploaded 信息:");
|
|
122
|
+
let headers = getHeaders();
|
|
123
|
+
let config = getUserConfig();
|
|
124
|
+
const fail = [];
|
|
112
125
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
return urlStr.replace('raw/master', 'contents')
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
// delete file
|
|
127
|
-
const deleteFile = async function (name) {
|
|
128
|
-
let headers = getHeaders()
|
|
129
|
-
let config = getUserConfig()
|
|
130
|
-
let filepath = getfilePath(name)
|
|
131
|
-
let sha = await getSha(filepath).catch((err) => {
|
|
132
|
-
ctx.log.info(JSON.stringify(err))
|
|
133
|
-
})
|
|
134
|
-
|
|
135
|
-
let url = `${filepath}` + `?access_token=${config.token}` +
|
|
126
|
+
for (let i = 0; i < rms.length; i++) {
|
|
127
|
+
const each = rms[i];
|
|
128
|
+
let filepath = getFilePath(each.imgUrl);
|
|
129
|
+
let sha = await getSha(filepath).catch((err) => {
|
|
130
|
+
ctx.log.info("[删除操作]获取sha值:" + JSON.stringify(err));
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
let url =
|
|
134
|
+
`${filepath}` +
|
|
135
|
+
`?access_token=${config.token}` +
|
|
136
136
|
`&message=${config.message}` +
|
|
137
|
-
`&sha=${sha}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
137
|
+
`&sha=${sha}`;
|
|
138
|
+
ctx.log.info("[删除操作]当前删除地址:" + url);
|
|
139
|
+
let opts = {
|
|
140
|
+
method: "DELETE",
|
|
141
|
+
url: encodeURI(url),
|
|
142
|
+
headers: headers,
|
|
143
|
+
};
|
|
144
|
+
ctx.log.info("[删除操作]当前参数" + JSON.stringify(opts));
|
|
145
|
+
// log request params
|
|
146
|
+
response = await ctx.request(opts);
|
|
147
|
+
ctx.log.info(response);
|
|
143
148
|
}
|
|
144
149
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
}
|
|
150
|
+
ctx.emit("notification", {
|
|
151
|
+
title: "删除提示",
|
|
152
|
+
body: fail.length === 0 ? "成功同步删除" : `删除失败${fail.length}个`,
|
|
153
|
+
});
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
const getFilePath = function (url) {
|
|
157
|
+
let pathInfo = urlParser.parse(url);
|
|
158
|
+
let baseUrl = pathInfo.protocol + "//" + pathInfo.host;
|
|
159
|
+
let urlStr = url.replace(baseUrl, baseUrl + "/api/v5/repos");
|
|
160
|
+
return urlStr.replace("raw/master", "contents");
|
|
161
|
+
};
|
|
150
162
|
|
|
151
163
|
const getSha = async function (filepath) {
|
|
152
|
-
let config = getUserConfig()
|
|
153
|
-
let headers =
|
|
154
|
-
|
|
155
|
-
'User-Agent': 'PicGo'
|
|
156
|
-
}
|
|
157
|
-
let url = `${filepath}` + `?access_token=${config.token}`
|
|
164
|
+
let config = getUserConfig();
|
|
165
|
+
let headers = getHeaders();
|
|
166
|
+
let url = `${filepath}` + `?access_token=${config.token}`;
|
|
158
167
|
|
|
159
|
-
ctx.log.info(url)
|
|
160
168
|
const opts = {
|
|
161
|
-
method:
|
|
169
|
+
method: "GET",
|
|
162
170
|
url: encodeURI(url),
|
|
163
|
-
headers: headers
|
|
164
|
-
}
|
|
171
|
+
headers: headers,
|
|
172
|
+
};
|
|
165
173
|
|
|
166
|
-
let res = await ctx.Request.request(opts)
|
|
167
|
-
let tmp = JSON.parse(res)
|
|
168
|
-
|
|
169
|
-
return tmp.sha
|
|
170
|
-
}
|
|
174
|
+
let res = await ctx.Request.request(opts);
|
|
175
|
+
let tmp = JSON.parse(res);
|
|
176
|
+
|
|
177
|
+
return tmp.sha;
|
|
178
|
+
};
|
|
171
179
|
|
|
172
180
|
const formatConfigPath = function (userConfig) {
|
|
173
|
-
return userConfig.path ?
|
|
174
|
-
}
|
|
181
|
+
return userConfig.path ? "/" + userConfig.path : "";
|
|
182
|
+
};
|
|
175
183
|
|
|
176
|
-
const config = ctx => {
|
|
177
|
-
let userConfig = ctx.getConfig(
|
|
184
|
+
const config = (ctx) => {
|
|
185
|
+
let userConfig = ctx.getConfig("picBed.gitee");
|
|
178
186
|
if (!userConfig) {
|
|
179
|
-
userConfig = {}
|
|
187
|
+
userConfig = {};
|
|
180
188
|
}
|
|
181
189
|
return [
|
|
182
190
|
// {
|
|
@@ -188,49 +196,49 @@ module.exports = (ctx) => {
|
|
|
188
196
|
// alias: 'url'
|
|
189
197
|
// },
|
|
190
198
|
{
|
|
191
|
-
name:
|
|
192
|
-
type:
|
|
199
|
+
name: "owner",
|
|
200
|
+
type: "input",
|
|
193
201
|
default: userConfig.owner,
|
|
194
202
|
required: true,
|
|
195
|
-
message:
|
|
196
|
-
alias:
|
|
203
|
+
message: "owner",
|
|
204
|
+
alias: "owner",
|
|
197
205
|
},
|
|
198
206
|
{
|
|
199
|
-
name:
|
|
200
|
-
type:
|
|
207
|
+
name: "repo",
|
|
208
|
+
type: "input",
|
|
201
209
|
default: userConfig.repo,
|
|
202
210
|
required: true,
|
|
203
|
-
message:
|
|
204
|
-
alias:
|
|
211
|
+
message: "repo",
|
|
212
|
+
alias: "repo",
|
|
205
213
|
},
|
|
206
214
|
{
|
|
207
|
-
name:
|
|
208
|
-
type:
|
|
215
|
+
name: "path",
|
|
216
|
+
type: "input",
|
|
209
217
|
default: userConfig.path,
|
|
210
218
|
required: false,
|
|
211
|
-
message:
|
|
212
|
-
alias:
|
|
219
|
+
message: "path;根目录可不用填",
|
|
220
|
+
alias: "path",
|
|
213
221
|
},
|
|
214
222
|
{
|
|
215
|
-
name:
|
|
216
|
-
type:
|
|
223
|
+
name: "token",
|
|
224
|
+
type: "input",
|
|
217
225
|
default: userConfig.token,
|
|
218
226
|
required: true,
|
|
219
|
-
message:
|
|
220
|
-
alias:
|
|
227
|
+
message: "5664b5620fb11111e3183a98011113ca31",
|
|
228
|
+
alias: "token",
|
|
221
229
|
},
|
|
222
230
|
{
|
|
223
|
-
name:
|
|
224
|
-
type:
|
|
231
|
+
name: "message",
|
|
232
|
+
type: "input",
|
|
225
233
|
default: userConfig.message,
|
|
226
234
|
required: false,
|
|
227
235
|
message: defaultMsg,
|
|
228
|
-
alias:
|
|
229
|
-
}
|
|
230
|
-
]
|
|
231
|
-
}
|
|
236
|
+
alias: "message",
|
|
237
|
+
},
|
|
238
|
+
];
|
|
239
|
+
};
|
|
232
240
|
return {
|
|
233
|
-
uploader:
|
|
234
|
-
register
|
|
235
|
-
}
|
|
236
|
-
}
|
|
241
|
+
uploader: "gitee",
|
|
242
|
+
register,
|
|
243
|
+
};
|
|
244
|
+
};
|