Skip to content

Commit

Permalink
Merge branch 'releasev1.0.7'
Browse files Browse the repository at this point in the history
  • Loading branch information
TabSpace committed Feb 18, 2019
2 parents 678aa77 + 263d652 commit 8007d4e
Show file tree
Hide file tree
Showing 5 changed files with 258 additions and 106 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ services:
- docker

node_js:
- 10
- 8

branches:
only:
Expand Down
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ upload({
log: true,
// 是否允许文件覆盖,默认为 false
overwrite: false,
// 为 true 则输出文件路径为腾讯云默认 CDN 地址。为具体域名,则替换腾讯云默认 CDN 域名。
cdn: '',
// 在腾讯云申请的 AppId
AppId: '1000000000',
// 配置腾讯云 COS 服务所需的 SecretId
Expand All @@ -55,5 +57,20 @@ upload({
FilePath: './1.zip',
// 文件在存储桶中的路径
Key: '1.zip'
}).then(rs => {
// 线上路径
console.info(rs.url);
// 为 true 表明线上文件已存在
console.info(rs.isExists);
// 为 true 表明进行了覆盖
console.info(rs.overwrited);
// 为 true 表明已进行了上传
console.info(rs.uploaded);
// 文件在对象存储的线上访问路径
console.info(rs.cosUrl);
// 文件在 CDN 的线上访问路径,如果没有配置 cdn 选项则为 undefined
console.info(rs.cdnUrl);
// 如果进行了上传,可以通过 uploadData 取得详细上传信息
console.info(rs.uploadData);
});
```
258 changes: 154 additions & 104 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,141 +16,191 @@ const requestParam = {

const SLICE_UPLOAD_FILE_SIZE = 1024 * 1024;

const uploadFile = (conf, cos) => {
let progressIndex = 0;

cos.sliceUploadFile({
Bucket: conf.Bucket,
Region: conf.Region,
Key: conf.Key,
FilePath: conf.FilePath,
onProgress: progressData => {
if (progressIndex > 0 && progressData && progressData.total > SLICE_UPLOAD_FILE_SIZE) {
if (progressIndex === 1) {
console.log($chalk.gray(`Uploading: ${conf.cosPath}`));
function showError(conf, msg, err) {
console.log($chalk.red(`Error: [${conf.Key}] ${msg}`));
if (conf.debug && err) {
console.error($chalk.red('Error Detail:'));
console.error(err);
}
}

function uploadFile(conf, cos) {
return new Promise((resolve, reject) => {
let progressIndex = 0;
cos.sliceUploadFile({
Bucket: conf.Bucket,
Region: conf.Region,
Key: conf.Key,
FilePath: conf.FilePath,
onProgress: progressData => {
if (progressIndex > 0 && progressData && progressData.total > SLICE_UPLOAD_FILE_SIZE) {
if (conf.log && progressIndex === 1) {
console.log($chalk.gray(`Uploading: ${conf.cosUrl}`));
}
let percent = (Math.floor(progressData.percent * 100) || 0) + '%';
if (conf.log) {
console.log($chalk.gray(`total:${progressData.total}, loaded:${progressData.loaded}, speed:${progressData.speed}, percent:${percent}`));
}
}
let percent = (Math.floor(progressData.percent * 100) || 0) + '%';
console.log($chalk.gray(`total:${progressData.total}, loaded:${progressData.loaded}, speed:${progressData.speed}, percent:${percent}`));
}
progressIndex++;
}
}, (err, data) => {
if (err) {
if (err.error && err.error.Message) {
conf.error(err.error.Message, err);
} else {
conf.error('Upload error', err);
progressIndex++;
}
} else if (data && data.statusCode === 200) {
if (conf.isOverwriting) {
console.log($chalk.cyan(`Overwrite: ${conf.cosPath}`));
conf.resolve({
isOverwrited: true,
path: conf.cosPath
});
}, (err, data) => {
let upErr = new Error('Upload error.');
if (err) {
upErr.detail = err;
if (err && err.error && err.error.Message) {
upErr.message = err.error.Message;
}
reject(upErr);
} else if (data && data.statusCode === 200) {
conf.uploadData = data;
conf.uploaded = true;
resolve(conf);
} else {
console.log($chalk.green(`Success: ${conf.cosPath}`));
conf.resolve({
path: conf.cosPath
});
upErr.detail = data;
reject(upErr);
}
} else {
conf.error('Upload error', data);
}
});
});
};
}

const checkAcl = (conf, cos) => {
cos.getObjectAcl({
Bucket: conf.Bucket,
Region: conf.Region,
Key: conf.Key
}, (err, data) => {
if (err) {
if (err.statusCode === 404) {
uploadFile(conf, cos);
} else if (err.error && err.error.Message) {
conf.error(err.error.Message, err);
} else {
conf.error('Check ACL error', err);
}
} else if (data && data.statusCode === 200) {
if (conf.overwrite) {
conf.isOverwriting = true;
uploadFile(conf, cos);
} else {
if (conf.log) {
console.log($chalk.gray(`Exists: ${conf.cosPath}`));
function checkAcl(conf, cos) {
return new Promise((resolve, reject) => {
cos.getObjectAcl({
Bucket: conf.Bucket,
Region: conf.Region,
Key: conf.Key
}, (err, data) => {
let aclErr = new Error('Acl Error.');
if (err) {
aclErr.detail = err;
if (err && err.error && err.error.Message) {
aclErr.message = err.error.Message;
}
conf.resolve({
isExists: true,
path: conf.cosPath
});
reject(aclErr);
} else if (data && data.statusCode === 200) {
conf.isExists = true;
resolve(conf);
} else {
aclErr.detail = data;
reject(aclErr);
}
} else {
conf.error('Check ACL error', data);
}
});
});
};
}

const upload = options => {
function upload(options) {
options = options || {};

let conf = Object.assign({
// 静态资源对应 cdn 域名,配置后,打印在控制台的日志自动替换域名显示
// 配置为 true ,自动匹配腾讯云 cdn 域名
cdn: '',
// 是否开启调试模式,调试模式开启后会有额外log产生
debug: false,
// 是否在控制台输出日志
log: true,
// 是否允许覆盖文件
overwrite: false
}, requestParam, options);

conf.domain = `${conf.Bucket}-${conf.AppId}.coscd.myqcloud.com`;
conf.cosPath = $urljoin(`http://${conf.domain}`, conf.Key);
conf.cosUrl = $urljoin(`http://${conf.domain}`, conf.Key);

if (conf.cdn === true) {
let cdnDomain = `${conf.Bucket}-${conf.AppId}.file.myqcloud.com`;
conf.cdnUrl = $urljoin(`http://${cdnDomain}`, conf.Key);
} else if (conf.cdn) {
conf.cdnUrl = $urljoin(`http://${conf.cdn}`, conf.Key);
}
if (conf.Bucket.indexOf('-') < 0) {
conf.Bucket = conf.Bucket + '-' + conf.AppId;
} else if (!conf.AppId) {
conf.AppId = conf.Bucket.split('-')[1] || '';
}

return new Promise((resolve, reject) => {
conf.resolve = resolve;
conf.reject = reject;
let hasAllRequestParam = Object.keys(requestParam).every(key => {
if (!conf[key]) {
showError(conf, `Missing parameter: ${key}`);
}
return conf[key];
});

if (!hasAllRequestParam) {
return Promise.reject(new Error('Missing parameter.'));
}

conf.error = (msg, err) => {
if (conf.log) {
console.log($chalk.red(`Error: [${conf.Key}] ${msg}`));
let cacheId = [
conf.AppId,
conf.SecretId,
conf.SecretKey
].join('____');
let cos = cosCache[cacheId];
if (!cos) {
// 官方提示:
// AppId has been deprecated,
// Please put it at the end of parameter Bucket
// (E.g: "test-1250000000").
// cos sdk 不再需要 AppId 作为参数
cos = new $cos({
SecretId: conf.SecretId,
SecretKey: conf.SecretKey
});
cosCache[cacheId] = cos;
}

let pm = checkAcl(conf, cos)
.then(spec => {
if (spec.overwrite) {
return uploadFile(spec, cos);
} else {
spec.isExists = true;
return spec;
}
})
.catch(err => {
if (err.detail && err.detail.statusCode === 404) {
return uploadFile(conf, cos);
} else {
return Promise.reject(err);
}
if (conf.debug && err) {
console.error($chalk.red('Error Detail:'));
console.error(err);
})
.then(spec => {
let fileUrl = spec.cosUrl;
if (spec.cdn && spec.cdnUrl) {
fileUrl = spec.cdnUrl;
}
reject(new Error(msg));
};

let hasAllRequestParam = Object.keys(requestParam).every(key => {
if (!conf[key]) {
conf.error(`Need param: ${key}`);
spec.url = fileUrl;

let execMsg = '';
if (spec.isExists) {
if (spec.overwrite) {
spec.statusMsg = 'Overwrite';
execMsg = $chalk.cyan(`Overwrite: ${fileUrl}`);
spec.overwrited = true;
} else {
spec.statusMsg = 'Exists';
execMsg = $chalk.gray(`Exists: ${fileUrl}`);
}
} else {
spec.statusMsg = 'Success';
execMsg = $chalk.green(`Success: ${fileUrl}`);
}
spec.execMsg = execMsg;
if (spec.log) {
console.log(execMsg);
}
return conf[key];
return spec;
})
.catch(err => {
if (err && err.message) {
showError(conf, err.message, err);
}
return Promise.reject(err);
});

if (!hasAllRequestParam) { return; }

let cos = cosCache[conf.AppId];
if (!cos) {
cos = new $cos({
// 官方提示:
// AppId has been deprecated,
// Please put it at the end of parameter Bucket
// (E.g: "test-1250000000").
// AppId: conf.AppId,
SecretId: conf.SecretId,
SecretKey: conf.SecretKey
});
cosCache[conf.AppId] = cos;
}

checkAcl(conf, cos);
});
};
return pm;
}

module.exports = upload;

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "qcloud-cos-upload",
"version": "1.0.5",
"version": "1.0.7",
"description": "上传单个文件到腾讯云COS服务",
"main": "index.js",
"scripts": {
Expand Down
Loading

0 comments on commit 8007d4e

Please sign in to comment.