mirror of
https://github.com/wekan/wekan.git
synced 2025-12-16 15:30:13 +01:00
150 lines
4.4 KiB
JavaScript
150 lines
4.4 KiB
JavaScript
import { Meteor } from 'meteor/meteor';
|
|
import { ReactiveCache } from '/imports/reactiveCache';
|
|
import { getOldAttachmentData, getOldAttachmentDataBuffer } from '/models/lib/attachmentBackwardCompatibility';
|
|
|
|
/**
|
|
* Migration script to convert old CollectionFS attachments to new Meteor-Files structure
|
|
* This script can be run to migrate all old attachments to the new format
|
|
*/
|
|
|
|
if (Meteor.isServer) {
|
|
Meteor.methods({
|
|
/**
|
|
* Migrate a single attachment from old to new structure
|
|
* @param {string} attachmentId - The old attachment ID
|
|
* @returns {Object} - Migration result
|
|
*/
|
|
migrateAttachment(attachmentId) {
|
|
if (!this.userId) {
|
|
throw new Meteor.Error('not-authorized', 'Must be logged in');
|
|
}
|
|
|
|
try {
|
|
// Get old attachment data
|
|
const oldAttachment = getOldAttachmentData(attachmentId);
|
|
if (!oldAttachment) {
|
|
return { success: false, error: 'Old attachment not found' };
|
|
}
|
|
|
|
// Check if already migrated
|
|
const existingAttachment = ReactiveCache.getAttachment(attachmentId);
|
|
if (existingAttachment) {
|
|
return { success: true, message: 'Already migrated', attachmentId };
|
|
}
|
|
|
|
// Get file data from GridFS
|
|
const fileData = getOldAttachmentDataBuffer(attachmentId);
|
|
if (!fileData) {
|
|
return { success: false, error: 'Could not read file data from GridFS' };
|
|
}
|
|
|
|
// Create new attachment using Meteor-Files
|
|
const fileObj = new File([fileData], oldAttachment.name, {
|
|
type: oldAttachment.type
|
|
});
|
|
|
|
const uploader = Attachments.insert({
|
|
file: fileObj,
|
|
meta: oldAttachment.meta,
|
|
isBase64: false,
|
|
transport: 'http'
|
|
});
|
|
|
|
if (uploader) {
|
|
return {
|
|
success: true,
|
|
message: 'Migration successful',
|
|
attachmentId,
|
|
newAttachmentId: uploader._id
|
|
};
|
|
} else {
|
|
return { success: false, error: 'Failed to create new attachment' };
|
|
}
|
|
|
|
} catch (error) {
|
|
console.error('Error migrating attachment:', error);
|
|
return { success: false, error: error.message };
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Migrate all attachments for a specific card
|
|
* @param {string} cardId - The card ID
|
|
* @returns {Object} - Migration results
|
|
*/
|
|
migrateCardAttachments(cardId) {
|
|
if (!this.userId) {
|
|
throw new Meteor.Error('not-authorized', 'Must be logged in');
|
|
}
|
|
|
|
const results = {
|
|
success: 0,
|
|
failed: 0,
|
|
errors: []
|
|
};
|
|
|
|
try {
|
|
// Get all old attachments for this card
|
|
const oldAttachments = ReactiveCache.getAttachments({ 'meta.cardId': cardId });
|
|
|
|
for (const attachment of oldAttachments) {
|
|
const result = Meteor.call('migrateAttachment', attachment._id);
|
|
if (result.success) {
|
|
results.success++;
|
|
} else {
|
|
results.failed++;
|
|
results.errors.push({
|
|
attachmentId: attachment._id,
|
|
error: result.error
|
|
});
|
|
}
|
|
}
|
|
|
|
return results;
|
|
|
|
} catch (error) {
|
|
console.error('Error migrating card attachments:', error);
|
|
return { success: false, error: error.message };
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Get migration status for attachments
|
|
* @param {string} cardId - The card ID (optional)
|
|
* @returns {Object} - Migration status
|
|
*/
|
|
getAttachmentMigrationStatus(cardId) {
|
|
if (!this.userId) {
|
|
throw new Meteor.Error('not-authorized', 'Must be logged in');
|
|
}
|
|
|
|
try {
|
|
const selector = cardId ? { 'meta.cardId': cardId } : {};
|
|
const allAttachments = ReactiveCache.getAttachments(selector);
|
|
|
|
const status = {
|
|
total: allAttachments.length,
|
|
newStructure: 0,
|
|
oldStructure: 0,
|
|
mixed: false
|
|
};
|
|
|
|
for (const attachment of allAttachments) {
|
|
if (attachment.meta && attachment.meta.source === 'legacy') {
|
|
status.oldStructure++;
|
|
} else {
|
|
status.newStructure++;
|
|
}
|
|
}
|
|
|
|
status.mixed = status.oldStructure > 0 && status.newStructure > 0;
|
|
|
|
return status;
|
|
|
|
} catch (error) {
|
|
console.error('Error getting migration status:', error);
|
|
return { error: error.message };
|
|
}
|
|
}
|
|
});
|
|
}
|