| 
					
				 | 
			
			
				@@ -2,8 +2,9 @@ const Papa = require('papaparse'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 // exporter maybe is broken since Gridfs introduced, add fs and path 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 export class Exporter { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  constructor(boardId) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  constructor(boardId, attachmentId) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     this._boardId = boardId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this._attachmentId = attachmentId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   build() { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -33,6 +34,62 @@ export class Exporter { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       }), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // [Old] for attachments we only export IDs and absolute url to original doc 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // [New] Encode attachment to base64 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const getBase64Data = function(doc, callback) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      let buffer = Buffer.allocUnsafe(0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      buffer.fill(0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // callback has the form function (err, res) {} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      const tmpFile = path.join( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        os.tmpdir(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        `tmpexport${process.pid}${Math.random()}`, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      const tmpWriteable = fs.createWriteStream(tmpFile); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      const readStream = doc.createReadStream(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      readStream.on('data', function(chunk) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        buffer = Buffer.concat([buffer, chunk]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      readStream.on('error', function() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        callback(null, null); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      readStream.on('end', function() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // done 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        fs.unlink(tmpFile, () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          //ignored 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        callback(null, buffer.toString('base64')); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      readStream.pipe(tmpWriteable); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const getBase64DataSync = Meteor.wrapAsync(getBase64Data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const byBoardAndAttachment = this._attachmentId 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ? { boardId: this._boardId, _id: this._attachmentId } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      : byBoard; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    result.attachments = Attachments.find(byBoardAndAttachment) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      .fetch() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      .map(attachment => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let filebase64 = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        filebase64 = getBase64DataSync(attachment); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          _id: attachment._id, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          cardId: attachment.cardId, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          //url: FlowRouter.url(attachment.url()), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          file: filebase64, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          name: attachment.original.name, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          type: attachment.original.type, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    //When has a especific valid attachment return the single element 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (this._attachmentId) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return result.attachments.length > 0 ? result.attachments[0] : {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     result.lists = Lists.find(byBoard, noBoardId).fetch(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     result.cards = Cards.find(byBoardNoLinked, noBoardId).fetch(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     result.swimlanes = Swimlanes.find(byBoard, noBoardId).fetch(); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -84,54 +141,6 @@ export class Exporter { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // [Old] for attachments we only export IDs and absolute url to original doc 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // [New] Encode attachment to base64 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const getBase64Data = function(doc, callback) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      let buffer = Buffer.allocUnsafe(0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      buffer.fill(0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // callback has the form function (err, res) {} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      const tmpFile = path.join( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        os.tmpdir(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        `tmpexport${process.pid}${Math.random()}`, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      const tmpWriteable = fs.createWriteStream(tmpFile); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      const readStream = doc.createReadStream(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      readStream.on('data', function(chunk) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        buffer = Buffer.concat([buffer, chunk]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      readStream.on('error', function() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        callback(null, null); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      readStream.on('end', function() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // done 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        fs.unlink(tmpFile, () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          //ignored 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        callback(null, buffer.toString('base64')); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      readStream.pipe(tmpWriteable); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const getBase64DataSync = Meteor.wrapAsync(getBase64Data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    result.attachments = Attachments.find(byBoard) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      .fetch() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      .map(attachment => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        let filebase64 = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        filebase64 = getBase64DataSync(attachment); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          _id: attachment._id, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          cardId: attachment.cardId, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          //url: FlowRouter.url(attachment.url()), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          file: filebase64, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          name: attachment.original.name, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          type: attachment.original.type, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     // we also have to export some user data - as the other elements only 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     // include id but we have to be careful: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     // 1- only exports users that are linked somehow to that board 
			 |