Skip to content

Instantly share code, notes, and snippets.

@bekatom
Last active August 17, 2018 09:20
Show Gist options
  • Save bekatom/3005a43cf8d262067d5d8722c09f8461 to your computer and use it in GitHub Desktop.
Save bekatom/3005a43cf8d262067d5d8722c09f8461 to your computer and use it in GitHub Desktop.
save image in local drive & upload to s3 - (With image processing to save thumbnail also )
/**
* @apiVersion 1.0.0
* @api {post} /api/v1/helpers/upload-image-s3 image upload to s3
* @apiName post image to s3
* @apiGroup Helpers
* @apiDescription Image Uploading to S3
*
* @apiParam {file} image.
*
* @apiUse defaultSuccessExample200
* @apiUse Errors
*/
async uploadImageS3 (req, res, imageLocationPrefix = '') {
try {
var rs = await this.saveImage(req, res, {
UPLOAD_DIR: config.uploader.localDir,
hasThumbnail: true,
waitThumbnail: true // waits thumbnail image processing
})
const file = rs[0]
const thumbnail = `${file.destination}/thumbnails/${file.filename}`
const remotePath = {
image: `${imageLocationPrefix}/${file.filename}`,
thumbnail: `${imageLocationPrefix}/thumbnails/${file.filename}`
}
// const result = await Uploader.upload(file.path, remotePath.image)
const result = await Uploader.putObject(file.path, remotePath.image)
// NOTE: upload thumbnail to s3 but don't wait it
// TODO: comment temporary
await Uploader.putObject(thumbnail, remotePath.thumbnail)
return {
result,
filename: file.filename,
url: Uploader.getUrl(remotePath.image),
thumbnail: Uploader.getUrl(remotePath.thumbnail)
}
} catch (error) {
return { error }
}
}
/**
* save image with thumbnail in local drive if dir is /tmp then it will be deleted
* @param {Request} req request
* @param {Response} res response
* @param {string} what type of files should be upload ex: "images", "excel"
* @returns {Promise<Express.Multer.File>} file
*/
saveImage (req, res, cfg) {
const { UPLOAD_DIR, hasThumbnail, waitThumbnail } = cfg
if (!fs.existsSync(UPLOAD_DIR)) {
fs.mkdirSync(UPLOAD_DIR)
}
let THUMBNAIL_DIR = `${UPLOAD_DIR}/thumbnails/`
const imageFormats = ['.jpg', '.png', '.jpeg']
if (hasThumbnail) {
if (!fs.existsSync(THUMBNAIL_DIR)) {
fs.mkdirSync(THUMBNAIL_DIR)
}
}
return new Promise((resolve, reject) => {
var storage = multer.diskStorage({
destination: function(req, file, cb) {
cb(null, UPLOAD_DIR)
},
filename: function(req, file, cb) {
crypto.pseudoRandomBytes(16, (err, raw) => {
cb(null, raw.toString('hex') + Date.now() + path.extname(file.originalname))
})
}
})
let upload = multer({
storage: storage,
fileFilter: function(req, file, cb) {
if (!imageFormats.includes(path.extname(file.originalname))) {
return cb(new Error('Only formats .jpg .png are allowed!'))
}
cb(null, true)
}
}).any()
upload(req, res, err => {
if (err) return reject(err)
if (req.files.length === 0) return reject(`There is no files selected!`)
if (!waitThumbnail) { // don't wait image processing for thumbnail
return resolve(req.files)
}
if (hasThumbnail) { // if we have thumbnail then generate it
gm(req.files[0].path)
.resize(240, 240, '!')
.noProfile()
.autoOrient()
.write(`${THUMBNAIL_DIR}/${req.files[0].filename}`, function (err) {
// NOTE: don't wait for this
if (err) return reject(err)
return resolve(req.files)
})
}
})
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment