images.controllers.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /** logic for image routes */
  2. import multer from 'multer';
  3. import Image from "../models/image.model.js";
  4. import { v2 as cloudinary } from 'cloudinary';
  5. import dotenv from 'dotenv';
  6. import path from 'path';
  7. import DatauriParser from 'datauri/parser.js';
  8. dotenv.config();
  9. const dUri = new DatauriParser();
  10. const dataUri = req => dUri.format(path.extname(req.file.originalname).toString(), req.file.buffer);
  11. cloudinary.config({
  12. cloud_name: process.env.CLOUDINARY_CLOUD_NAME,
  13. api_key: process.env.CLOUDINARY_API_KEY,
  14. api_secret: process.env.CLOUDINARY_API_SECRET,
  15. });
  16. const storage = multer.memoryStorage();
  17. /*
  18. const imageFileFilter = (req, file, cb) => {
  19. console.log("File in filter", file);
  20. if (file.mimetype === 'image/jpeg' || file.mimetype === 'image/jpg' || file.mimetype === 'image/png') {
  21. cb(null, true);
  22. } else {
  23. cb(null, false);
  24. }
  25. }*/
  26. export const upload = multer({
  27. storage: storage,
  28. limits: {
  29. // Allow upload files under 10MB
  30. fileSize: 10485760,
  31. },
  32. // fileFilter: imageFileFilter,
  33. });
  34. export const uploadSingleImage = async (req, res) => {
  35. const image = dataUri(req).content;
  36. const { category, categoryId, tags, name } = req.body;
  37. const folderName = category && categoryId ? category + '/' + categoryId : req.params.folder;
  38. const uploadOptions = {
  39. folder: folderName,
  40. tags: tags || [],
  41. };
  42. if (category === 'userProfile') {
  43. uploadOptions.folder = category;
  44. uploadOptions.public_id = categoryId;
  45. uploadOptions.overwrite = true;
  46. uploadOptions.transformation = { aspect_ratio: 1, gravity: "faces", crop: "fill" };
  47. }
  48. cloudinary.uploader.upload(image, uploadOptions).then((cloudinaryImage) => {
  49. console.log('upload successful');
  50. const { public_id, secure_url, url } = cloudinaryImage;
  51. const newImage = new Image({
  52. categoryName: category,
  53. categoryId,
  54. url: secure_url || url,
  55. cloudinaryPublicId: public_id,
  56. name,
  57. });
  58. try {
  59. newImage.save().then(() => {
  60. console.log('added image to ' + folderName, public_id, name);
  61. res.status(201).json({ 'message': 'successfully added new Image', 'Image': newImage })
  62. });
  63. } catch (error) {
  64. res.status(409).json({ message: error.message, errorDetails: 'upload successful, but database storage failed' });
  65. }
  66. }).catch((error) => {
  67. res.status(409).json({ message: error.message, errorDetails: 'upload failed' });
  68. });
  69. }
  70. async function copySingleImage(image, category, newId) {
  71. let returnImage = null;
  72. if (image.url) {
  73. await cloudinary.uploader.upload(image.url, { folder: category + '/' + newId }).then(async (cloudinaryImage) => {
  74. console.log('upload successful');
  75. const { public_id, secure_url, url } = cloudinaryImage;
  76. const newImage = new Image({
  77. categoryName: category,
  78. categoryId: newId,
  79. url: secure_url || url,
  80. cloudinaryPublicId: public_id,
  81. name: image.name,
  82. });
  83. await newImage.save().then((savedImage) => {
  84. returnImage = savedImage;
  85. }).catch((error) => {
  86. console.log('upload of copied image successful, but database storage failed', 'error:', error.message);
  87. });
  88. }).catch((error) => {
  89. console.log('image upload failed because ', error);
  90. });
  91. }
  92. return returnImage;
  93. }
  94. export const copyImagesForCategory = async (req, res) => {
  95. let { category, oldId, newId } = req.params;
  96. let newImages = [];
  97. await Image.find({ categoryName: category, categoryId: oldId }, async function (err, foundImages) {
  98. if (err) {
  99. console.log('error in find', err);
  100. } else {
  101. newImages = await Promise.all(foundImages.map(async (i) => {
  102. return await copySingleImage(i, 'mealImages', newId)
  103. }));
  104. if (newImages.length > 0) {
  105. res.status(201).json({ 'message': 'successfully copied Images', newImages });
  106. } else {
  107. res.status(400).json({ 'info': `copying images failed. Check log for more info` });
  108. }
  109. }
  110. });
  111. }
  112. export const deleteSingleImage = async (req, res) => {
  113. const image = req.body;
  114. Image.findByIdAndDelete(image._id, {}, function (err, deletionResult) {
  115. if (err) {
  116. res.status(400).json({ 'info': `Deletion of image ${image._id} failed`, 'message': err.message });
  117. } else {
  118. cloudinary.uploader.destroy(image.cloudinaryPublicId).then((result) => {
  119. res.status(201).json({ 'info': 'image deleted', deletionResult, cloudinaryResult: result });
  120. }).catch(error => {
  121. console.log('image deleted from database but not from cloudinary: ', image, 'reason', error);
  122. res.status(201).json({ 'info': 'image deleted from database but not from cloudinary', 'cloudinaryError': error });
  123. });
  124. }
  125. });
  126. }
  127. export const deleteAllImagesFromCategory = async (req, res) => {
  128. let category = req.params.category;
  129. let id = req.params.id;
  130. console.log('delete all images from ', category, id);
  131. await Image.find({ categoryName: category, categoryId: id }, function (err, foundImages) {
  132. if (err) {
  133. console.log('error in find', err);
  134. } else {
  135. foundImages.forEach(i => {
  136. cloudinary.uploader.destroy(i.cloudinaryPublicId).then((result) => {
  137. console.log(i.name + ' deleted from cloudinary');
  138. }).catch(error => {
  139. console.log('deletion of ' + i.name + ' from cloudinary failed because', error);
  140. });
  141. });
  142. }
  143. })
  144. await cloudinary.api.delete_folder(category + '/' + id);
  145. Image.deleteMany({ categoryName: category, categoryId: id }, {}, function (err, deletionResult) {
  146. if (err) {
  147. res.status(400).json({ 'info': `Deletion of images from ${category} ${id} failed`, 'message': err.message });
  148. } else {
  149. res.status(201).json({ 'info': `images from ${category} with ${id} deleted`, deletionResult })
  150. }
  151. });
  152. }