upload dms files into new folder structure #1548
gitea/salix/test This commit looks good Details

This commit is contained in:
Joan Sanchez 2019-06-20 07:46:30 +02:00
parent 8d5aef4684
commit 19dc0c80b8
7 changed files with 100 additions and 101 deletions

1
.gitignore vendored
View File

@ -1,5 +1,6 @@
node_modules node_modules
dist/* dist/*
e2e/dms/*
npm-debug.log npm-debug.log
.eslintcache .eslintcache
datasources.*.json datasources.*.json

View File

@ -36,40 +36,31 @@ module.exports = Self => {
Self.downloadFile = async function(ctx, id) { Self.downloadFile = async function(ctx, id) {
const env = process.env.NODE_ENV; const env = process.env.NODE_ENV;
const storageConnector = Self.app.dataSources.storage.connector;
const models = Self.app.models; const models = Self.app.models;
const dms = await Self.findById(id, { const dms = await Self.findById(id);
include: {
relation: 'dmsType',
scope: {
fields: ['path', 'readRoleFk'],
include: {
relation: 'readRole'
}
}
}
});
const hasReadRole = await models.DmsType.hasReadRole(ctx, dms.dmsTypeFk); const hasReadRole = await models.DmsType.hasReadRole(ctx, dms.dmsTypeFk);
if (!hasReadRole) if (!hasReadRole)
throw new UserError(`You don't have enough privileges`); throw new UserError(`You don't have enough privileges`);
if (env && env != 'development') { if (env && env != 'development') {
const path = `/${dms.companyFk}/${dms.dmsType().path}/${dms.file}`; const pathHash = storageConnector.getPathHash(dms.id);
file = { file = {
path: `/var/lib/salix/dms/${path}`,
contentType: 'application/octet-stream', contentType: 'application/octet-stream',
container: pathHash,
name: dms.file name: dms.file
}; };
} else { } else {
file = { file = {
path: `${process.cwd()}/README.md`,
contentType: 'text/plain', contentType: 'text/plain',
name: `README.md` container: 'temp',
name: `file.txt`
}; };
} }
await fs.access(file.path); const stream = await models.Container.downloadStream(file.container, file.name);
let stream = fs.createReadStream(file.path);
return [stream, file.contentType, `filename="${file.name}"`]; return [stream, file.contentType, `filename="${file.name}"`];
}; };
}; };

View File

@ -1,5 +1,4 @@
const UserError = require('vn-loopback/util/user-error'); const UserError = require('vn-loopback/util/user-error');
const fs = require('fs-extra');
module.exports = Self => { module.exports = Self => {
Self.remoteMethodCtx('removeFile', { Self.remoteMethodCtx('removeFile', {
@ -23,24 +22,13 @@ module.exports = Self => {
Self.removeFile = async(ctx, id) => { Self.removeFile = async(ctx, id) => {
const models = Self.app.models; const models = Self.app.models;
const trashDmsType = await models.DmsType.findOne({where: {code: 'trash'}});
const dms = await models.Dms.findById(id); const dms = await models.Dms.findById(id);
const dmsType = await models.DmsType.findById(dms.dmsTypeFk);
const trashDmsType = await models.DmsType.findOne({
where: {
code: 'trash'
}
});
const hasWriteRole = await models.DmsType.hasWriteRole(ctx, dms.dmsTypeFk); const hasWriteRole = await models.DmsType.hasWriteRole(ctx, dms.dmsTypeFk);
if (!hasWriteRole) if (!hasWriteRole)
throw new UserError(`You don't have enough privileges`); throw new UserError(`You don't have enough privileges`);
const file = await models.Container.getFile(dmsType.path, dms.file);
const originPath = `${file.client.root}/${dmsType.path}/${file.name}`;
const destinationPath = `${file.client.root}/${trashDmsType.path}/${file.name}`;
await fs.rename(originPath, destinationPath);
return dms.updateAttribute('dmsTypeFk', trashDmsType.id); return dms.updateAttribute('dmsTypeFk', trashDmsType.id);
}; };
}; };

View File

@ -1,5 +1,6 @@
const fs = require('fs-extra');
const UserError = require('vn-loopback/util/user-error'); const UserError = require('vn-loopback/util/user-error');
const fs = require('fs-extra');
const md5 = require('md5');
module.exports = Self => { module.exports = Self => {
Self.remoteMethodCtx('uploadFile', { Self.remoteMethodCtx('uploadFile', {
@ -7,9 +8,6 @@ module.exports = Self => {
accessType: 'WRITE', accessType: 'WRITE',
accepts: [ accepts: [
{ {
arg: 'options',
type: 'object'
}, {
arg: 'warehouseId', arg: 'warehouseId',
type: 'Number', type: 'Number',
description: '' description: ''
@ -33,8 +31,7 @@ module.exports = Self => {
arg: 'hasFile', arg: 'hasFile',
type: 'Boolean', type: 'Boolean',
description: '' description: ''
} }],
],
returns: { returns: {
type: 'Object', type: 'Object',
root: true root: true
@ -45,23 +42,20 @@ module.exports = Self => {
} }
}); });
Self.uploadFile = async(ctx, options) => { Self.uploadFile = async(ctx, options = {}) => {
const models = Self.app.models;
const storageConnector = Self.app.dataSources.storage.connector; const storageConnector = Self.app.dataSources.storage.connector;
const myUserId = ctx.req.accessToken.userId; const models = Self.app.models;
const myWorker = await models.Worker.findOne({where: {userFk: myUserId}});
const args = ctx.args;
const fileOptions = {}; const fileOptions = {};
const args = ctx.args;
let tx; let tx;
let myOptions = {};
if (typeof options == 'object') if (typeof options == 'object')
Object.assign(myOptions, options); Object.assign(options, options);
if (!myOptions.transaction) { if (!options.transaction) {
tx = await Self.beginTransaction({}); tx = await Self.beginTransaction({});
myOptions.transaction = tx; options.transaction = tx;
} }
try { try {
@ -69,26 +63,43 @@ module.exports = Self => {
if (!hasWriteRole) if (!hasWriteRole)
throw new UserError(`You don't have enough privileges`); throw new UserError(`You don't have enough privileges`);
// Create final folder if not exists
const dmsType = await models.DmsType.findById(args.dmsTypeId);
await models.Container.getContainer(dmsType.path).catch(async err => {
if (err.code === 'ENOENT') {
await models.Container.createContainer({
name: dmsType.path
});
}
});
// Upload file to temporary path // Upload file to temporary path
const uploaded = await models.Container.upload('temp', ctx.req, ctx.result, fileOptions); const tempContainer = await getContainer('temp');
const uploaded = await models.Container.upload(tempContainer.name, ctx.req, ctx.result, fileOptions);
const files = Object.values(uploaded.files).map(file => { const files = Object.values(uploaded.files).map(file => {
return file[0]; return file[0];
}); });
const promises = []; const addedDms = [];
for (const file of files) {
const newDms = await createDms(ctx, file.name, options);
const pathHash = storageConnector.getPathHash(newDms.id);
const container = await getContainer(pathHash);
files.forEach(file => { const originPath = `${tempContainer.client.root}/${tempContainer.name}/${file.name}`;
const newDms = Self.create({ const destinationPath = `${container.client.root}/${pathHash}/${newDms.file}`;
fs.rename(originPath, destinationPath);
addedDms.push(newDms);
}
if (tx) await tx.commit();
return addedDms;
} catch (e) {
if (tx) await tx.rollback();
throw e;
}
};
async function createDms(ctx, fileName, options) {
const models = Self.app.models;
const storageConnector = Self.app.dataSources.storage.connector;
const myUserId = ctx.req.accessToken.userId;
const myWorker = await models.Worker.findOne({where: {userFk: myUserId}});
const args = ctx.args;
const newDms = await Self.create({
workerFk: myWorker.id, workerFk: myWorker.id,
dmsTypeFk: args.dmsTypeId, dmsTypeFk: args.dmsTypeId,
companyFk: args.companyId, companyFk: args.companyId,
@ -96,32 +107,35 @@ module.exports = Self => {
reference: args.reference, reference: args.reference,
description: args.description, description: args.description,
hasFile: args.hasFile hasFile: args.hasFile
}, myOptions).then(newDms => { }, options);
const extension = storageConnector.getFileExtension(file.name);
const fileName = `${newDms.id}.${extension}`;
return newDms.updateAttribute('file', fileName, myOptions); const extension = storageConnector.getFileExtension(fileName);
}).then(dms => { fileName = `${newDms.id}.${extension}`;
return models.Container.getContainer('temp').then(container => {
const originPath = `${container.client.root}/${container.name}/${file.name}`;
const destinationPath = `${container.client.root}/${dmsType.path}/${dms.file}`;
return fs.rename(originPath, destinationPath).then(() => { return newDms.updateAttribute('file', fileName, options);
return dms; }
});
});
}); /**
* Returns a container instance
promises.push(newDms); * If doesn't exists creates a new one
}); *
* @param {String} name Container name
const resolvedPromise = await Promise.all(promises); * @return {Object} Container instance
*/
if (tx) await tx.commit(); async function getContainer(name) {
return resolvedPromise; const models = Self.app.models;
} catch (e) { let container;
if (tx) await tx.rollback(); try {
throw e; container = await models.Container.getContainer(name);
} catch (err) {
if (err.code === 'ENOENT') {
container = await models.Container.createContainer({
name: name
});
} else throw err;
}
return container;
} }
};
}; };

