Skip to content

Instantly share code, notes, and snippets.

@t2k
Last active August 29, 2015 14:09
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save t2k/ae28bda9e194976ced03 to your computer and use it in GitHub Desktop.
Save t2k/ae28bda9e194976ced03 to your computer and use it in GitHub Desktop.
Async Parallel Image Processing
mongoose = require "mongoose"
Busboy = require "busboy"
secrets = require "../config/secrets"
GridStream = require "gridfs-stream"
Files = require "../models/files"
sharp = require "sharp"
async = require "async"
# POST files
# process the uploaded file with nodeJS stream module == Busboy
# pass this file stream from busboy to MongoDB GridFS using mongoose
# gridfs-stream 'writestream',
# Then, using Async.parallel for image processing.
# save multiple resized copies: 'raw', 'desktop', 'tablet', 'mobile', thumb'
exports.mongodbUpload = (req, res, next) ->
FIELDS = ['title','tag']
fieldValues = {}
gridStream = new GridStream(mongoose.connection.db, mongoose.mongo)
busboy = new Busboy
headers: req.headers
limits:
fileSize: 1024 * 1024 * 15
files: 1
#busboy field event
busboy.on 'field', (fieldname, val, fieldNameTrunc, valTrunc) ->
if fieldname in FIELDS
fieldValues[fieldname] = val
#busboy file event
busboy.on "file", (fieldname, stream, filename, encoding, mimetype) ->
async.parallel
raw: (done) ->
writestream = gridStream.createWriteStream
mode: "w"
filename: filename
content_type: mimetype
metadata:
userid: req.user._id
fields: fieldValues
encoding: encoding
size: 'raw'
writestream.on 'error', (err) ->
done err, msg: 'error'
writestream.on "close", (file) ->
done null, file
stream.pipe writestream
desktop: (done) ->
transformer = sharp()
.resize 1920,1080
.crop sharp.gravity.north
writestream = gridStream.createWriteStream
mode: "w"
filename: filename
content_type: mimetype
metadata:
userid: req.user._id
fields: fieldValues
encoding: encoding
size: 'desktop'
writestream.on 'error', (err) ->
done err, msg: 'error'
writestream.on "close", (file) ->
done null, file
stream.pipe(transformer).pipe(writestream)
tablet: (done) ->
transformer = sharp()
.resize 1024,768
.crop sharp.gravity.north
writestream = gridStream.createWriteStream
mode: "w"
filename: filename
content_type: mimetype
metadata:
userid: req.user._id
fields: fieldValues
encoding: encoding
size: 'tablet'
writestream.on 'error', (err) ->
done err, msg: 'error'
writestream.on "close", (file) ->
done null, file
stream.pipe(transformer).pipe(writestream)
mobile: (done) ->
transformer = sharp()
.resize 480,320
.crop sharp.gravity.north
writestream = gridStream.createWriteStream
mode: "w"
filename: filename
content_type: mimetype
metadata:
userid: req.user._id
fields: fieldValues
encoding: encoding
size: 'mobile'
writestream.on 'error', (err) ->
done err, msg: 'error'
writestream.on "close", (file) ->
done null, file
stream.pipe(transformer).pipe(writestream)
thumb: (done) ->
transformer = sharp()
.resize 64,64
.crop sharp.gravity.north
writestream = gridStream.createWriteStream
mode: "w"
filename: filename
content_type: mimetype
metadata:
userid: req.user._id
fields: fieldValues
encoding: encoding
size: 'thumb'
writestream.on 'error', (err) ->
done err, msg: 'error'
writestream.on "close", (file) ->
done null, file
stream.pipe(transformer).pipe(writestream)
, (err, result) ->
return res.status(500).json() if err
# transMutateReconfig into our fileMap
fileMap =
tag: result.raw.metadata.fields.tag
title: result.raw.metadata.fields.title
raw: result.raw._id
desktop: result.desktop._id
tablet: result.tablet._id
mobile: result.mobile._id
thumb: result.thumb._id
# addFile will add the mongo _id via result
req.user.addFile fileMap, (err, result) ->
return res.status(503).json() if err
#created 201
res.status(201).json(newFile: result) # client will newFile prop with
busboy.on "finish", -> # returns async
req.user.fileCacheTime = Date.now()
busboy.on "error", (err)-> # returns async
req.pipe busboy
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment