Skip to content

Instantly share code, notes, and snippets.

@trev-dev
Last active November 16, 2017 00:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save trev-dev/649dc1a10d6894c7d6dfe74d7b7c7cb2 to your computer and use it in GitHub Desktop.
Save trev-dev/649dc1a10d6894c7d6dfe74d7b7c7cb2 to your computer and use it in GitHub Desktop.
Image upload example
var express = require('express');
var config = require('./modules/config');
var routes = require('./modules/routes'); // Using all routes as an exported function. See routes.js.
var db = require('./modules/db.js');
var app = express();
app.set('view engine', 'pug');
app.use('/form', express.static(`${__dirname}/static`));
app.use('/form/form', express.static(`${__dirname}/static`));
// app.use('/static', express.static(`${__dirname}/static`));
app.use('/uploads', express.static(`${__dirname}/uploads`));
routes(app, config, db); // Running routes module with the app, config and database objects. Webroutes are found in routes.js.
db.sql.sync().then(function(){
app.listen(config.port, function(){
console.log(`Express running on ${config.port}`);
});
});
var jimp = require('jimp'); // Image manipulation middleware
var imageSize = require('image-size'); // Image size tester
var fs = require('fs');
function renameImage(img) {
function pruneExtension (name) { // Capture the file extension.
var ext = name.split('.');
ext = ext[ext.length - 1];
return `.${ext}`;
}
img.extension = pruneExtension(img.originalname); // Store extension on img object
img.oldPath = img.path; // Preserve the original image path
img.newPath = `${img.oldPath}${img.extension}`; // Create new path
fs.renameSync(img.oldPath, img.newPath); // move/rename file.
}
}
module.exports = { // Export
adjustImage: function(img){ // The method that this module uses to rename, resize and move images.
// it then resolves with the final location of the image.
renameImage(img); // Rename the image to include the extension
return new Promise(function(resolve, reject){ // Start promise chain.
var size = imageSize(img.newPath);
if (size.width < 1000) { // When the image is under 1000px wide, simply resolve the new path for the file.
resolve(img.newPath);
} else { // Image is too big. Resize it!
jimp.read(img.newPath, function(err, image){
if (err) {
reject(err);
}
img.newPath = `${img.oldPath}-jimp${img.extension}`; // adapt newPath to include a -jimp tag in the file name.
image.resize(1000, jimp.AUTO).quality(60).write(img.newPath, ()=>{ // Resize the image to 1000px and compress it.
// Write new image to a separate file.
fs.unlinkSync(`${img.oldPath}${img.extension}`); // delete the original image.
resolve(img.newPath); //resolve the new compressed image.
});
});
}
});
}
};
var Shopify = require('shopify-node-api');
var security = require('./security')();
var url = require('url');
var multer = require('multer'); // For extrapolating multipart files from the req.body.
var autoReap = require('multer-autoreap');
var bodyParser = require('body-parser');
var fs = require('fs');
var mkdirp = require('mkdirp');
var upload = multer({dest:'uploads/tmp'}); // setup multer with a file destination as "upload" object.
var image = require('./images'); // Import image module. See image.js
var form = require('./form');
var _ = require('underscore');
module.exports = function(app, config, db) { // express post route for image uploading
// THE ROUTE WHERE LEAKAGE IS SUSPECTED. Problem is probably either here, or some aspect of image.js.
app.post(['/upload/:store/:name', '/form/upload/:store/:name'], upload.array('images', 6) /* multer middleware */, function(req, res){
var shop = req.params.store;
var name = req.params.name;
var promises = [];
// Generate promise array loaded with image handling promises
req.files.forEach(function(cur){
// take the files from req.files and build a queue of image.adjustImage() methods - see image.js.
promises.push(image.adjustImage(cur));
});
// Iterate through all the promises for the uploaded images, then execute code when done
// This is done to ensure image handling is completed for each async image.adjustImage() before returning
// the href paths in a JSON array to the front end to be displayed there.
Promise.all(promises).then((paths)=>{
var dir = `./uploads/${shop}/${name}`;
// If destination path does not exist, make it so.
if (!fs.existsSync(dir)) {
mkdirp.sync(dir);
}
// Delete old image files in destination folder
oldfiles = fs.readdirSync(dir);
oldfiles.forEach(function(cur){
fs.unlinkSync(`${dir}/${cur}`);
});
// For each of the newly uploaded image files, move them to the destination folder.
paths.forEach(function(cur){
fileName = cur.split('/').pop();
fs.renameSync(`./${cur}`, `${dir}/${fileName}`);
});
// Send array of image files to front end.
var newPaths = fs.readdir(dir, function(err, files){
files = files.map(function(cur){
return `${dir}/${cur}`.slice(1);
});
res.json(files);
});
}).catch(function(err){
console.log(err);
});
});
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment