|
|
|
@ -1,9 +1,11 @@ |
|
|
|
|
/* eslint-disable import/no-extraneous-dependencies */ |
|
|
|
|
// import httpStatus from 'http-status';
|
|
|
|
|
import fs from 'fs'; |
|
|
|
|
import archiver from 'archiver'; |
|
|
|
|
import { exec } from 'child_process'; |
|
|
|
|
import sequelize from 'sequelize'; |
|
|
|
|
import multer from 'multer'; |
|
|
|
|
import path from 'path'; |
|
|
|
|
import { cloneDeep } from 'lodash'; |
|
|
|
|
import { handler as ErrorHandel } from '../../middlewares/errors'; |
|
|
|
|
// import ApiException from '../../../common/utils/APIException';
|
|
|
|
|
import { |
|
|
|
@ -12,8 +14,25 @@ import { |
|
|
|
|
storage as storageConfig |
|
|
|
|
} from '../../../config/vars'; |
|
|
|
|
import uploadAdapter from '../../../common/services/adapters/upload-adapter'; |
|
|
|
|
import { cloneDeep, forEach } from 'lodash'; |
|
|
|
|
import File from '../../../common/models/file.model'; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function getAllFilesWithInfo(dirPath, fileList = []) { |
|
|
|
|
const files = fs.readdirSync(dirPath); |
|
|
|
|
|
|
|
|
|
files.forEach(file => { |
|
|
|
|
const filePath = path.join(dirPath, file); |
|
|
|
|
const stat = fs.statSync(filePath); |
|
|
|
|
|
|
|
|
|
if (stat.isDirectory()) { |
|
|
|
|
getAllFilesWithInfo(filePath, fileList); |
|
|
|
|
} else { |
|
|
|
|
fileList.push({ path: filePath, name: file }); |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
return fileList; |
|
|
|
|
} |
|
|
|
|
function deleteFolderRecursive(folderPath) { |
|
|
|
|
if (fs.existsSync(folderPath)) { |
|
|
|
|
fs.readdirSync(folderPath).forEach((file) => { |
|
|
|
@ -36,46 +55,63 @@ exports.get = (req, res, next) => { |
|
|
|
|
try { |
|
|
|
|
const user = req.user; |
|
|
|
|
|
|
|
|
|
let path = `${storageConfig.uri}/${user.id}`; |
|
|
|
|
let pathDefault = `${storageConfig.uri}/${user.id}`; |
|
|
|
|
if (req.body.path) { |
|
|
|
|
path += req.body.path; |
|
|
|
|
pathDefault += req.body.path; |
|
|
|
|
} |
|
|
|
|
// console.log(path);
|
|
|
|
|
const listFile = []; |
|
|
|
|
fs.readdir(path, (err, files) => { |
|
|
|
|
|
|
|
|
|
fs.readdir(pathDefault, async (err, files) => { |
|
|
|
|
let listFile = []; |
|
|
|
|
const listPath = []; |
|
|
|
|
if (files && files.length > 0) { |
|
|
|
|
files.forEach((item) => { |
|
|
|
|
let pathDb = `${storageConfig.uri}/${user.id}`; |
|
|
|
|
let pathReplace = `${cdnConfig.uri}/${user.id}`; |
|
|
|
|
if (req.body.path === '') { |
|
|
|
|
pathDb += `/${item}`; |
|
|
|
|
pathReplace += `/${item}`; |
|
|
|
|
} else { |
|
|
|
|
pathDb += `${req.body.path}/${item}`; |
|
|
|
|
|
|
|
|
|
pathReplace += `${req.body.path}/${item}`; |
|
|
|
|
} |
|
|
|
|
listFile.push({ |
|
|
|
|
name: item, |
|
|
|
|
path: `${cdnConfig.uri}/${user.id}${req.body.path}/${item}`, |
|
|
|
|
path: pathReplace, |
|
|
|
|
path_origin: pathDb, |
|
|
|
|
isFolder: fs.lstatSync(`${storageConfig.uri}/${user.id}/${req.body.path}/${item}`).isDirectory() |
|
|
|
|
}); |
|
|
|
|
if (!fs.lstatSync(pathDb).isDirectory()) { |
|
|
|
|
listPath.push(pathDb); |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
const result = await File.findAll({ where: { |
|
|
|
|
url: { |
|
|
|
|
[sequelize.Op.in]: listPath |
|
|
|
|
} |
|
|
|
|
} }); |
|
|
|
|
listFile = listFile.map((file) => { |
|
|
|
|
const operation = file; |
|
|
|
|
const exist = result.find((a) => a.dataValues.url === file.path_origin); |
|
|
|
|
if (exist) { |
|
|
|
|
operation.download_count = exist.download_count; |
|
|
|
|
} else if (!file.isFolder) { |
|
|
|
|
operation.download_count = 0; |
|
|
|
|
} |
|
|
|
|
return operation; |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
return res.json({ |
|
|
|
|
code: 0, |
|
|
|
|
data: listFile |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|
// test local
|
|
|
|
|
// fs.readdir(path, (err, files) => {
|
|
|
|
|
// if (files && files.length > 0) {
|
|
|
|
|
// files.forEach((item) => {
|
|
|
|
|
// listFile.push({
|
|
|
|
|
// name: item,
|
|
|
|
|
// path: `${storageConfig.uri}/${user.id}${req.body.path}/${item}`,
|
|
|
|
|
// isFolder: fs.lstatSync(`${storageConfig.uri}/${user.id}/${req.body.path}/${item}`).isDirectory()
|
|
|
|
|
// });
|
|
|
|
|
// });
|
|
|
|
|
// }
|
|
|
|
|
// return res.json({
|
|
|
|
|
// code: 0,
|
|
|
|
|
// data: listFile
|
|
|
|
|
// });
|
|
|
|
|
// });
|
|
|
|
|
// console.log(listPath);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return null; |
|
|
|
|
// return null;
|
|
|
|
|
/** resize image uploaded */ |
|
|
|
|
} catch (ex) { |
|
|
|
|
return ErrorHandel(ex, req, res, next); |
|
|
|
@ -90,12 +126,12 @@ exports.get = (req, res, next) => { |
|
|
|
|
exports.create = (req, res, next) => { |
|
|
|
|
const user = req.user; |
|
|
|
|
let dir = `${user.id}`; |
|
|
|
|
const name_folder = cloneDeep(req.body.name).trim(); |
|
|
|
|
const nameFolder = cloneDeep(req.body.name).trim(); |
|
|
|
|
if (req.body.path) { |
|
|
|
|
dir += req.body.path; |
|
|
|
|
} |
|
|
|
|
if (req.body.name) { |
|
|
|
|
dir += `/${name_folder}`; |
|
|
|
|
dir += `/${nameFolder}`; |
|
|
|
|
} |
|
|
|
|
if (!fs.existsSync(dir)) { |
|
|
|
|
uploadAdapter.createFolder({ path: dir }); |
|
|
|
@ -113,11 +149,26 @@ exports.update = (req, res, next) => { |
|
|
|
|
const oldPath = req.body.oldPath.replace(cdnConfig.uri, storageConfig.uri); |
|
|
|
|
const newPath = req.body.newPath.replace(cdnConfig.uri, storageConfig.uri); |
|
|
|
|
|
|
|
|
|
fs.rename(oldPath, newPath, (err) => { |
|
|
|
|
fs.rename(oldPath, newPath, async (err) => { |
|
|
|
|
if (err) { |
|
|
|
|
console.log(err); |
|
|
|
|
return res.status(400).json({ code: 400, message: 'lỗi' }); |
|
|
|
|
} |
|
|
|
|
await File.update( |
|
|
|
|
// Update data
|
|
|
|
|
{ |
|
|
|
|
url: sequelize.literal(`REPLACE(url, '${oldPath}', '${newPath}')`), |
|
|
|
|
}, |
|
|
|
|
// Options for the update query
|
|
|
|
|
{ |
|
|
|
|
where: { |
|
|
|
|
url: { |
|
|
|
|
[sequelize.Op.like]: `%${oldPath}%`, // Find records containing the old substring
|
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
} |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
return res.json({ code: 0, message: 'success' }); |
|
|
|
|
}); |
|
|
|
|
return null; |
|
|
|
@ -132,7 +183,7 @@ exports.delete = (req, res, next) => { |
|
|
|
|
const user = req.user; |
|
|
|
|
const dir = `${storageConfig.uri_backup}/${user.id}`; |
|
|
|
|
multer({ dest: `${dir}` }); |
|
|
|
|
const path = req.body.path.replace(cdnConfig.uri, storageConfig.uri); |
|
|
|
|
const path1 = req.body.path.replace(cdnConfig.uri, storageConfig.uri); |
|
|
|
|
const newpath = req.body.path.replace(cdnConfig.uri, storageConfig.uri_backup); |
|
|
|
|
// fs.rm(path, { recursive: true }, err => {
|
|
|
|
|
// if (err) {
|
|
|
|
@ -140,8 +191,19 @@ exports.delete = (req, res, next) => { |
|
|
|
|
// }
|
|
|
|
|
// return res.json({ code: 0, message: 'success' });
|
|
|
|
|
// });
|
|
|
|
|
fs.rename(path, newpath, (err) => { |
|
|
|
|
|
|
|
|
|
fs.rename(path1, newpath, async (err) => { |
|
|
|
|
if (err) throw err; |
|
|
|
|
await File.destroy( |
|
|
|
|
// Options for the update query
|
|
|
|
|
{ |
|
|
|
|
where: { |
|
|
|
|
url: { |
|
|
|
|
[sequelize.Op.like]: `%${path1}%`, // Find records containing the old substring
|
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
} |
|
|
|
|
); |
|
|
|
|
return res.json({ code: 0, message: 'success' }); |
|
|
|
|
}); |
|
|
|
|
return null; |
|
|
|
@ -152,35 +214,75 @@ exports.delete = (req, res, next) => { |
|
|
|
|
exports.download = async (req, res, next) => { |
|
|
|
|
try { |
|
|
|
|
const user = req.user; |
|
|
|
|
const namefile = `${user.name}-${Date.now()}.zip`; |
|
|
|
|
const namefile = `${user.name.replace(/\s/g, '')}-${Date.now()}.zip`; |
|
|
|
|
const dir = `${storageConfig.uri}/download/${user.id}/${namefile}`; |
|
|
|
|
const folder = `${storageConfig.uri}/download/${user.id}`; |
|
|
|
|
multer({ dest: `${folder}` }); |
|
|
|
|
await deleteFolderRecursive(folder); |
|
|
|
|
const output = fs.createWriteStream(dir); |
|
|
|
|
const archive = archiver('zip', { |
|
|
|
|
zlib: { level: 9 } // Sets the compression level.
|
|
|
|
|
}); |
|
|
|
|
let command = ` zip -r ${dir} `; |
|
|
|
|
|
|
|
|
|
// const output = fs.createWriteStream(dir);
|
|
|
|
|
// const archive = archiver('zip', {
|
|
|
|
|
// zlib: { level: 9 } // Sets the compression level.
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
archive.pipe(output); |
|
|
|
|
// archive.pipe(output);
|
|
|
|
|
let promise = []; |
|
|
|
|
if (req.body.data) { |
|
|
|
|
req.body.data.forEach((e) => { |
|
|
|
|
const path = e.path.replace(cdnConfig.uri, storageConfig.uri).replace(/ /g, '\\ '); |
|
|
|
|
// const path = e.path.replace(cdnConfig.uri, storageConfig.uri);
|
|
|
|
|
console.log('path', path); |
|
|
|
|
// const download = path.split("/");
|
|
|
|
|
// download.splice( download.indexOf(`${user.id}`), 0, "download");
|
|
|
|
|
// const final_path = download.join("/");
|
|
|
|
|
if (e.isFolder) { |
|
|
|
|
archive.directory(path, e.name); |
|
|
|
|
req.body.data.forEach(async (e) => { |
|
|
|
|
const path1 = e.path.replace(cdnConfig.uri, storageConfig.uri).replace(/ /g, '\\ '); |
|
|
|
|
const path2 = e.path.replace(cdnConfig.uri, storageConfig.uri); |
|
|
|
|
|
|
|
|
|
if (fs.lstatSync(path2).isDirectory()) { |
|
|
|
|
getAllFilesWithInfo(path2, promise); |
|
|
|
|
} else { |
|
|
|
|
archive.file(path, { name: e.name }); |
|
|
|
|
console.log('path', path2); |
|
|
|
|
promise.push({ |
|
|
|
|
name: e.name, |
|
|
|
|
path: path2 |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
command += `${path1} `; |
|
|
|
|
}); |
|
|
|
|
console.log('promise', promise); |
|
|
|
|
promise = promise.map((file) => promise.push( |
|
|
|
|
File.findOne({ |
|
|
|
|
where: { url: file.path }, // Condition to find the record with the specified name
|
|
|
|
|
}) |
|
|
|
|
.then(record => { |
|
|
|
|
if (record) { |
|
|
|
|
// Record with the specified name found, increment the download_count by 1
|
|
|
|
|
return record.increment('download_count', { by: 1 }); |
|
|
|
|
} |
|
|
|
|
// Record with the specified name not found, create a new record with the name and download_count of 1 (default value)
|
|
|
|
|
return File.create({ url: file.path, download_count: 1, name: file.name }); |
|
|
|
|
}) |
|
|
|
|
.catch(err => { |
|
|
|
|
console.error('Error:', err); |
|
|
|
|
}) |
|
|
|
|
)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
archive.finalize(); |
|
|
|
|
exec(command, (error, stdout, stderr) => { |
|
|
|
|
if (error) { |
|
|
|
|
console.error(`Command execution error: ${error.message}`); |
|
|
|
|
return res.status(400).json({ |
|
|
|
|
code: 400, |
|
|
|
|
message: 'error' |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
if (stderr) { |
|
|
|
|
console.error(`Command stderr: ${stderr}`); |
|
|
|
|
return res.status(400).json({ |
|
|
|
|
code: 400, |
|
|
|
|
message: 'error' |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
console.log(`Command output: ${stdout}`); |
|
|
|
|
Promise.all(promise); |
|
|
|
|
return res.json({ |
|
|
|
|
code: 0, |
|
|
|
|
data: { |
|
|
|
@ -188,6 +290,7 @@ exports.download = async (req, res, next) => { |
|
|
|
|
path: `${cdnConfig.uri}/download/${user.id}/${namefile}`, |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|
} catch (ex) { |
|
|
|
|
return ErrorHandel(ex, req, res, next); |
|
|
|
|
} |
|
|
|
@ -196,9 +299,9 @@ exports.download = async (req, res, next) => { |
|
|
|
|
|
|
|
|
|
exports.forceDelete = (req, res, next) => { |
|
|
|
|
try { |
|
|
|
|
const path = req.body.path.replace(cdnConfig.uri, storageConfig.uri); |
|
|
|
|
const path1 = req.body.path.replace(cdnConfig.uri, storageConfig.uri); |
|
|
|
|
// const newpath = req.body.path.replace(cdnConfig.uri, storageConfig.uri_backup);
|
|
|
|
|
fs.rm(path, { recursive: true }, err => { |
|
|
|
|
fs.rm(path1, { recursive: true }, err => { |
|
|
|
|
if (err) { |
|
|
|
|
return res.status(400).json({ code: 400, message: 'lỗi', detail: err }); |
|
|
|
|
} |
|
|
|
@ -218,12 +321,22 @@ exports.deleteMultiple = (req, res, next) => { |
|
|
|
|
multer({ dest: `${dir}` }); |
|
|
|
|
if (req.body.data) { |
|
|
|
|
req.body.data.forEach((e) => { |
|
|
|
|
const path = e.path.replace(cdnConfig.uri, storageConfig.uri); |
|
|
|
|
const path1 = e.path.replace(cdnConfig.uri, storageConfig.uri); |
|
|
|
|
let newpath = e.path.replace(cdnConfig.uri, storageConfig.uri_backup); |
|
|
|
|
const split = newpath.split('/'); |
|
|
|
|
newpath = `${dir}/${split[split.length - 1]}`; |
|
|
|
|
fs.rename(path, newpath, (err) => { |
|
|
|
|
fs.rename(path1, newpath, async (err) => { |
|
|
|
|
if (err) throw err; |
|
|
|
|
await File.destroy( |
|
|
|
|
// Options for the update query
|
|
|
|
|
{ |
|
|
|
|
where: { |
|
|
|
|
url: { |
|
|
|
|
[sequelize.Op.like]: `%${path1}%`, // Find records containing the old substring
|
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
} |
|
|
|
|
); |
|
|
|
|
return { code: 0, message: 'success' }; |
|
|
|
|
}); |
|
|
|
|
}); |
|
|
|
|