gridfs.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  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. const Uploader = require('./uploader');
  6. const lib = new Uploader(crowi);
  7. const COLLECTION_NAME = 'attachmentFiles';
  8. // const CHUNK_COLLECTION_NAME = `${COLLECTION_NAME}.chunks`;
  9. // instantiate mongoose-gridfs
  10. const { createModel } = require('mongoose-gridfs');
  11. const AttachmentFile = createModel({
  12. modelName: COLLECTION_NAME,
  13. bucketName: COLLECTION_NAME,
  14. connection: mongoose.connection,
  15. });
  16. // get Collection instance of chunk
  17. // const chunkCollection = mongoose.connection.collection(CHUNK_COLLECTION_NAME);
  18. // create promisified method
  19. AttachmentFile.promisifiedWrite = util.promisify(AttachmentFile.write).bind(AttachmentFile);
  20. AttachmentFile.promisifiedUnlink = util.promisify(AttachmentFile.unlink).bind(AttachmentFile);
  21. lib.isValidUploadSettings = function() {
  22. return true;
  23. };
  24. lib.deleteFile = async function(attachment) {
  25. let filenameValue = attachment.fileName;
  26. if (attachment.filePath != null) { // backward compatibility for v3.3.x or below
  27. filenameValue = attachment.filePath;
  28. }
  29. const attachmentFile = await AttachmentFile.findOne({ filename: filenameValue });
  30. if (attachmentFile == null) {
  31. logger.warn(`Any AttachmentFile that relate to the Attachment (${attachment._id.toString()}) does not exist in GridFS`);
  32. return;
  33. }
  34. return AttachmentFile.promisifiedUnlink({ _id: attachmentFile._id });
  35. };
  36. lib.deleteFiles = async function(attachments) {
  37. attachments.map(async(attachment) => {
  38. return lib.deleteFile(attachment);
  39. });
  40. };
  41. /**
  42. * get size of data uploaded files using (Promise wrapper)
  43. */
  44. // const getCollectionSize = () => {
  45. // return new Promise((resolve, reject) => {
  46. // chunkCollection.stats((err, data) => {
  47. // if (err) {
  48. // // return 0 if not exist
  49. // if (err.errmsg.includes('not found')) {
  50. // return resolve(0);
  51. // }
  52. // return reject(err);
  53. // }
  54. // return resolve(data.size);
  55. // });
  56. // });
  57. // };
  58. /**
  59. * check the file size limit
  60. *
  61. * In detail, the followings are checked.
  62. * - per-file size limit (specified by MAX_FILE_SIZE)
  63. * - mongodb(gridfs) size limit (specified by MONGO_GRIDFS_TOTAL_LIMIT)
  64. */
  65. lib.checkLimit = async(uploadFileSize) => {
  66. const maxFileSize = crowi.configManager.getConfig('crowi', 'app:maxFileSize');
  67. // Use app:fileUploadTotalLimit if gridfs:totalLimit is null (default for gridfs:totalLimitd is null)
  68. const gridfsTotalLimit = crowi.configManager.getConfig('crowi', 'gridfs:totalLimit')
  69. || crowi.configManager.getConfig('crowi', 'app:fileUploadTotalLimit');
  70. return lib.doCheckLimit(uploadFileSize, maxFileSize, gridfsTotalLimit);
  71. };
  72. lib.uploadFile = async function(fileStream, attachment) {
  73. logger.debug(`File uploading: fileName=${attachment.fileName}`);
  74. return AttachmentFile.promisifiedWrite(
  75. {
  76. filename: attachment.fileName,
  77. contentType: attachment.fileFormat,
  78. },
  79. fileStream,
  80. );
  81. };
  82. /**
  83. * Find data substance
  84. *
  85. * @param {Attachment} attachment
  86. * @return {stream.Readable} readable stream
  87. */
  88. lib.findDeliveryFile = async function(attachment) {
  89. let filenameValue = attachment.fileName;
  90. if (attachment.filePath != null) { // backward compatibility for v3.3.x or below
  91. filenameValue = attachment.filePath;
  92. }
  93. const attachmentFile = await AttachmentFile.findOne({ filename: filenameValue });
  94. if (attachmentFile == null) {
  95. throw new Error(`Any AttachmentFile that relate to the Attachment (${attachment._id.toString()}) does not exist in GridFS`);
  96. }
  97. // return stream.Readable
  98. return AttachmentFile.read({ _id: attachmentFile._id });
  99. };
  100. return lib;
  101. };