gridfs.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. const logger = require('@alias/logger')('growi:service:fileUploaderGridfs');
  2. const mongoose = require('mongoose');
  3. const util = require('util');
  4. module.exports = function(crowi) {
  5. 'use strict';
  6. const lib = {};
  7. // instantiate mongoose-gridfs
  8. const gridfs = require('mongoose-gridfs')({
  9. collection: 'attachmentFiles',
  10. model: 'AttachmentFile',
  11. mongooseConnection: mongoose.connection
  12. });
  13. // obtain a model
  14. const AttachmentFile = gridfs.model;
  15. const Chunks = mongoose.model('Chunks', gridfs.schema, 'attachmentFiles.chunks');
  16. // create promisified method
  17. AttachmentFile.promisifiedWrite = util.promisify(AttachmentFile.write).bind(AttachmentFile);
  18. lib.deleteFile = async function(attachment) {
  19. let filenameValue = attachment.fileName;
  20. if (attachment.filePath != null) { // backward compatibility for v3.3.x or below
  21. filenameValue = attachment.filePath;
  22. }
  23. const attachmentFile = await AttachmentFile.findOne({ filename: filenameValue });
  24. AttachmentFile.unlinkById(attachmentFile._id, function(error, unlinkedFile) {
  25. if (error) {
  26. throw new Error(error);
  27. }
  28. });
  29. };
  30. /**
  31. * get size of data uploaded files using (Promise wrapper)
  32. */
  33. const getCollectionSize = () => {
  34. return new Promise((resolve, reject) => {
  35. Chunks.collection.stats((err, data) => {
  36. if (err) {
  37. reject(err);
  38. }
  39. resolve(data.size);
  40. });
  41. });
  42. };
  43. /**
  44. * chech storage for fileUpload reaches MONGO_GRIDFS_TOTAL_LIMIT (for gridfs)
  45. */
  46. lib.checkCapacity = async(uploadFileSize) => {
  47. // skip checking if env var is undefined
  48. if (process.env.MONGO_GRIDFS_TOTAL_LIMIT == null) {
  49. return true;
  50. }
  51. const usingFilesSize = await getCollectionSize();
  52. return (+process.env.MONGO_GRIDFS_TOTAL_LIMIT > usingFilesSize + +uploadFileSize);
  53. };
  54. lib.uploadFile = async function(fileStream, attachment) {
  55. logger.debug(`File uploading: fileName=${attachment.fileName}`);
  56. return AttachmentFile.promisifiedWrite(
  57. {
  58. filename: attachment.fileName,
  59. contentType: attachment.fileFormat
  60. },
  61. fileStream);
  62. };
  63. /**
  64. * Find data substance
  65. *
  66. * @param {Attachment} attachment
  67. * @return {stream.Readable} readable stream
  68. */
  69. lib.findDeliveryFile = async function(attachment) {
  70. let filenameValue = attachment.fileName;
  71. if (attachment.filePath != null) { // backward compatibility for v3.3.x or below
  72. filenameValue = attachment.filePath;
  73. }
  74. const attachmentFile = await AttachmentFile.findOne({ filename: filenameValue });
  75. if (attachmentFile == null) {
  76. throw new Error(`Any AttachmentFile that relate to the Attachment (${attachment._id.toString()}) does not exist in GridFS`);
  77. }
  78. // return stream.Readable
  79. return AttachmentFile.readById(attachmentFile._id);
  80. };
  81. return lib;
  82. };