Skip to content

Instantly share code, notes, and snippets.

@cesarandreu
Created May 2, 2015 05:36
Show Gist options
  • Save cesarandreu/5f87558f0f7545aca6cc to your computer and use it in GitHub Desktop.
Save cesarandreu/5f87558f0f7545aca6cc to your computer and use it in GitHub Desktop.
var fs = require('fs')
var Joi = require('joi')
var _ = require('lodash')
var Router = require('koa-router')
var middleware = require('../middleware')
var bodyParser = require('koa-better-body')
module.exports = BikeshedsController
function BikeshedsController () {
var auth = middleware.authenticate()
var bodyFile = bodyParser({
multipart: true,
formidable: {
multiples: true
}
})
var routes = new Router()
.post(
'/bikesheds',
auth,
bodyFile,
BikeshedsController.create
)
return routes.middleware()
}
/**
* POST /bikesheds
*/
BikeshedsController.create = function* create () {
var {Bikeshed, Bike} = this.models
var {user} = this.state
var s3 = this.s3
var body = this.request.body
var schema = BikeshedsController.create.schema
var value = yield (cb) => Joi.validate(body, schema, cb)
var bikeshed = yield new Bikeshed({
description: value.fields.description,
userId: user.id,
bikes: _.map(value.files, file => {
return new Bike({
type: file.type,
size: file.size,
name: file.name
})
})
}).saveAll()
bikeshed.bikes = yield bikeshed.bikes.map(bike => {
var file = value.files[bike.name]
return BikeshedsController.create.uploadBike({
bike, file, s3
})
})
if (_.every(bikeshed.bikes, {status: 'success'})) {
bikeshed.status = 'success'
this.status = 201
} else {
bikeshed.status = 'error'
this.status = 503
}
this.body = yield bikeshed.saveAll()
}
/**
* uploadBike
* Try uploading file to s3
* Sets bike status to success or error
* Tries deleting failed file uploads
*
* @param options.bike
* @param options.file
* @param options.s3
* @returns bike
*/
BikeshedsController.create.uploadBike = function* uploadBike ({bike, file, s3}={}) {
var Key = `${bike.bikeshedId}/${bike.id}`
var Bucket = 'bshed'
var uploadFileOptions = {
Body: fs.createReadStream(file.path),
ACL: 'public-react',
Bucket, Key
}
try {
yield s3.uploadFilePromise(uploadFileOptions)
bike.status = 'success'
} catch (err) {
console.log('ERROR UPLOAD BIKE', err)
bike.status = 'error'
try {
yield s3.deleteObjectPromise({Bucket, Key})
} catch (err) {
console.log('ERROR DELETING BIKE', err)
}
}
return bike
}
/**
* Create bikeshed schema
* Check validation on ctx.request.body
*/
BikeshedsController.create.schema = Joi.object().keys({
files: Joi.object().min(2).max(5).required(),
fields: Joi.object().default({}).keys({
description: Joi.string().default('')
})
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment