-
Notifications
You must be signed in to change notification settings - Fork 3
/
elog-doge-upload.js
215 lines (201 loc) · 6.12 KB
/
elog-doge-upload.js
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
const {
S3Client,
PutObjectCommand,
HeadObjectCommand,
} = require("@aws-sdk/client-s3");
// 节省体积,只引入 S3 服务(推荐)
const S3 = require("aws-sdk/clients/s3");
var axios = require("axios");
var crypto = require("crypto");
var querystring = require("querystring");
/**
● 处理前缀,结尾自动加上/
● @param prefix
● @return {*|string}
*/
const formattedPrefix = (prefix) => {
// 如果没传,则默认为空
if (!prefix) return "";
let _prefix = prefix;
// 如果开头无需/
if (_prefix.startsWith("/")) {
prefix = prefix.slice(1);
}
// 如果结尾需要/
if (!_prefix.endsWith("/")) {
_prefix = `${_prefix}/`;
}
return _prefix;
};
class DogeCloudUploader {
constructor(config) {
this.config = config.dogeCloudUploader;
this.config.prefixKey = formattedPrefix(this.config.prefixKey);
// 该 API 参考文档: https://docs.dogecloud.com/oss/api-tmp-token
this.init();
}
async init() {
try {
console.log("init start");
await this.dogecloudApi(
"/auth/tmp_token.json",
{
channel: "OSS_FULL",
scopes: ["*"],
},
true,
function (err, data) {
if (err) {
console.log(err.Error);
return;
}
try {
// 这里推荐使用 Redis 之类的缓存将获取到的临时密钥缓存下来,两小时内有效
const client = new S3({
region: "automatic",
endpoint: process.env.R2_ENDPOINT,
credentials: data.Credentials,
params: {
Bucket: process.env.R2_BUCKET,
},
});
this.client = client;
} catch (e) {
console.error("初始化出错", err.message);
}
}.bind(this)
);
} catch (e) {
console.error("init初始化出错", err.message);
}
}
async hasImage(fileName) {
try {
if (!this.client) {
await this.init();
}
// 如果后缀是svg直接跳过
if (fileName.endsWith(".svg")) {
return;
}
let tdata = null;
let terr = null;
await this.client.copyObject(
{
Bucket: "s-gz-6611-oss1-1258813047", // 这里替换为目标空间的 s3Bucket 值
CopySource:
"/" +
process.env.R2_BUCKET +
"/" +
this.config.prefixKey +
fileName, // sourceS3Bucket 替换为源空间的 s3Bucket 值
Key: "_copy/" + this.config.prefixKey + fileName, // 目标路径
},
function (err, data) {
if (err) console.error("hasImage", err.name); // 出错
}
);
return undefined;
} catch (err) {
if (err.name === "NoSuchKey") {
return undefined;
}
console.error("检查图片出错", err.message);
}
}
async uploadImg(imgBuffer, fileName) {
try {
const params = {
Bucket: process.env.R2_BUCKET,
Key: this.config.prefixKey + fileName,
Body: imgBuffer,
// ContentType: "image/svg+xml",
// 如果需要可以在这里设置更多的上传参数,例如 ContentType 等
};
// 根据后缀类型设置对应的contentType
switch (fileName.split(".").pop()) {
case "svg":
params.ContentType = "image/svg+xml";
break;
case "png":
params.ContentType = "image/png";
break;
case "jpg":
params.ContentType = "image/jpeg";
break;
case "jpeg":
params.ContentType = "image/jpeg";
break;
case "gif":
params.ContentType = "image/gif";
break;
case "webp":
params.ContentType = "image/webp";
break;
default:
params.ContentType = "image/jpeg";
break;
}
await this.client.putObject(params, function (err, data) {
if (err) console.error("uploadImg", err, err.stack);
// else console.error(data);
});
return `https://${process.env.R2_HOST}/${
this.config.prefixKey + fileName
}`;
} catch (err) {
console.error("上传图片出错", err.message);
// throw err; 不抛出错误
}
}
dogecloudApi(apiPath, data = {}, jsonMode = false, callback = null) {
// 这里替换为你的多吉云永久 AccessKey 和 SecretKey,可在用户中心 - 密钥管理中查看
// 请勿在客户端暴露 AccessKey 和 SecretKey,那样恶意用户将获得账号完全控制权
const accessKey = process.env.R2_ACCESSKEYID;
const secretKey = process.env.R2_SECRET_ACCESSKEY;
const body = jsonMode ? JSON.stringify(data) : querystring.encode(data);
const sign = crypto
.createHmac("sha1", secretKey)
.update(Buffer.from(apiPath + "\n" + body, "utf8"))
.digest("hex");
const authorization = "TOKEN " + accessKey + ":" + sign;
return new Promise(function (resolve, reject) {
try {
axios
.request({
url: "https://api.dogecloud.com" + apiPath,
method: "POST",
data: body,
responseType: "json",
headers: {
"Content-Type": jsonMode
? "application/json"
: "application/x-www-form-urlencoded",
Authorization: authorization,
},
})
.then(function (response) {
if (response.data.code !== 200) {
// API 返回错误
callback
? callback({ Error: "API Error: " + response.data.msg }, null)
: reject({
errno: response.data.code,
msg: "API Error: " + response.data.msg,
});
return;
}
callback
? callback(null, response.data.data)
: resolve(response.data.data);
})
.catch(function (err) {
callback ? callback(err, null) : reject(err);
});
} catch (error) {
callback ? callback(error, null) : reject(err);
}
});
}
}
module.exports = DogeCloudUploader;