Created
May 2, 2015 05:36
-
-
Save cesarandreu/5f87558f0f7545aca6cc to your computer and use it in GitHub Desktop.
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
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