UNPKG

@universis/candidates

Version:

Universis api server plugin for study program candidates, internship selection etc

160 lines (148 loc) 6.63 kB
import {DataObject} from '@themost/data'; import {TraceUtils, DataNotFoundError, HttpServerError, HttpBadRequestError} from "@themost/common"; import path from 'path'; class MimeTypeError extends HttpBadRequestError { constructor(message) { super(message); this.code = "EMIME"; } } class EnableAttachmentModel extends DataObject { constructor() { super(); } /** * @returns {Promise<*>} */ getRecipient() { if (this.getModel().getAttribute('recipient')) { return this.getModel().where('id').equal(this.id).select('recipient').silent().value(); } return Promise.resolve(); } addAttachment(file) { const context = this.context; const self = this; let finalResult; return new Promise((resolve, reject)=> { this.context.db.executeInTransaction((callback)=> { if (typeof file.originalname === 'string') { let fileName = file.originalname; // TODO: change this if busboy default encoding changes to utf-8 instead of latin1 // buffer original name with latin1 encoding and back const buffer = Buffer.from(file.originalname, 'latin1'); const testConversion = buffer.toString('latin1'); // then check if the produced name is the same with originalName and parse it as utf-8 if (testConversion == file.originalname) { fileName = Buffer.from(file.originalname, 'latin1').toString('utf-8'); } file.name = fileName.replace(/\.[A-Z0-9]+$/ig, function (x) { return x.toLowerCase(); }); } const mime = file.mimetype || file.contentType; if (mime == null) { return reject(new MimeTypeError('The specified file type is not supported by the system.')) } const addAttributes ={}; const attributeNames = context.model('Attachment').attributeNames; attributeNames.forEach((attribute)=> { if (Object.prototype.hasOwnProperty.call(file, attribute)) { addAttributes[attribute] = file[attribute]; } }); const newAttachment = Object.assign(addAttributes, { contentType:mime }); const svc = context.getApplication().getService(function PrivateContentService() { }); //add attachment to attachments context.unattended((cb)=> { // set attachment ownership to recipient EnableAttachmentModel.prototype.getRecipient.call(self).then( recipient => { if (recipient) { newAttachment.owner = recipient; } let filePath; if (file.destination && file.filename) { filePath = path.resolve(file.destination, file.filename); } else { filePath = file.path; } svc.copyFrom(context, filePath, newAttachment, function(err) { if (err) { TraceUtils.error(err); return cb(new HttpServerError()); } return cb(); }); }).catch( err=> { return cb(err); }); }, (err)=> { if (err) { return callback(err); } const attachments = self.property('attachments'); // set attachment ownership attachments.insert(newAttachment, (err)=> { if (err) { return callback(err); } svc.resolveUrl(context, newAttachment, function(err, url) { if (err) { callback(err); } else { finalResult =Object.assign({ }, newAttachment, { url: url, name: newAttachment.filename }); callback(); } }); }); }); }, (err)=> { if (err) { return reject(err); } return resolve(finalResult); }); }) } removeAttachment(id) { const context = this.context; const self = this; let result; return new Promise((resolve, reject)=> { context.db.executeInTransaction((callback)=> { //get attachment return context.model('Attachment').where('id').equal(id).getItem().then((attachment)=> { if (attachment) { //remove attachment connection return self.property('attachments').remove(attachment,(err)=> { //remove attachment if (err) { return callback(err); } return context.model('Attachment').silent().remove(attachment).then(()=> { result = attachment; return callback(); }).catch((err)=> { return callback(err); }); }); } return callback(new DataNotFoundError()); }).catch((err)=> { return callback(err); }); }, (err)=> { if (err) { return reject(err); } return resolve(result); }); }); } } module.exports = EnableAttachmentModel;