diff --git a/client/components/boards/boardsList.js b/client/components/boards/boardsList.js index c6ce48af6..b1dcc2d79 100644 --- a/client/components/boards/boardsList.js +++ b/client/components/boards/boardsList.js @@ -260,7 +260,7 @@ BlazeComponent.extendComponent({ }, (err, res) => { if (err) { - self.setError(err.error); + console.error(err); } else { Session.set('fromBoard', null); subManager.subscribe('board', res, false); @@ -268,7 +268,6 @@ BlazeComponent.extendComponent({ id: res, slug: title, }); - //Utils.goBoardId(res); } }, ); diff --git a/models/cards.js b/models/cards.js index c6bf0cdd7..0b926f4b6 100644 --- a/models/cards.js +++ b/models/cards.js @@ -5,7 +5,8 @@ import { TYPE_LINKED_BOARD, TYPE_LINKED_CARD, } from '../config/const'; -import Attachments from "./attachments"; +import Attachments, { fileStoreStrategyFactory } from "./attachments"; +import { copyFile } from './lib/fileStoreStrategy.js'; Cards = new Mongo.Collection('cards'); @@ -586,11 +587,11 @@ Cards.helpers({ const _id = Cards.insert(this); // Copy attachments - oldCard.attachments().forEach(att => { - att.cardId = _id; - delete att._id; - return Attachments.insert(att); - }); + oldCard.attachments() + .map(att => att.get()) + .forEach(att => { + copyFile(att, _id, fileStoreStrategyFactory); + }); // copy checklists Checklists.find({ cardId: oldId }).forEach(ch => { diff --git a/models/lib/fileStoreStrategy.js b/models/lib/fileStoreStrategy.js index 5ec438fa3..e184b2fdf 100644 --- a/models/lib/fileStoreStrategy.js +++ b/models/lib/fileStoreStrategy.js @@ -336,3 +336,55 @@ export const moveToStorage = function(fileObj, storageDestination, fileStoreStra } }); }; + +export const copyFile = function(fileObj, newCardId, fileStoreStrategyFactory) { + const versionName = "original"; + const strategyRead = fileStoreStrategyFactory.getFileStrategy(fileObj, versionName); + const readStream = strategyRead.getReadStream(); + const strategyWrite = fileStoreStrategyFactory.getFileStrategy(fileObj, versionName, STORAGE_NAME_FILESYSTEM); + + const tempPath = path.join(fileStoreStrategyFactory.storagePath, Random.id() + "-" + versionName + "-" + fileObj.name); + const writeStream = strategyWrite.getWriteStream(tempPath); + + writeStream.on('error', error => { + console.error('[writeStream error]: ', error, fileObj._id); + }); + + readStream.on('error', error => { + console.error('[readStream error]: ', error, fileObj._id); + }); + + // https://forums.meteor.com/t/meteor-code-must-always-run-within-a-fiber-try-wrapping-callbacks-that-you-pass-to-non-meteor-libraries-with-meteor-bindenvironmen/40099/8 + readStream.on('end', Meteor.bindEnvironment(() => { + const fileId = Random.id(); + Attachments.addFile( + tempPath, + { + fileName: fileObj.name, + type: fileObj.type, + meta: { + boardId: fileObj.meta.boardId, + cardId: newCardId, + listId: fileObj.meta.listId, + swimlaneId: fileObj.meta.swimlaneId, + source: 'copy', + copyFrom: fileObj._id, + }, + userId: fileObj.userId, + size: fileObj.fileSize, + fileId, + }, + (err, fileRef) => { + if (err) { + console.log(err); + } else { + // Set the userId again + Attachments.update({ _id: fileRef._id }, { $set: { userId: fileObj.userId } }); + } + }, + true, + ); + })); + + readStream.pipe(writeStream); +};