attachment.js 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. const debug = require('debug')('growi:models:attachment');
  2. const logger = require('@alias/logger')('growi:models:attachment');
  3. const path = require('path');
  4. const mongoose = require('mongoose');
  5. const ObjectId = mongoose.Schema.Types.ObjectId;
  6. module.exports = function(crowi) {
  7. const fileUploader = require('../service/file-uploader')(crowi);
  8. let attachmentSchema;
  9. function generateFileHash(fileName) {
  10. const hash = require('crypto').createHash('md5');
  11. hash.update(`${fileName}_${Date.now()}`);
  12. return hash.digest('hex');
  13. }
  14. attachmentSchema = new mongoose.Schema({
  15. page: { type: ObjectId, ref: 'Page', index: true },
  16. creator: { type: ObjectId, ref: 'User', index: true },
  17. filePath: { type: String }, // DEPRECATED: remains for backward compatibility for v3.3.7 or below
  18. fileName: { type: String, required: true },
  19. originalName: { type: String },
  20. fileFormat: { type: String, required: true },
  21. fileSize: { type: Number, default: 0 },
  22. createdAt: { type: Date, default: Date.now() },
  23. });
  24. attachmentSchema.virtual('filePathProxied').get(function() {
  25. return `/attachment/${this._id}`;
  26. });
  27. attachmentSchema.virtual('downloadPathProxied').get(function() {
  28. return `/download/${this._id}`;
  29. });
  30. attachmentSchema.statics.create = async function(pageId, user, fileStream, originalName, fileFormat, fileSize) {
  31. const Attachment = this;
  32. const extname = path.extname(originalName);
  33. let fileName = generateFileHash(originalName);
  34. if (extname.length > 1) { // ignore if empty or '.' only
  35. fileName = `${fileName}${extname}`;
  36. }
  37. let attachment = new Attachment();
  38. attachment.page = pageId;
  39. attachment.creator = user._id;
  40. attachment.originalName = originalName;
  41. attachment.fileName = fileName;
  42. attachment.fileFormat = fileFormat;
  43. attachment.fileSize = fileSize;
  44. attachment.createdAt = Date.now();
  45. // upload file
  46. await fileUploader.uploadFile(fileStream, attachment);
  47. // save attachment
  48. attachment = await attachment.save();
  49. return attachment;
  50. };
  51. attachmentSchema.statics.removeAttachmentsByPageId = function(pageId) {
  52. var Attachment = this;
  53. return new Promise((resolve, reject) => {
  54. Attachment.find({ page: pageId})
  55. .then((attachments) => {
  56. for (let attachment of attachments) {
  57. attachment.removeWithSubstance().then((res) => {
  58. // do nothing
  59. }).catch((err) => {
  60. debug('Attachment remove error', err);
  61. });
  62. }
  63. resolve(attachments);
  64. }).catch((err) => {
  65. reject(err);
  66. });
  67. });
  68. };
  69. attachmentSchema.methods.removeWithSubstance = async function() {
  70. await fileUploader.deleteFile(this);
  71. return await this.remove();
  72. };
  73. return mongoose.model('Attachment', attachmentSchema);
  74. };