mirror of https://github.com/wekan/wekan
parent
85480a6cae
commit
96f8b5c9f4
@ -0,0 +1,47 @@ |
||||
import { createObjectId } from '../grid/createObjectId'; |
||||
|
||||
const createInterceptDownload = bucket => |
||||
function interceptDownload(http, file, versionName) { |
||||
const { gridFsFileId } = file.versions[versionName].meta || {}; |
||||
if (gridFsFileId) { |
||||
// opens the download stream using a given gfs id
|
||||
// see: http://mongodb.github.io/node-mongodb-native/3.2/api/GridFSBucket.html#openDownloadStream
|
||||
const gfsId = createObjectId({ gridFsFileId }); |
||||
const readStream = bucket.openDownloadStream(gfsId); |
||||
|
||||
readStream.on('data', data => { |
||||
http.response.write(data); |
||||
}); |
||||
|
||||
readStream.on('end', () => { |
||||
http.response.end(); // don't pass parameters to end() or it will be attached to the file's binary stream
|
||||
}); |
||||
|
||||
readStream.on('error', () => { |
||||
// not found probably
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
http.response.statusCode = 404; |
||||
http.response.end('not found'); |
||||
}); |
||||
|
||||
http.response.setHeader('Cache-Control', this.cacheControl); |
||||
http.response.setHeader( |
||||
'Content-Disposition', |
||||
getContentDisposition(file.name, http?.params?.query?.download), |
||||
); |
||||
} |
||||
return Boolean(gridFsFileId); // Serve file from either GridFS or FS if it wasn't uploaded yet
|
||||
}; |
||||
|
||||
/** |
||||
* Will initiate download, if links are called with ?download="true" queryparam. |
||||
**/ |
||||
const getContentDisposition = (name, downloadFlag) => { |
||||
const dispositionType = downloadFlag === 'true' ? 'attachment;' : 'inline;'; |
||||
|
||||
const encodedName = encodeURIComponent(fileName); |
||||
const dispositionName = `filename="${encodedName}"; filename=*UTF-8"${encodedName}";`; |
||||
const dispositionEncoding = 'charset=utf-8'; |
||||
|
||||
return `${dispositionType} ${dispositionName} ${dispositionEncoding}`; |
||||
}; |
@ -0,0 +1,17 @@ |
||||
import { createObjectId } from '../grid/createObjectId'; |
||||
|
||||
const createOnAfterRemove = bucket => |
||||
function onAfterRemove(files) { |
||||
files.forEach(file => { |
||||
Object.keys(file.versions).forEach(versionName => { |
||||
const gridFsFileId = (file.versions[versionName].meta || {}) |
||||
.gridFsFileId; |
||||
if (gridFsFileId) { |
||||
const gfsId = createObjectId({ gridFsFileId }); |
||||
bucket.delete(gfsId, err => { |
||||
// if (err) console.error(err);
|
||||
}); |
||||
} |
||||
}); |
||||
}); |
||||
}; |
@ -0,0 +1,51 @@ |
||||
import { Meteor } from 'meteor/meteor'; |
||||
import fs from 'fs'; |
||||
|
||||
export const createOnAfterUpload = bucket => |
||||
function onAfterUpload(file) { |
||||
const self = this; |
||||
|
||||
// here you could manipulate your file
|
||||
// and create a new version, for example a scaled 'thumbnail'
|
||||
// ...
|
||||
|
||||
// then we read all versions we have got so far
|
||||
Object.keys(file.versions).forEach(versionName => { |
||||
const metadata = { ...file.meta, versionName, fileId: file._id }; |
||||
fs.createReadStream(file.versions[versionName].path) |
||||
|
||||
// this is where we upload the binary to the bucket using bucket.openUploadStream
|
||||
// see http://mongodb.github.io/node-mongodb-native/3.2/api/GridFSBucket.html#openUploadStream
|
||||
.pipe( |
||||
bucket.openUploadStream(file.name, { |
||||
contentType: file.type || 'binary/octet-stream', |
||||
metadata, |
||||
}), |
||||
) |
||||
|
||||
// and we unlink the file from the fs on any error
|
||||
// that occurred during the upload to prevent zombie files
|
||||
.on('error', err => { |
||||
// console.error(err);
|
||||
self.unlink(this.collection.findOne(file._id), versionName); // Unlink files from FS
|
||||
}) |
||||
|
||||
// once we are finished, we attach the gridFS Object id on the
|
||||
// FilesCollection document's meta section and finally unlink the
|
||||
// upload file from the filesystem
|
||||
.on( |
||||
'finish', |
||||
Meteor.bindEnvironment(ver => { |
||||
const property = `versions.${versionName}.meta.gridFsFileId`; |
||||
|
||||
self.collection.update(file._id, { |
||||
$set: { |
||||
[property]: ver._id.toHexString(), |
||||
}, |
||||
}); |
||||
|
||||
self.unlink(this.collection.findOne(file._id), versionName); // Unlink files from FS
|
||||
}), |
||||
); |
||||
}); |
||||
}; |
@ -0,0 +1,9 @@ |
||||
import { MongoInternals } from 'meteor/mongo'; |
||||
|
||||
export const createBucket = bucketName => { |
||||
const options = bucketName ? { bucketName } : void 0; |
||||
return new MongoInternals.NpmModule.GridFSBucket( |
||||
MongoInternals.defaultRemoteCollectionDriver().mongo.db, |
||||
options, |
||||
); |
||||
}; |
@ -0,0 +1,4 @@ |
||||
import { MongoInternals } from 'meteor/mongo'; |
||||
|
||||
export const createObjectId = ({ gridFsFileId }) => |
||||
new MongoInternals.NpmModule.ObjectID(gridFsFileId); |
Loading…
Reference in new issue