| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280 | 
							- import { ReactiveCache } from '/imports/reactiveCache';
 
- import { Meteor } from 'meteor/meteor';
 
- import { MongoInternals } from 'meteor/mongo';
 
- /**
 
-  * Backward compatibility layer for CollectionFS to Meteor-Files migration
 
-  * Handles reading attachments from old CollectionFS database structure
 
-  */
 
- // Old CollectionFS collections
 
- const OldAttachmentsFiles = new Mongo.Collection('cfs_gridfs.attachments.files');
 
- const OldAttachmentsFileRecord = new Mongo.Collection('cfs.attachments.filerecord');
 
- /**
 
-  * Check if an attachment exists in the new Meteor-Files structure
 
-  * @param {string} attachmentId - The attachment ID to check
 
-  * @returns {boolean} - True if exists in new structure
 
-  */
 
- export function isNewAttachmentStructure(attachmentId) {
 
-   if (Meteor.isServer) {
 
-     return !!ReactiveCache.getAttachment(attachmentId);
 
-   }
 
-   return false;
 
- }
 
- /**
 
-  * Get attachment data from old CollectionFS structure
 
-  * @param {string} attachmentId - The attachment ID
 
-  * @returns {Object|null} - Attachment data in new format or null if not found
 
-  */
 
- export function getOldAttachmentData(attachmentId) {
 
-   if (Meteor.isServer) {
 
-     try {
 
-       // First try to get from old filerecord collection
 
-       const fileRecord = OldAttachmentsFileRecord.findOne({ _id: attachmentId });
 
-       if (!fileRecord) {
 
-         return null;
 
-       }
 
-       // Get file data from old files collection
 
-       const fileData = OldAttachmentsFiles.findOne({ _id: attachmentId });
 
-       if (!fileData) {
 
-         return null;
 
-       }
 
-       // Convert old structure to new structure
 
-       const convertedAttachment = {
 
-         _id: attachmentId,
 
-         name: fileRecord.original?.name || fileData.filename || 'Unknown',
 
-         size: fileRecord.original?.size || fileData.length || 0,
 
-         type: fileRecord.original?.type || fileData.contentType || 'application/octet-stream',
 
-         extension: getFileExtension(fileRecord.original?.name || fileData.filename || ''),
 
-         extensionWithDot: getFileExtensionWithDot(fileRecord.original?.name || fileData.filename || ''),
 
-         meta: {
 
-           boardId: fileRecord.boardId,
 
-           swimlaneId: fileRecord.swimlaneId,
 
-           listId: fileRecord.listId,
 
-           cardId: fileRecord.cardId,
 
-           userId: fileRecord.userId,
 
-           source: 'legacy'
 
-         },
 
-         uploadedAt: fileRecord.uploadedAt || fileData.uploadDate || new Date(),
 
-         updatedAt: fileRecord.original?.updatedAt || fileData.uploadDate || new Date(),
 
-         // Legacy compatibility fields
 
-         isImage: isImageFile(fileRecord.original?.type || fileData.contentType),
 
-         isVideo: isVideoFile(fileRecord.original?.type || fileData.contentType),
 
-         isAudio: isAudioFile(fileRecord.original?.type || fileData.contentType),
 
-         isText: isTextFile(fileRecord.original?.type || fileData.contentType),
 
-         isJSON: isJSONFile(fileRecord.original?.type || fileData.contentType),
 
-         isPDF: isPDFFile(fileRecord.original?.type || fileData.contentType),
 
-         // Legacy link method for compatibility
 
-         link: function(version = 'original') {
 
-           return `/cfs/files/attachments/${this._id}`;
 
-         },
 
-         // Legacy versions structure for compatibility
 
-         versions: {
 
-           original: {
 
-             path: `/cfs/files/attachments/${this._id}`,
 
-             size: this.size,
 
-             type: this.type,
 
-             storage: 'gridfs'
 
-           }
 
-         }
 
-       };
 
-       return convertedAttachment;
 
-     } catch (error) {
 
-       console.error('Error reading old attachment data:', error);
 
-       return null;
 
-     }
 
-   }
 
-   return null;
 
- }
 
- /**
 
-  * Get file extension from filename
 
-  * @param {string} filename - The filename
 
-  * @returns {string} - File extension without dot
 
-  */
 
- function getFileExtension(filename) {
 
-   if (!filename) return '';
 
-   const lastDot = filename.lastIndexOf('.');
 
-   if (lastDot === -1) return '';
 
-   return filename.substring(lastDot + 1).toLowerCase();
 
- }
 
- /**
 
-  * Get file extension with dot
 
-  * @param {string} filename - The filename
 
-  * @returns {string} - File extension with dot
 
-  */
 
- function getFileExtensionWithDot(filename) {
 
-   const ext = getFileExtension(filename);
 
-   return ext ? `.${ext}` : '';
 
- }
 
- /**
 
-  * Check if file is an image
 
-  * @param {string} mimeType - MIME type
 
-  * @returns {boolean} - True if image
 
-  */
 
- function isImageFile(mimeType) {
 
-   return mimeType && mimeType.startsWith('image/');
 
- }
 
- /**
 
-  * Check if file is a video
 
-  * @param {string} mimeType - MIME type
 
-  * @returns {boolean} - True if video
 
-  */
 
