mirror of
https://github.com/wekan/wekan.git
synced 2025-12-16 15:30:13 +01:00
247 lines
6.6 KiB
JavaScript
247 lines
6.6 KiB
JavaScript
|
|
import fs from 'fs';
|
||
|
|
import { createBucket } from './grid/createBucket';
|
||
|
|
import { createObjectId } from './grid/createObjectId';
|
||
|
|
import { createOnAfterUpload } from './fsHooks/createOnAfterUpload';
|
||
|
|
import { createInterceptDownload } from './fsHooks/createInterceptDownload';
|
||
|
|
import { createOnAfterRemove } from './fsHooks/createOnAfterRemove';
|
||
|
|
|
||
|
|
const insertActivity = (fileObj, activityType) =>
|
||
|
|
Activities.insert({
|
||
|
|
userId: fileObj.userId,
|
||
|
|
type: 'card',
|
||
|
|
activityType,
|
||
|
|
attachmentId: fileObj._id,
|
||
|
|
attachmentName: fileObj.name,
|
||
|
|
boardId: fileObj.meta.boardId,
|
||
|
|
cardId: fileObj.meta.cardId,
|
||
|
|
listId: fileObj.meta.listId,
|
||
|
|
swimlaneId: fileObj.meta.swimlaneId,
|
||
|
|
});
|
||
|
|
|
||
|
|
let attachmentBucket;
|
||
|
|
if (Meteor.isServer) {
|
||
|
|
attachmentBucket = createBucket('attachments');
|
||
|
|
}
|
||
|
|
|
||
|
|
/** Strategy to store attachments */
|
||
|
|
class AttachmentStoreStrategy {
|
||
|
|
|
||
|
|
/** constructor
|
||
|
|
* @param filesCollection the current FilesCollection instance
|
||
|
|
* @param fileObj the current file object
|
||
|
|
* @param versionName the current version
|
||
|
|
*/
|
||
|
|
constructor(filesCollection, fileObj, versionName) {
|
||
|
|
this.filesCollection = filesCollection;
|
||
|
|
this.fileObj = fileObj;
|
||
|
|
this.versionName = versionName;
|
||
|
|
}
|
||
|
|
|
||
|
|
/** after successfull upload */
|
||
|
|
onAfterUpload() {
|
||
|
|
// If the attachment doesn't have a source field or its source is different than import
|
||
|
|
if (!this.fileObj.meta.source || this.fileObj.meta.source !== 'import') {
|
||
|
|
// Add activity about adding the attachment
|
||
|
|
insertActivity(this.fileObj, 'addAttachment');
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/** download the file
|
||
|
|
* @param http the current http request
|
||
|
|
*/
|
||
|
|
interceptDownload(http) {
|
||
|
|
}
|
||
|
|
|
||
|
|
/** after file remove */
|
||
|
|
onAfterRemove() {
|
||
|
|
insertActivity(this.fileObj, 'deleteAttachment');
|
||
|
|
}
|
||
|
|
|
||
|
|
/** returns a read stream
|
||
|
|
* @return the read stream
|
||
|
|
*/
|
||
|
|
getReadStream() {
|
||
|
|
}
|
||
|
|
|
||
|
|
/** returns a write stream
|
||
|
|
* @return the write stream
|
||
|
|
*/
|
||
|
|
getWriteStream() {
|
||
|
|
}
|
||
|
|
|
||
|
|
/** writing finished
|
||
|
|
* @param finishedData the data of the write stream finish event
|
||
|
|
*/
|
||
|
|
writeStreamFinished(finishedData) {
|
||
|
|
}
|
||
|
|
|
||
|
|
/** remove the file */
|
||
|
|
unlink() {
|
||
|
|
}
|
||
|
|
|
||
|
|
/** return the storage name
|
||
|
|
* @return the storage name
|
||
|
|
*/
|
||
|
|
getStorageName() {
|
||
|
|
}
|
||
|
|
|
||
|
|
static getFileStrategy(filesCollection, fileObj, versionName, storage) {
|
||
|
|
if (!storage) {
|
||
|
|
storage = fileObj.versions[versionName].storage || "gridfs";
|
||
|
|
}
|
||
|
|
let ret;
|
||
|
|
if (["fs", "gridfs"].includes(storage)) {
|
||
|
|
if (storage == "fs") {
|
||
|
|
ret = new AttachmentStoreStrategyFilesystem(filesCollection, fileObj, versionName);
|
||
|
|
} else if (storage == "gridfs") {
|
||
|
|
ret = new AttachmentStoreStrategyGridFs(filesCollection, fileObj, versionName);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
console.log("getFileStrategy: ", ret.constructor.name);
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/** Strategy to store attachments at GridFS (MongoDB) */
|
||
|
|
class AttachmentStoreStrategyGridFs extends AttachmentStoreStrategy {
|
||
|
|
|
||
|
|
/** constructor
|
||
|
|
* @param filesCollection the current FilesCollection instance
|
||
|
|
* @param fileObj the current file object
|
||
|
|
* @param versionName the current version
|
||
|
|
*/
|
||
|
|
constructor(filesCollection, fileObj, versionName) {
|
||
|
|
super(filesCollection, fileObj, versionName);
|
||
|
|
}
|
||
|
|
|
||
|
|
/** after successfull upload */
|
||
|
|
onAfterUpload() {
|
||
|
|
createOnAfterUpload(this.filesCollection, attachmentBucket, this.fileObj, this.versionName);
|
||
|
|
super.onAfterUpload();
|
||
|
|
}
|
||
|
|
|
||
|
|
/** download the file
|
||
|
|
* @param http the current http request
|
||
|
|
*/
|
||
|
|
interceptDownload(http) {
|
||
|
|
const ret = createInterceptDownload(this.filesCollection, attachmentBucket, this.fileObj, http, this.versionName);
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
/** after file remove */
|
||
|
|
onAfterRemove() {
|
||
|
|
this.unlink();
|
||
|
|
super.onAfterRemove();
|
||
|
|
}
|
||
|
|
|
||
|
|
/** returns a read stream
|
||
|
|
* @return the read stream
|
||
|
|
*/
|
||
|
|
getReadStream() {
|
||
|
|
const gridFsFileId = (this.fileObj.versions[this.versionName].meta || {})
|
||
|
|
.gridFsFileId;
|
||
|
|
let ret;
|
||
|
|
if (gridFsFileId) {
|
||
|
|
const gfsId = createObjectId({ gridFsFileId });
|
||
|
|
ret = attachmentBucket.openDownloadStream(gfsId);
|
||
|
|
}
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
/** returns a write stream
|
||
|
|
* @return the write stream
|
||
|
|
*/
|
||
|
|
getWriteStream() {
|
||
|
|
const fileObj = this.fileObj;
|
||
|
|
const versionName = this.versionName;
|
||
|
|
const metadata = { ...fileObj.meta, versionName, fileId: fileObj._id };
|
||
|
|
const ret = attachmentBucket.openUploadStream(this.fileObj.name, {
|
||
|
|
contentType: fileObj.type || 'binary/octet-stream',
|
||
|
|
metadata,
|
||
|
|
});
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
/** writing finished
|
||
|
|
* @param finishedData the data of the write stream finish event
|
||
|
|
*/
|
||
|
|
writeStreamFinished(finishedData) {
|
||
|
|
const gridFsFileIdName = this.getGridFsFileIdName();
|
||
|
|
Attachments.update({ _id: this.fileObj._id }, { $set: { [gridFsFileIdName]: finishedData._id.toHexString(), } });
|
||
|
|
}
|
||
|
|
|
||
|
|
/** remove the file */
|
||
|
|
unlink() {
|
||
|
|
createOnAfterRemove(this.filesCollection, attachmentBucket, this.fileObj, this.versionName);
|
||
|
|
const gridFsFileIdName = this.getGridFsFileIdName();
|
||
|
|
Attachments.update({ _id: this.fileObj._id }, { $unset: { [gridFsFileIdName]: 1 } });
|
||
|
|
}
|
||
|
|
|
||
|
|
/** return the storage name
|
||
|
|
* @return the storage name
|
||
|
|
*/
|
||
|
|
getStorageName() {
|
||
|
|
return "gridfs";
|
||
|
|
}
|
||
|
|
|
||
|
|
/** returns the property name of gridFsFileId
|
||
|
|
* @return the property name of gridFsFileId
|
||
|
|
*/
|
||
|
|
getGridFsFileIdName() {
|
||
|
|
const ret = `versions.${this.versionName}.meta.gridFsFileId`;
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/** Strategy to store attachments at filesystem */
|
||
|
|
class AttachmentStoreStrategyFilesystem extends AttachmentStoreStrategy {
|
||
|
|
|
||
|
|
/** constructor
|
||
|
|
* @param filesCollection the current FilesCollection instance
|
||
|
|
* @param fileObj the current file object
|
||
|
|
* @param versionName the current version
|
||
|
|
*/
|
||
|
|
constructor(filesCollection, fileObj, versionName) {
|
||
|
|
super(filesCollection, fileObj, versionName);
|
||
|
|
}
|
||
|
|
|
||
|
|
/** returns a read stream
|
||
|
|
* @return the read stream
|
||
|
|
*/
|
||
|
|
getReadStream() {
|
||
|
|
const ret = fs.createReadStream(this.fileObj.versions[this.versionName].path)
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
/** returns a write stream
|
||
|
|
* @return the write stream
|
||
|
|
*/
|
||
|
|
getWriteStream() {
|
||
|
|
const newFileName = this.fileObj.name;
|
||
|
|
const filePath = this.fileObj.versions[this.versionName].path;
|
||
|
|
const ret = fs.createWriteStream(filePath);
|
||
|
|
return ret;
|
||
|
|
}
|
||
|
|
|
||
|
|
/** writing finished
|
||
|
|
* @param finishedData the data of the write stream finish event
|
||
|
|
*/
|
||
|
|
writeStreamFinished(finishedData) {
|
||
|
|
}
|
||
|
|
|
||
|
|
/** remove the file */
|
||
|
|
unlink() {
|
||
|
|
const filePath = this.fileObj.versions[this.versionName].path;
|
||
|
|
fs.unlink(filePath, () => {});
|
||
|
|
}
|
||
|
|
|
||
|
|
/** return the storage name
|
||
|
|
* @return the storage name
|
||
|
|
*/
|
||
|
|
getStorageName() {
|
||
|
|
return "fs";
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
export default AttachmentStoreStrategy;
|