Last active
August 29, 2015 14:09
-
-
Save t2k/ae28bda9e194976ced03 to your computer and use it in GitHub Desktop.
Async Parallel Image Processing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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