- function isVideoFile(mimeType) {
 
-   return mimeType && mimeType.startsWith('video/');
 
- }
 
- /**
 
-  * Check if file is audio
 
-  * @param {string} mimeType - MIME type
 
-  * @returns {boolean} - True if audio
 
-  */
 
- function isAudioFile(mimeType) {
 
-   return mimeType && mimeType.startsWith('audio/');
 
- }
 
- /**
 
-  * Check if file is text
 
-  * @param {string} mimeType - MIME type
 
-  * @returns {boolean} - True if text
 
-  */
 
- function isTextFile(mimeType) {
 
-   return mimeType && mimeType.startsWith('text/');
 
- }
 
- /**
 
-  * Check if file is JSON
 
-  * @param {string} mimeType - MIME type
 
-  * @returns {boolean} - True if JSON
 
-  */
 
- function isJSONFile(mimeType) {
 
-   return mimeType === 'application/json';
 
- }
 
- /**
 
-  * Check if file is PDF
 
-  * @param {string} mimeType - MIME type
 
-  * @returns {boolean} - True if PDF
 
-  */
 
- function isPDFFile(mimeType) {
 
-   return mimeType === 'application/pdf';
 
- }
 
- /**
 
-  * Get attachment with backward compatibility
 
-  * @param {string} attachmentId - The attachment ID
 
-  * @returns {Object|null} - Attachment data or null if not found
 
-  */
 
- export function getAttachmentWithBackwardCompatibility(attachmentId) {
 
-   // First try new structure
 
-   if (isNewAttachmentStructure(attachmentId)) {
 
-     return ReactiveCache.getAttachment(attachmentId);
 
-   }
 
-   // Fall back to old structure
 
-   return getOldAttachmentData(attachmentId);
 
- }
 
- /**
 
-  * Get attachments for a card with backward compatibility
 
-  * @param {Object} query - Query object
 
-  * @returns {Array} - Array of attachments
 
-  */
 
- export function getAttachmentsWithBackwardCompatibility(query) {
 
-   const newAttachments = ReactiveCache.getAttachments(query);
 
-   const oldAttachments = [];
 
-   if (Meteor.isServer) {
 
-     try {
 
-       // Query old structure for the same card
 
-       const cardId = query['meta.cardId'];
 
-       if (cardId) {
 
-         const oldFileRecords = OldAttachmentsFileRecord.find({ cardId }).fetch();
 
-         for (const fileRecord of oldFileRecords) {
 
-           const oldAttachment = getOldAttachmentData(fileRecord._id);
 
-           if (oldAttachment) {
 
-             oldAttachments.push(oldAttachment);
 
-           }
 
-         }
 
-       }
 
-     } catch (error) {
 
-       console.error('Error reading old attachments:', error);
 
-     }
 
-   }
 
-   // Combine and deduplicate
 
-   const allAttachments = [...newAttachments, ...oldAttachments];
 
-   const uniqueAttachments = allAttachments.filter((attachment, index, self) =>
 
-     index === self.findIndex(a => a._id === attachment._id)
 
-   );
 
-   return uniqueAttachments;
 
- }
 
- /**
 
-  * Get file stream from old GridFS structure
 
-  * @param {string} attachmentId - The attachment ID
 
-  * @returns {Object|null} - GridFS file stream or null if not found
 
-  */
 
- export function getOldAttachmentStream(attachmentId) {
 
-   if (Meteor.isServer) {
 
-     try {
 
-       const db = MongoInternals.defaultRemoteCollectionDriver().mongo.db;
 
-       const bucket = new MongoInternals.NpmModule.GridFSBucket(db, {
 
-         bucketName: 'cfs_gridfs.attachments'
 
-       });
 
-       const downloadStream = bucket.openDownloadStreamByName(attachmentId);
 
-       return downloadStream;
 
-     } catch (error) {
 
-       console.error('Error creating GridFS stream:', error);
 
-       return null;
 
-     }
 
-   }
 
-   return null;
 
- }
 
- /**
 
-  * Get file data from old GridFS structure
 
-  * @param {string} attachmentId - The attachment ID
 
-  * @returns {Buffer|null} - File data buffer or null if not found
 
-  */
 
- export function getOldAttachmentDataBuffer(attachmentId) {
 
-   if (Meteor.isServer) {
 
-     try {
 
-       const db = MongoInternals.defaultRemoteCollectionDriver().mongo.db;
 
-       const bucket = new MongoInternals.NpmModule.GridFSBucket(db, {
 
-         bucketName: 'cfs_gridfs.attachments'
 
-       });
 
-       return new Promise((resolve, reject) => {
 
-         const chunks = [];
 
-         const downloadStream = bucket.openDownloadStreamByName(attachmentId);
 
-         downloadStream.on('data', (chunk) => {
 
-           chunks.push(chunk);
 
-         });
 
-         downloadStream.on('end', () => {
 
-           resolve(Buffer.concat(chunks));
 
-         });
 
-         downloadStream.on('error', (error) => {
 
-           reject(error);
 
-         });
 
-       });
 
-     } catch (error) {
 
-       console.error('Error reading GridFS data:', error);
 
-       return null;
 
-     }
 
-   }
 
-   return null;
 
- }
 
 
  |