diff --git a/middleware/Pictures.js b/middleware/Pictures.js new file mode 100644 index 0000000..0c8f6e2 --- /dev/null +++ b/middleware/Pictures.js @@ -0,0 +1,191 @@ +const pictures = require('../models').vegetablePictures +const multer = require('multer') +const Vegetables = require('./Vegetables') +const path = require('path') +const fs = require('fs') +const Aws = require('../libs/aws') +const uuid = require('uuid/v4') + +class Pictures { + constructor () { + this._upload = multer({ + storage: multer.diskStorage({}), + fileFilter: function (req, file, cb) { + const filetypes = /jpg|jpeg|png|JPG|JPEG|PNG/ + const mimetype = filetypes.test(file.mimetype) + const extname = filetypes.test(path.extname(file.originalname).toLowerCase()) + + if (mimetype && extname) { + return cb(null, true) + } + cb(new Error('Error: File upload only supports the following filetypes - ' + filetypes)) + } + }).single('picture') + } + + _reOrderPictures (position, vegetableId) { + pictures.findAll({ + where: { + vegetableId: vegetableId + } + }) + .then(items => { + items.forEach((item) => { + let itemPosition = item.order + if (itemPosition >= position) { + item.update({ order: itemPosition - 1 }) + .catch((e) => { + console.log(e) + }) + } + }) + }) + .catch((error) => { + console.log(error) + }) + } + + static getAll (req, callback) { + Vegetables.getOne(req, (err, item) => { + if (err) { + callback(err, item) + return false + } + + pictures.findAndCountAll({ + where: { + vegetableId: req.params.vegetablesId + }, + order: [ + ['order', 'ASC'] + ] + }) + .then(items => { + if (!items) { + callback(new Error('No picture found'), 204) + return false + } + callback(null, items) + }) + .catch((e) => { + callback(e, null) + }) + }) + } + + static getOne (req, callback) { + Vegetables.getOne(req, (err, item) => { + if (err) { + callback(err, item) + return false + } + + pictures.find({ + where: { + id: req.params.pictureId, + vegetableId: req.params.vegetablesId + }, + order: [ + ['order', 'ASC'] + ] + }) + .then(item => { + if (!item) { + callback(new Error('Picture not found'), 404) + return false + } + callback(null, item) + }) + .catch((e) => { + callback(e, null) + }) + }) + } + + createOne (req, callback) { + Vegetables.getOne(req, (err, item) => { + if (err) { + callback(err, item) + return false + } + + Pictures.getAll(req, (err, items) => { + if (err) { + callback(err, item) + return false + } + + const order = items.count + 1 + + this._upload(req, req.body, (err) => { + if (err) { + callback(err, null) + return false + } + + if (req.file) { + let aws = new Aws() + aws.upload({ + path: req.file.path, + filename: `picture_${req.params.vegetablesId}_${uuid()}.${req.file.originalname.split('.')[req.file.originalname.split('.').length - 1]}` + }, (err, res) => { + if (err) { callback(err, null) } + + pictures.create({ + order: order, + url: res.file, + vegetableId: req.params.vegetablesId + }) + .then(item => { + callback(null, item) + }) + .catch(e => { + callback(e, null) + }) + fs.unlink(req.file.path, () => {}) + }) + } else { + callback(new Error('No file sent'), 406) + } + }) + }) + }) + } + + deleteOne (req, callback) { + Pictures.getOne(req, (err, item) => { + if (err) { + callback(err, item) + return false + } + + const aws = new Aws() + + aws.deleteObjects([item.url], (err) => { + if (err) { + callback(err, null) + return false + } + + pictures.destroy({ + where: { + id: req.params.pictureId + } + }) + .then(deleted => { + if (deleted === 0) { + callback(new Error('Error when trying to delete item')) + return false + } + + callback(null, null) + }) + .catch(e => { + callback(e, null) + }) + }) + }) + } +} + +module.exports = Pictures diff --git a/migrations/20180907185320-create-vegetables_pictures.js b/migrations/20180907185320-create-vegetables_pictures.js index c0e4b1a..eebcbd7 100644 --- a/migrations/20180907185320-create-vegetables_pictures.js +++ b/migrations/20180907185320-create-vegetables_pictures.js @@ -13,7 +13,7 @@ module.exports = { order: { type: Sequelize.INTEGER }, - vegetablesId: { + vegetableId: { type: Sequelize.INTEGER, references: { model: 'vegetables', key: 'id' } }, diff --git a/models/vegetables.js b/models/vegetables.js index 55d8d41..157f3d4 100644 --- a/models/vegetables.js +++ b/models/vegetables.js @@ -18,7 +18,7 @@ module.exports = (sequelize, DataTypes) => { }) vegetables.hasMany(models.vegetablePictures, { as: 'Pictures', - foreignKey: 'vegetablesId', + foreignKey: 'vegetableId', onDelete: 'cascade' }) } diff --git a/models/vegetables_pictures.js b/models/vegetables_pictures.js index 52a600b..846e53d 100644 --- a/models/vegetables_pictures.js +++ b/models/vegetables_pictures.js @@ -2,14 +2,17 @@ module.exports = (sequelize, DataTypes) => { const vegetablePictures = sequelize.define('vegetablePictures', { url: DataTypes.STRING, order: DataTypes.INTEGER, - vegetablesId: { + vegetableId: { type: DataTypes.INTEGER, references: 'vegetables', referencesKey: 'id' } }, {}) - vegetablePictures.associate = function (models) { - vegetablePictures.hasOne(models.vegetables, { as: 'Vegetables', foreignKey: 'id' }) + vegetablePictures.associate = function(models) { + vegetablePictures.hasOne(models.vegetables, { + as: 'Vegetables', + foreignKey: 'id' + }) } return vegetablePictures } diff --git a/routes/vegetables.js b/routes/vegetables.js index 44290fb..1db5eb9 100644 --- a/routes/vegetables.js +++ b/routes/vegetables.js @@ -1,15 +1,18 @@ const express = require('express') const router = express.Router() -const VegetableTypes = require('../middleware/Vegetables') +const Vegetables = require('../middleware/Vegetables') +const Pictures = require('../middleware/Pictures') module.exports = function (passport) { - const basePath = '/api/types/:vegetableTypesId/vegetables/' - const itemPath = basePath + ':vegetablesId' + const basePath = '/api/types/:vegetableTypesId/vegetables' + const itemPath = basePath + '/:vegetablesId' + const picturesPath = itemPath + '/pictures' + const picturePath = picturesPath + '/:pictureId' router.route(basePath) .get( function (req, res) { - VegetableTypes.getAll(req, function (err, items) { + Vegetables.getAll(req, function (err, items) { if (err) { res.status(items || 500).send(err.message) } else { @@ -21,8 +24,8 @@ module.exports = function (passport) { .post( passport.authenticate(['basic-auth']), function (req, res) { - const vegetableTypes = new VegetableTypes() - vegetableTypes.createOne(req, function (err, item) { + const vegetable = new Vegetables() + vegetable.createOne(req, function (err, item) { if (err) { res.status(item || 500).send(err.message) } else { @@ -35,7 +38,7 @@ module.exports = function (passport) { router.route(itemPath) .get( function (req, res) { - VegetableTypes.getOne(req, function (err, item) { + Vegetables.getOne(req, function (err, item) { if (err) { res.status(item || 500).send(err.message) } else { @@ -47,8 +50,8 @@ module.exports = function (passport) { .patch( passport.authenticate(['basic-auth']), function (req, res) { - const vegetableTypes = new VegetableTypes() - vegetableTypes.patchOne(req, function (err, item) { + const vegetable = new Vegetables() + vegetable.patchOne(req, function (err, item) { if (err) { res.status(item || 500).send(err.message) } else { @@ -60,8 +63,60 @@ module.exports = function (passport) { .delete( passport.authenticate(['basic-auth']), function (req, res) { - const vegetableTypes = new VegetableTypes() - vegetableTypes.deleteOne(req, function (err, item) { + const vegetable = new Vegetables() + vegetable.deleteOne(req, function (err, item) { + if (err) { + res.status(item || 500).send(err.message) + } else { + res.status(200).json(item) + } + }) + } + ) + + router.route(picturesPath) + .get( + function (req, res) { + Pictures.getAll(req, function (err, item) { + if (err) { + res.status(item || 500).send(err.message) + } else { + res.status(200).json(item) + } + }) + } + ) + .post( + passport.authenticate(['basic-auth']), + function (req, res) { + const picture = new Pictures() + picture.createOne(req, function (err, item) { + if (err) { + res.status(item || 500).send(err.message) + } else { + res.status(201).json(item) + } + }) + } + ) + + router.route(picturePath) + .get( + function (req, res) { + Pictures.getOne(req, function (err, item) { + if (err) { + res.status(item || 500).send(err.message) + } else { + res.status(200).json(item) + } + }) + } + ) + .delete( + passport.authenticate(['basic-auth']), + function (req, res) { + const picture = new Pictures() + picture.deleteOne(req, function (err, item) { if (err) { res.status(item || 500).send(err.message) } else {