UNPKG

node-image-farmer

Version:

Image thumbnailing middleware based on connect-thumb. Adds ability to retrieve files from the filesystem.

142 lines (127 loc) 6.01 kB
var fileRetriever = require('./file-retriever'), imageModifier = require('./image-modifier'), mkdirp = require('mkdirp'), moment = require('moment'), crypto = require('crypto'), fs = require('fs'), debug = require('debug')('node-image-farmer:node-image-farmer'); if(!Promise){ var Promise = require('es6-promise').Promise; } var imageFarmer = { /** * Return cryptographic hash (defaulting to: "sha1") of a string. * * @param {String} str * @param {String} algo - Algorithm used for hashing, defaults to sha1 * @param {String} encoding - defaults to hex * @return {String} */ hash: function(str, algo, encoding) { return crypto .createHash(algo || 'sha1') .update(str) .digest(encoding || 'hex'); }, processOptions: function(options, appConfig){ var hashedName = imageFarmer.hash(options.originalUrl); // This is to be safe, in case somebody uses risky encodeFn var hashedOriginalName = imageFarmer.hash(options.imageUrl || options.imagePath); // We prefer the imageUrl above imagePath if it's defineed var imagePreset = ( options.preset || "full" ); var preset = (imagePreset ? "-" + imagePreset : ""); var targetDir = appConfig.tmpDir + '/'+( imagePreset || "full" ); var fullDir = appConfig.tmpDir + '/full'; var filepath = fullDir + '/' + hashedOriginalName + "." + options.extension; var modifiedFilePath = targetDir + '/' + hashedName + preset + "." + options.extension; var processOptions = { filepath: filepath, modifiedFilePath: modifiedFilePath, fullDir: fullDir, targetDir: targetDir, preset: imagePreset, hashedOriginalName: hashedOriginalName, hashedName: hashedName }; debug("-----------------STARTING FARMING PROCESS-------------------"); return imageFarmer.createDirectories(options, appConfig).then(function(){ debug("Directories created..."); // see if we can serve the file from file cache, if ttl has not yet expired var fileStream = null; if (appConfig.tmpCacheTTL > 0) { debug("tmpCacheTTL is being used..."); return imageFarmer.tempProcess(fileStream, processOptions, options, appConfig); }else { return imageFarmer.fullProcess(fileStream, processOptions, options, appConfig); } }); }, fullProcess: function(fileStream, processOptions, options, appConfig){ debug("Trying to get full file..."); return new Promise(function(resolve, reject){ fileRetriever.getFullFile(processOptions.filepath, appConfig).then(function(){ debug("Got full file, modifying image..."); //process full file //pass the raw filestream to another function maybe? if(appConfig.useMultipleProcesses){ debug("--Using multiple processes..."); return imageModifier.modifyImageProcess(processOptions, options, appConfig); }else{ return imageModifier.modifyImage(processOptions, options, appConfig); } }).then(function(){ debug("Image modification is complete, getting the temp file..."); //send temp file resolve(fileRetriever.getTempFile(processOptions.modifiedFilePath, options, appConfig)); }).catch(function(err){ debug("--Couldn't get full file, trying actual..."); //can't get the full file, try the actual file fileRetriever.getFile(processOptions, options).then(function(fileStream){ debug("--Got actual file..."); //resize file if(appConfig.useMultipleProcesses){ debug("--Using multiple processes..."); return imageModifier.modifyImageProcess(processOptions, options, appConfig); }else{ return imageModifier.modifyImage(processOptions, options, appConfig); } }).then(function(){ debug("--Using temp file..."); resolve(fileRetriever.getTempFile(processOptions.modifiedFilePath, options, appConfig)); }).catch(function(err){ debug("Failed to process file.", err); reject(err); }); }); }); }, tempProcess: function(fileStream, processOptions, options, appConfig){ debug("Trying to get temp file..."); return fileRetriever.getTempFile(processOptions.modifiedFilePath, options, appConfig).catch(function(){ debug("--Couldn't get temp file..."); return imageFarmer.fullProcess(fileStream, processOptions, options, appConfig); }); }, createDirectories: function(options, appConfig){ return new Promise(function(resolve, reject){ var targetDir = appConfig.tmpDir + '/'+( options.preset || "full" ); var fullDir = appConfig.tmpDir + '/full'; // create the full directory mkdirp(fullDir, function (err) { if (err) { err.responseCode = 500; reject(err); }else{ //we can chain these because we want the full folder before the preset folder anyway. mkdirp(targetDir, function (err) { if (err) { err.responseCode = 500; reject(err); }else { resolve(); } }); } }); }); } }; module.exports = imageFarmer;