jsharmony
Version:
Rapid Application Development (RAD) Platform for Node.js Database Application Development
467 lines (435 loc) • 26.7 kB
JavaScript
/*
Copyright 2017 apHarmony
This file is part of jsHarmony.
jsHarmony is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
jsHarmony is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this package. If not, see <http://www.gnu.org/licenses/>.
*/
var Helper = require('./lib/Helper.js');
var _ = require('lodash');
var async = require('async');
var path = require('path');
var multiparty = require('multiparty');
var HelperFS = require('./lib/HelperFS.js');
var fs = require('fs');
module.exports = exports = {};
exports.Upload = function (req, res) {
var jsh = this.jsh;
if (!('_DBContext' in req) || (req._DBContext == '') || (req._DBContext == null)) { return Helper.GenError(req, res, -30, 'Invalid file upload request.'); }
var temp_folder = jsh.Config.datadir + 'temp/';
var public_folder = temp_folder + 'public/';
var user_folder = temp_folder + req._DBContext + '/';
var form = new multiparty.Form({ maxFilesSize: jsh.Config.max_filesize, uploadDir: (public_folder) });
form.parse(req, function (err, fields, files) {
//Handle Error
if (err != null) {
if (('code' in err) && (err.code == 'ETOOBIG')) { return Helper.GenError(req, res, -31, 'Upload file exceeded maximum file size.'); }
jsh.Log.error(err);
return Helper.GenError(req, res, -30, 'Invalid file upload request.');
}
var prevtoken = '';
if ((fields != null) && ('prevtoken' in fields) && (_.isString(fields.prevtoken[0]))) prevtoken = path.basename(fields.prevtoken[0]);
if (files == null) { return Helper.GenError(req, res, -30, 'Invalid file upload request.'); }
if (!('file' in files)) { return Helper.GenError(req, res, -30, 'Invalid file upload request.'); }
if (files.file.length != 1) { return Helper.GenError(req, res, -30, 'Invalid file upload request.'); }
var xfile = files.file[0];
var file_size = xfile.size;
var file_token = '';
var file_orig_name = path.basename(xfile.originalFilename);
var file_path = xfile.path;
var file_ext = path.extname(path.basename(file_orig_name)).toLowerCase(); //Get extension
if (!_.includes(jsh.Config.valid_extensions, file_ext)) { return Helper.GenError(req, res, -32, 'File extension is not supported.'); }
async.waterfall([
async.apply(HelperFS.createFolderIfNotExists, user_folder),
async.apply(HelperFS.clearFiles, user_folder, jsh.Config.user_temp_expiration, jsh.Config.max_user_temp_foldersize),
async.apply(HelperFS.clearFiles, public_folder, jsh.Config.public_temp_expiration, -1),
async.apply(HelperFS.genRandomFileName, user_folder, file_ext),
function (fname, callback) { file_token = fname; callback(null); },
function (callback) { HelperFS.rename(file_path, (user_folder + file_token), callback); },
function (callback) { if (prevtoken != '') { HelperFS.tryUnlink(user_folder + prevtoken, callback); } else callback(null); }
], function (err, rslt) {
//Handle error or return result
if (err) {
if (_.isObject(err) && ('number' in err) && (err.number == -36)) return Helper.GenError(req, res, -36, 'User exceeded max temp folder size');
return Helper.GenError(req, res, -99999, 'Error occurred during file operation (' + err.toString() + ')');
}
else {
rslt = { '_success': 1, 'file_size': file_size, 'file_token': file_token, 'file_orig_name': file_orig_name, 'file_extension': file_ext };
if (req.jsproxyid) return res.end(Helper.js_proxy(req, rslt));
else{
res.type('json');
return res.end(JSON.stringify(rslt));
}
}
});
});
};
exports.UploadCKEditor = function (req, res) {
var jsh = this.jsh;
if (!('_DBContext' in req) || (req._DBContext == '') || (req._DBContext == null)) { return Helper.GenError(req, res, -30, 'Invalid file upload request.'); }
if (!Helper.HasRole(req, 'CMSFILES')) { Helper.GenError(req, res, -15, 'Invalid Access'); return; }
var temp_folder = jsh.Config.datadir + 'temp/';
var public_folder = temp_folder + 'public/';
var cmsfiles_folder = jsh.Config.datadir + 'cmsfiles/';
var form = new multiparty.Form({ maxFilesSize: jsh.Config.max_filesize, uploadDir: (public_folder) });
form.parse(req, function (err, fields, files) {
//Handle Error
if (err != null) {
if (('code' in err) && (err.code == 'ETOOBIG')) { return Helper.GenError(req, res, -31, 'Upload file exceeded maximum file size.'); }
jsh.Log.error(err);
return Helper.GenError(req, res, -30, 'Invalid file upload request.');
}
if (files == null) { return Helper.GenError(req, res, -30, 'Invalid file upload request.'); }
if (!('upload' in files)) { return Helper.GenError(req, res, -30, 'Invalid file upload request.'); }
if (files.upload.length != 1) { return Helper.GenError(req, res, -30, 'Invalid file upload request.'); }
var xfile = files.upload[0];
//var file_size = xfile.size;
var file_orig_name = path.basename(xfile.originalFilename);
var file_path = xfile.path;
var file_ext = path.extname(path.basename(file_orig_name)).toLowerCase(); //Get extension
if (!_.includes(jsh.Config.valid_extensions, file_ext)) { return Helper.GenError(req, res, -32, 'File extension is not supported.'); }
async.waterfall([
async.apply(HelperFS.createFolderIfNotExists, cmsfiles_folder),
async.apply(HelperFS.clearFiles, public_folder, jsh.Config.public_temp_expiration, -1),
function (callback) {
fs.exists(cmsfiles_folder + file_orig_name, function (exists) {
if (exists) return callback({ number: -37, message: 'File already exists' });
else return callback(null);
});
},
function (callback) { HelperFS.rename(file_path, (cmsfiles_folder + file_orig_name), callback); }
], function (err, rslt) {
//Handle error or return result
if (err) {
if (_.isObject(err) && ('number' in err) && (err.number == -36)) return Helper.GenError(req, res, -36, 'User exceeded max temp folder size');
else if (_.isObject(err) && ('number' in err) && (err.number == -37)) return res.send('File name already exists on server - cannot overwrite');
return Helper.GenError(req, res, -99999, 'Error occurred during file operation (' + err.toString() + ')');
}
else {
var rhtml = '\
<script type="text/javascript">\
(function(){\
var funcNum = ' + req.query.CKEditorFuncNum + ';\
var url = "' + Helper.getFullURL(req, req.baseurl) + 'cmsfiles/' + file_orig_name + '";\
var message = "Uploaded file successfully";\
window.parent.CKEDITOR.tools.callFunction(funcNum, url, message);\
})();\
</script>';
return res.end(rhtml);
}
});
});
};
exports.ClearUpload = function (req, res) {
var jsh = this.jsh;
if (!('_DBContext' in req) || (req._DBContext == '') || (req._DBContext == null)) { return Helper.GenError(req, res, -30, 'Invalid file upload request.'); }
var user_folder = jsh.Config.datadir + 'temp/' + req._DBContext + '/';
HelperFS.clearFiles(user_folder, -1, -1, function (err) {
res.type('json');
res.end(JSON.stringify({ '_success': 1 }));
});
};
exports.DefaultThumbnail = function (req, res, fext) {
var svgContent = '<?xml version="1.0" encoding="utf-8"?>\
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"\
width="87.25px" height="116.75px" viewBox="0 0 87.25 116.75" enable-background="new 0 0 87.25 116.75" xml:space="preserve">\
<style>.jsh_svgtxt_small { font: 12px sans-serif; }</style>\
<polygon fill="#FAFBFB" stroke="#999999" stroke-miterlimit="10" points="0.5,0.5 0.5,116.25 86.75,116.25 86.75,25.5 62,0.5 "/>\
<polyline fill="#F1F0F0" stroke="#999999" stroke-width="0.7" stroke-miterlimit="10" points="62,0.75 62,25.75 86.75,25.75 "/>\
<path fill="#F1F0F0" stroke="#999999" stroke-miterlimit="10" d="M62,0.75"/>\
<path fill="#F1F0F0" stroke="#999999" stroke-miterlimit="10" d="M86.75,25.75"/>\
<text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle" class="jsh_svgtxt_small">'+Helper.escapeHTML(Helper.trim(fext||'','.'))+'</text>\
</svg>\
';
res.writeHead(200, {
'Content-Type': 'image/svg+xml',
'Content-Length': svgContent.length,
});
res.end(svgContent);
};
exports.Download = function (req, res, fullmodelid, keyid, fieldid, options) {
if (!options) options = {};
if (!('_DBContext' in req) || (req._DBContext == '') || (req._DBContext == null)) { return Helper.GenError(req, res, -10, 'Invalid Login / Not Authenticated'); }
if (!keyid) return Helper.GenError(req, res, -33, 'Download file not found.');
if (req.query && (req.query.format=='js')) req.jsproxyid = 'xfiledownloader';
var _this = this;
var jsh = this.jsh;
var serveFile = function (req, res, fpath, fname, fext) {
var serveoptions = {};
if (options.view || options.source){
serveoptions = { attachment: false, mime_override: fext };
if(fext && (fext in jsh.Config.file_viewers)){
if(jsh.Config.file_viewers[fext](jsh, req, res, options, fpath, fname) !== false) return;
}
}
HelperFS.outputFile(req, res, fpath, fname, function (err) {
//Only executes upon error
if (err != null) {
if (('code' in err) && (err.code == 'ENOENT')){
if('thumb' in options){ return exports.DefaultThumbnail(req, res, fext); }
return Helper.GenError(req, res, -33, 'Download file not found.');
}
return Helper.GenError(req, res, -99999, 'Error occurred during file operation (' + err.toString() + ')');
}
}, serveoptions);
};
if (fullmodelid == '_temp') {
var fname = path.basename(keyid);
var file_ext = path.extname(fname).toLowerCase(); //Get extension
if ((file_ext == '') || (!_.includes(jsh.Config.valid_extensions, file_ext))) { return Helper.GenError(req, res, -32, 'File extension is not supported.'); }
var fpath = jsh.Config.datadir + 'temp/' + req._DBContext + '/' + fname;
if(('thumb' in options) && !_.includes(jsh.Config.supported_images, file_ext)){ return exports.DefaultThumbnail(req, res, file_ext); }
serveFile(req, res, fpath, fname, file_ext);
}
else {
if (!this.jsh.hasModel(req, fullmodelid)) throw new Error('Error: Model ' + fullmodelid + ' not found in collection.');
var model = this.jsh.getModel(req, fullmodelid);
var db = this.jsh.getModelDB(req, fullmodelid);
var dbcontext = this.jsh.getDBContext(req, model, db);
//Verify model access
if (!Helper.hasModelAction(req, model, 'B')) { Helper.GenError(req, res, -11, _this._tP('Invalid Model Access for @fullmodelid', { fullmodelid })); return; }
if (model.unbound) { Helper.GenError(req, res, -11, 'Cannot run database queries on unbound models'); return; }
//Get key name
var keylist = this.getKeyNames(model.fields);
var keys = this.getFieldsByName(model.fields, keylist);
if (keys.length != 1) throw new Error('File downloads require one key');
var filelist = this.getFileFieldNames(req, model.fields, 'B');
var fieldlist = [keylist[0]];
//Make sure fieldid is in fields
if (!_.includes(filelist, fieldid)) return Helper.GenError(req, res, -33, 'Download file not found.');
var field = this.getFieldByName(model.fields, fieldid);
if (!('controlparams' in field)) { throw new Error('File ' + fieldid + ' missing controlparams'); }
if (!('sqlparams' in field.controlparams)) { throw new Error('File ' + fieldid + ' missing sqlparams'); }
if ('file_extension' in field.controlparams.sqlparams) { fieldlist.push(field.controlparams.sqlparams.file_extension); }
if ('file_name' in field.controlparams.sqlparams) { fieldlist.push(field.controlparams.sqlparams.file_name); }
//Get row from database
var sql_ptypes = [];
var sql_params = {};
var verrors = {};
var datalockqueries = [];
var fields = _this.getFieldsByName(model.fields, fieldlist);
//Add DataLock parameters to SQL
this.getDataLockSQL(req, model, model.fields, sql_ptypes, sql_params, verrors, function (datalockquery) { datalockqueries.push(datalockquery); });
//Add keys as SQL parameters
var keyfield = keys[0];
var keyname = keyfield.name;
var dbtype = _this.getDBType(keyfield);
sql_ptypes.push(dbtype);
sql_params[keyname] = this.DeformatParam(keyfield, keyid, verrors);
verrors = _.merge(verrors, model.xvalidate.Validate('K', sql_params));
if (!_.isEmpty(verrors)) { Helper.GenError(req, res, -2, verrors[''].join('\n')); return; }
var sql = db.sql.Download(_this.jsh, model, fields, keys, datalockqueries);
this.ExecRow(dbcontext, sql, sql_ptypes, sql_params, function (err, rslt) {
//Get extension, filename
if(err) jsh.Log.error(err);
if ((rslt == null) || (rslt.length != 1) || (rslt[0] == null)) { return Helper.GenError(req, res, -33, 'Download file not found.'); }
var fname = keyid;
if ('file_name' in field.controlparams.sqlparams) { fname = rslt[0][field.controlparams.sqlparams.file_name]; }
else if ('file_extension' in field.controlparams.sqlparams) { fname += rslt[0][field.controlparams.sqlparams.file_extension]; }
var fpath = jsh.Config.datadir + field.controlparams.data_folder + '/' + (field.controlparams.data_file_prefix||fieldid) + '_' + keyid;
if ('thumb' in options) {
if(('show_thumbnail' in field.controlparams) && (field.controlparams.show_thumbnail===options.thumb)){
fpath = jsh.Config.datadir + field.controlparams.data_folder + '/' + (field.controlparams.data_file_prefix||fieldid) + '_' + field.controlparams.show_thumbnail + '_' + keyid;
}
else if (field.controlparams.thumbnails) for (var tname in field.controlparams.thumbnails) {
fpath = jsh.Config.datadir + field.controlparams.data_folder + '/' + (field.controlparams.data_file_prefix||fieldid) + '_' + tname + '_' + keyid;
break;
}
}
if (field.controlparams._data_file_has_extension) fpath += '%%%EXT%%%';
HelperFS.getExtFileName(fpath, function(err, filename){
if(err) return Helper.GenError(req, res, -33, 'Download file not found.');
var fext = path.extname(filename);
if(field.controlparams._data_file_has_extension && !('file_extension' in field.controlparams.sqlparams)) fname += fext;
if(!fext) fext = path.extname(fname);
serveFile(req, res, filename, fname, fext);
});
}, undefined, db);
}
};
exports.ProcessFileParams = function (req, res, model, P, fieldlist, sql_extfields, sql_extvalues, fileops, vfiles, file, filecallback) {
var _this = this;
var jsh = this.jsh;
var field = this.getFieldByName(model.fields, file);
//Validate File field
if (file in P) {
if (!('controlparams' in field)) { throw new Error('File ' + file + ' missing controlparams'); }
if (!('sqlparams' in field.controlparams)) { throw new Error('File ' + file + ' missing sqlparams'); }
if ('file_size' in field.controlparams.sqlparams) {
if (!_.includes(fieldlist, field.controlparams.sqlparams.file_size)) fieldlist.push(field.controlparams.sqlparams.file_size);
if (!this.getFieldByName(model.fields, field.controlparams.sqlparams.file_size)) throw new Error(file + ' file_size parameter not defined as a field');
}
if ('file_extension' in field.controlparams.sqlparams) {
if (!_.includes(fieldlist, field.controlparams.sqlparams.file_extension)) fieldlist.push(field.controlparams.sqlparams.file_extension);
if (!this.getFieldByName(model.fields, field.controlparams.sqlparams.file_extension)) throw new Error(file + ' file_extension parameter not defined as a field');
}
if ('file_upload_timestamp' in field.controlparams.sqlparams) {
if (!_.includes(sql_extfields, field.controlparams.sqlparams.file_upload_timestamp)){
if (_.includes(fieldlist, field.controlparams.sqlparams.file_upload_timestamp)) Helper.remove(fieldlist, field.controlparams.sqlparams.file_upload_timestamp);
sql_extfields.push(field.controlparams.sqlparams.file_upload_timestamp);
if (!this.getFieldByName(model.fields, field.controlparams.sqlparams.file_upload_timestamp)) throw new Error(file + ' file_upload_timestamp parameter not defined as a field');
var sql_TSTMP = _this.getSQL(model, jsh.map.timestamp);
if(!sql_TSTMP) throw new Error('SQL macro '+jsh.map.timestamp+' needs to be defined: function should return timestamp for upload');
sql_extvalues.push(_this.getSQL(model, sql_TSTMP));
}
}
if ('file_upload_user' in field.controlparams.sqlparams) {
if (!_.includes(sql_extfields, field.controlparams.sqlparams.file_upload_user)){
if (_.includes(fieldlist, field.controlparams.sqlparams.file_upload_user)) Helper.remove(fieldlist, field.controlparams.sqlparams.file_upload_user);
sql_extfields.push(field.controlparams.sqlparams.file_upload_user);
if (!this.getFieldByName(model.fields, field.controlparams.sqlparams.file_upload_user)) throw new Error(file + ' file_upload_user parameter not defined as a field');
var sql_CUSER = _this.getSQL(model, jsh.map.current_user);
if(!sql_CUSER) throw new Error('SQL macro '+jsh.map.current_user+' needs to be defined: function should return User ID for upload');
sql_extvalues.push(sql_CUSER);
}
}
if (!('_DBContext' in req) || (req._DBContext == '') || (req._DBContext == null)) { return filecallback(Helper.GenError(req, res, -10, 'Invalid Login / Not Authenticated')); }
var filedest = jsh.Config.datadir + field.controlparams.data_folder + '/' + (field.controlparams.data_file_prefix||file) + '_%%%KEY%%%';
if (field.controlparams._data_file_has_extension) filedest += '%%%EXT%%%';
if (P[file] == '') {
if ('file_size' in field.controlparams.sqlparams) {
if (field.controlparams.sqlparams.file_size in P) throw new Error('Parameter conflict - ' + field.controlparams.sqlparams.file_size);
P[field.controlparams.sqlparams.file_size] = null;
}
if ('file_extension' in field.controlparams.sqlparams) {
if (field.controlparams.sqlparams.file_extension in P) throw new Error('Parameter conflict - ' + field.controlparams.sqlparams.file_extension);
P[field.controlparams.sqlparams.file_extension] = null;
}
//Delete File in main operation
fileops.push({ op: 'move', src: '', dest: filedest });
//Delete Thumbnails in main operation
if (field.controlparams.thumbnails) for (var tname in field.controlparams.thumbnails) {
var tdest = jsh.Config.datadir + field.controlparams.data_folder + '/' + (field.controlparams.data_file_prefix||field.name) + '_' + tname + '_%%%KEY%%%';
if (field.controlparams._data_file_has_extension) filedest += '%%%EXT%%%';
fileops.push({ op: 'move', src: '', dest: tdest });
}
filecallback(null);
}
else {
var fpath = '';
//Separate model.id, keyid
if (P[file].indexOf('_temp/') != 0) { return Helper.GenError(req, res, -34, 'File path not supported'); }
var filekeyid = P[file].substr(('_temp/').length);
var fname = path.basename(filekeyid);
var file_ext = path.extname(fname).toLowerCase(); //Get extension
if ((file_ext == '') || (!_.includes(jsh.Config.valid_extensions, file_ext))) { return filecallback(Helper.GenError(req, res, -32, 'File extension is not supported.')); }
fpath = jsh.Config.datadir + 'temp/' + req._DBContext + '/' + fname;
//Validate file exists, get stats (size + ext)
HelperFS.getFileStats(req, res, fpath, function (err, stat) {
if (err != null) { return filecallback(Helper.GenError(req, res, -33, 'File not found.')); }
//Add parameters, make sure they don't conflict with existing parameters
var file_size = stat.size;
if ('file_size' in field.controlparams.sqlparams) {
if (field.controlparams.sqlparams.file_size in P) throw new Error('Parameter conflict - ' + field.controlparams.sqlparams.file_size);
P[field.controlparams.sqlparams.file_size] = file_size;
}
if ('file_extension' in field.controlparams.sqlparams) {
if (field.controlparams.sqlparams.file_extension in P) throw new Error('Parameter conflict - ' + field.controlparams.sqlparams.file_extension);
P[field.controlparams.sqlparams.file_extension] = file_ext;
}
//Perform validation, if necessary - MaxSize, Extension, Required
vfiles[file] = {
size: file_size,
ext: file_ext
};
//Create Thumbnails, if applicable
if (field.controlparams.thumbnails) for (var tname in field.controlparams.thumbnails) {
var tdest = jsh.Config.datadir + field.controlparams.data_folder + '/' + (field.controlparams.data_file_prefix||field.name) + '_' + tname + '_%%%KEY%%%';
if (field.controlparams._data_file_has_extension) tdest += '.' + field.controlparams.thumbnails[tname].format;
if (_.includes(jsh.Config.supported_images, file_ext)) {
if (field.controlparams.thumbnails[tname].resize) fileops.push({ op: 'img_resize', src: fpath, dest: tdest, size: field.controlparams.thumbnails[tname].resize, format: field.controlparams.thumbnails[tname].format });
else if (field.controlparams.thumbnails[tname].crop) fileops.push({ op: 'img_crop', src: fpath, dest: tdest, size: field.controlparams.thumbnails[tname].crop, format: field.controlparams.thumbnails[tname].format });
else throw new Error('No thumbnail resize or crop operation in ' + field.name);
}
else {
fileops.push({ op: 'move', src: '', dest: tdest });
}
}
//Resize Image, if applicable
if (field.controlparams.image && _.includes(jsh.Config.supported_images, file_ext)) {
filedest = Helper.ReplaceAll(filedest, '%%%EXT%%%', '.' + field.controlparams.image.format);
if (field.controlparams.image.resize) fileops.push({ op: 'img_resize', src: fpath, dest: filedest, size: field.controlparams.image.resize, format: field.controlparams.image.format });
else if (field.controlparams.image.crop) fileops.push({ op: 'img_crop', src: fpath, dest: filedest, size: field.controlparams.image.crop, format: field.controlparams.image.format });
else fileops.push({ op: 'img_resample', src: fpath, dest: filedest, format: field.controlparams.image.format });
fileops.push({ op: 'delete_on_complete', src: fpath });
}
else {
//On completion (of entire SQL statement), move file (Add another dbtask to be executed)
filedest = Helper.ReplaceAll(filedest, '%%%EXT%%%', file_ext);
fileops.push({ op: 'move', src: fpath, dest: filedest });
}
filecallback(null);
});
}
}
else filecallback(null);
};
exports.ProcessFileOperations = function (keyval, fileops, rslt, stats, callback) {
var jsh = this.jsh;
if ((typeof keyval == 'undefined') || !keyval) return callback(Helper.NewError('Invalid file key', -13), null);
async.each(fileops, function (fileop, opcallback) {
var filesrc = '';
var filedest = '';
if (fileop.src) filesrc = Helper.ReplaceAll(fileop.src, '%%%KEY%%%', keyval);
if (fileop.dest) filedest = Helper.ReplaceAll(fileop.dest, '%%%KEY%%%', keyval);
async.waterfall([
function(filehandlercb){
//Get src file extension
HelperFS.getExtFileName(filesrc, function(err, filename){
if(err) return callback(Helper.NewError('File not found', -33));
filesrc = filename;
return filehandlercb();
});
},
function(filehandlercb){
//Get dest file extension
HelperFS.getExtFileName(filedest, function(err, filename){
if(err) return callback(Helper.NewError('File not found', -33));
filedest = filename;
return filehandlercb();
});
},
], function(){
if (fileop.op == 'move') {
HelperFS.copyFile(fileop.src, filedest, function (fileerr) {
if (fileerr != null) return opcallback(fileerr);
return opcallback(null);
});
}
else if (fileop.op == 'img_resample'){
jsh.Extensions.image.resample(filesrc, filedest, fileop.format, opcallback);
}
else if (fileop.op == 'img_crop') {
jsh.Extensions.image.crop(filesrc, filedest, fileop.size, fileop.format, opcallback);
}
else if (fileop.op == 'img_resize') {
jsh.Extensions.image.resize(filesrc, filedest, fileop.size, fileop.format, opcallback);
}
else return opcallback(null);
});
}, function (fileerr) {
if ((fileerr != null) && ('code' in fileerr) && (fileerr.code == 'ENOENT')) { /* Ignore this error */ }
else if (fileerr != null) {
jsh.Log.error(fileerr);
return callback(Helper.NewError('Error committing file update.', -35), null);
}
return callback(null, rslt, stats);
});
};
exports.ProcessFileOperationsDone = function (fileops, callback) {
async.eachSeries(fileops, function (fileop, opcallback) {
if ((fileop.op == 'move') || (fileop.op == 'delete_on_complete')) {
if (fileop.src == '') return opcallback(null);
HelperFS.unlink(fileop.src, function (err) { opcallback(null); });
}
else return opcallback(null);
}, function (err) { callback(null, null); });
};
return module.exports;