attachments.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. import { FilesCollection } from 'meteor/ostrio:files';
  2. const fs = require('fs');
  3. const collectionName = 'attachments2';
  4. Attachments = new FilesCollection({
  5. storagePath: storagePath(),
  6. debug: false,
  7. // allowClientCode: true,
  8. collectionName: 'attachments2',
  9. onAfterUpload: onAttachmentUploaded,
  10. onBeforeRemove: onAttachmentRemoving
  11. });
  12. if (Meteor.isServer) {
  13. Meteor.startup(() => {
  14. Attachments.collection._ensureIndex({ cardId: 1 });
  15. });
  16. // TODO: Permission related
  17. Attachments.allow({
  18. insert() {
  19. return false;
  20. },
  21. update() {
  22. return true;
  23. },
  24. remove() {
  25. return true;
  26. }
  27. });
  28. Meteor.methods({
  29. cloneAttachment(file, overrides) {
  30. check(file, Object);
  31. check(overrides, Match.Maybe(Object));
  32. const path = file.path;
  33. const opts = {
  34. fileName: file.name,
  35. type: file.type,
  36. meta: file.meta,
  37. userId: file.userId
  38. };
  39. for (let key in overrides) {
  40. if (key === 'meta') {
  41. for (let metaKey in overrides.meta) {
  42. opts.meta[metaKey] = overrides.meta[metaKey];
  43. }
  44. } else {
  45. opts[key] = overrides[key];
  46. }
  47. }
  48. const buffer = fs.readFileSync(path);
  49. Attachments.write(buffer, opts, (err, fileRef) => {
  50. if (err) {
  51. console.log('Error when cloning record', err);
  52. }
  53. });
  54. return true;
  55. }
  56. });
  57. Meteor.publish(collectionName, function() {
  58. return Attachments.find().cursor;
  59. });
  60. } else {
  61. Meteor.subscribe(collectionName);
  62. }
  63. function storagePath(defaultPath) {
  64. const storePath = process.env.ATTACHMENTS_STORE_PATH;
  65. return storePath ? storePath : defaultPath;
  66. }
  67. function onAttachmentUploaded(fileRef) {
  68. Attachments.update({_id:fileRef._id}, {$set: {"meta.uploading": false}});
  69. if (!fileRef.meta.source || fileRef.meta.source !== 'import') {
  70. // Add activity about adding the attachment
  71. Activities.insert({
  72. userId: fileRef.userId,
  73. type: 'card',
  74. activityType: 'addAttachment',
  75. attachmentId: fileRef._id,
  76. // this preserves the name so that notifications can be meaningful after
  77. // this file is removed
  78. attachmentName: fileRef.name,
  79. boardId: fileRef.meta.boardId,
  80. cardId: fileRef.meta.cardId,
  81. listId: fileRef.meta.listId,
  82. swimlaneId: fileRef.meta.swimlaneId,
  83. });
  84. } else {
  85. // Don't add activity about adding the attachment as the activity
  86. // be imported and delete source field
  87. Attachments.collection.update(
  88. {
  89. _id: fileRef._id,
  90. },
  91. {
  92. $unset: {
  93. 'meta.source': '',
  94. },
  95. },
  96. );
  97. }
  98. }
  99. function onAttachmentRemoving(cursor) {
  100. const file = cursor.get()[0];
  101. const meta = file.meta;
  102. Activities.insert({
  103. userId: this.userId,
  104. type: 'card',
  105. activityType: 'deleteAttachment',
  106. attachmentId: file._id,
  107. // this preserves the name so that notifications can be meaningful after
  108. // this file is removed
  109. attachmentName: file.name,
  110. boardId: meta.boardId,
  111. cardId: meta.cardId,
  112. listId: meta.listId,
  113. swimlaneId: meta.swimlaneId,
  114. });
  115. return true;
  116. }
  117. export default Attachments;