View File

@ -1,5 +1,3 @@
const uuid = require('uuid/v1');
module.exports = function(app) { module.exports = function(app) {
let models = app.models(); let models = app.models();
models.forEach(function(model) { models.forEach(function(model) {
@ -33,14 +31,6 @@ module.exports = function(app) {
router.get('/status', app.loopback.status()); router.get('/status', app.loopback.status());
app.use(router); app.use(router);
const storageConnector = app.dataSources.storage.connector;
storageConnector.getFilename = function(file) {
return `${uuid()}.${storageConnector.getFileExtension(file.name)}`;
};
storageConnector.getFileExtension = function(fileName) {
return fileName.split('.').pop();
};
/* /*
let ds = app.dataSources.auth; let ds = app.dataSources.auth;
//ds.automigrate(function() { //ds.automigrate(function() {

View File

@ -0,0 +1,18 @@
const uuid = require('uuid/v1');
const md5 = require('md5');
module.exports = app => {
const storageConnector = app.dataSources.storage.connector;
storageConnector.getFilename = function(file) {
return `${uuid()}.${storageConnector.getFileExtension(file.name)}`;
};
storageConnector.getFileExtension = function(fileName) {
return fileName.split('.').pop();
};
storageConnector.getPathHash = function(id) {
return md5(id).substring(0, 2);
};
};

View File

@ -20,14 +20,11 @@ module.exports = Self => {
Self.removeFile = async(ctx, id) => { Self.removeFile = async(ctx, id) => {
const models = Self.app.models; const models = Self.app.models;
const targetClientDms = await models.ClientDms.findById(id); const clientDms = await models.ClientDms.findById(id);
const targetDms = await models.Dms.findById(targetClientDms.dmsFk);
const trashDmsType = await models.DmsType.findOne({where: {code: 'trash'}});
await models.Dms.removeFile(ctx, targetClientDms.dmsFk); await models.Dms.removeFile(ctx, clientDms.dmsFk);
await targetClientDms.destroy();
return targetDms.updateAttribute('dmsTypeFk', trashDmsType.id); return clientDms.destroy();
}; };
}; };