lx-music-desktop/publish/utils/cos.js

154 lines
4.7 KiB
JavaScript
Raw Normal View History

2019-08-16 09:27:23 +00:00
const fs = require('fs')
const { jp, sizeFormate } = require('./index')
const chalk = require('chalk')
const COS = require('cos-nodejs-sdk-v5')
const config = require('./cosConfig')
const MultiProgress = require('multi-progress')
const multi = new MultiProgress(process.stderr)
const cos = new COS({
SecretId: config.secretId,
SecretKey: config.secretKey,
KeepAlive: false,
})
const getCosFileList = () => new Promise((resolve, reject) => {
cos.getBucket({
Bucket: config.bucket,
Region: config.region,
Prefix: config.prefix,
}, function(err, data) {
if (err) {
console.log(err)
reject(err)
console.log(chalk.red('COS文件列表获取失败'))
}
resolve(data.Contents.filter(o => o.Key !== config.prefix).map(o => o.Key.replace(config.prefix, '')))
})
})
const getLocalFileList = () => fs.readdirSync(jp('../assets'), 'utf8')
const diffFileList = (localFiles, cosFiles) => {
const removeFiles = []
cosFiles.forEach(file => {
let index = localFiles.indexOf(file)
if (index < 0) return removeFiles.push(file)
localFiles.splice(index, 1)
})
if (cosFiles.includes('latest.yml')) {
removeFiles.push('latest.yml')
localFiles.push('latest.yml')
}
if (cosFiles.includes('version.json')) {
removeFiles.push('version.json')
localFiles.push('version.json')
}
return removeFiles
}
const deleteCosFiles = files => new Promise((resolve, reject) => {
files = files.map(f => ({ Key: config.prefix + f }))
cos.deleteMultipleObject({
Bucket: config.bucket,
Region: config.region,
Objects: files,
}, function(err, data) {
if (err) {
console.log(err)
reject(err)
}
resolve()
})
})
const createProgressBar = (name, spacekLen, total) => multi.newBar(
`${` ${name}`.padEnd(spacekLen, ' ')} :status [:bar] :current/:total :percent :speed`, {
complete: '=',
incomplete: ' ',
width: 30,
total,
})
const uploadFile = (fileName, len) => new Promise((resolve, reject) => {
const filePath = jp('../assets', fileName)
// let size = fs.statSync(filePath).size
let bar = null
let prevLoaded = 0
cos.sliceUploadFile({
Bucket: config.bucket,
Region: config.region,
Key: config.prefix + fileName, /* 必须 */
FilePath: filePath, /* 必须 */
// TaskReady: function(taskId) { /* 非必须 */
// console.log(taskId)
// },
onHashProgress(progressData) { /* 非必须 */
if (!bar) {
bar = createProgressBar(fileName, len, progressData.total)
prevLoaded = 0
}
bar.tick(progressData.loaded - prevLoaded, {
status: '校验中',
speed: sizeFormate(progressData.speed) + '/s',
})
prevLoaded = progressData.loaded
// console.log('校验', fileName, JSON.stringify(progressData))
// console.log('校验', JSON.stringify(progressData))
},
onProgress(progressData) { /* 非必须 */
if (!bar) {
bar = createProgressBar(fileName, len, progressData.total)
prevLoaded = 0
}
bar.tick(progressData.loaded - prevLoaded, {
status: '上传中',
speed: sizeFormate(progressData.speed) + '/s',
})
prevLoaded = progressData.loaded
// console.log('上传', fileName, JSON.stringify(progressData))
// console.log('上传', JSON.stringify(progressData))
},
}, (err, data) => {
if (err) {
console.log(err)
return reject(err)
}
bar.tick({
status: '已完成',
speed: '',
})
resolve(data)
})
})
module.exports = async() => {
console.log(chalk.blue('正在获取COS文件列表...'))
const cosFiles = await getCosFileList()
console.log(chalk.green('COS文件列表获取成功'))
const uploadFiles = getLocalFileList()
const removeFiles = diffFileList(uploadFiles, cosFiles)
if (removeFiles.length) {
console.log(chalk.blue('共需删除') + chalk.yellow(removeFiles.length) + chalk.blue('个文件'))
console.log(chalk.blue('正在从COS删除多余的文件...'))
await deleteCosFiles(removeFiles)
console.log(chalk.green('多余文件删除成功'))
} else {
console.log(chalk.blue('没有在COS发现多余的文件'))
}
if (uploadFiles.length) {
console.log(chalk.blue('共需上传') + chalk.green(uploadFiles.length) + chalk.blue('个文件'))
console.log(chalk.blue('正在上传新文件到COS...'))
let max = Math.max(...uploadFiles.map(f => f.length)) + 2
let tasks = uploadFiles.map(f => uploadFile(f, max))
await Promise.all(tasks)
console.log(''.padEnd(Math.max(2, tasks.length - 2), '\n'))
console.log(chalk.green('所有文件上传完成'))
} else {
console.log(chalk.blue('没有需要上传的文件'))
}
}