gridfs.js 4.4 KB

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