Skip to content
Snippets Groups Projects
Commit 5377e327 authored by Diego Sampaio's avatar Diego Sampaio
Browse files

upload files do file system support

parent 20a478e2
No related branches found
No related tags found
No related merge requests found
Showing
with 216 additions and 55 deletions
......@@ -55,6 +55,7 @@ id-map@1.0.4
idorecall:email-normalize@1.0.0
jalik:ufs@0.5.2
jalik:ufs-gridfs@0.1.1
jalik:ufs-local@0.2.5
jparker:crypto-core@0.1.0
jparker:crypto-md5@0.1.1
jparker:gravatar@0.4.1
......
......@@ -212,6 +212,7 @@
"FileUpload_S3_CDN" : "CDN domain for downloads",
"FileUpload_S3_Region" : "Region",
"FileUpload_Storage_Type" : "Storage Type",
"FileUpload_FileSystemPath" : "System Path",
"Follow_social_profiles" : "Follow our social profiles, fork us on github and share your thoughts about the rocket.chat app on our trello board.",
"Force_SSL" : "Force SSL",
"Forgot_password" : "Forgot your password",
......
......@@ -21,10 +21,7 @@ if UploadFS?
name: 'rocketchat_uploads'
collectionName: 'rocketchat_uploads'
filter: new UploadFS.Filter
maxSize: RocketChat.settings.get('FileUpload_MaxFileSize')
contentTypes: RocketChat.fileUploadMediaWhiteList()
onFinishUpload: ->
console.log arguments
onCheck: FileUpload.validateFileUpload
transformWrite: (readStream, writeStream, fileId, file) ->
if RocketChatFile.enabled is false or not /^image\/.+/.test(file.type)
return readStream.pipe writeStream
......
/* globals FileUploadBase, UploadFS, FileUpload:true, FileSystemStore:true */
FileSystemStore = new UploadFS.store.Local({
collection: RocketChat.models.Uploads.model,
name: 'fileSystem',
filter: new UploadFS.Filter({
onCheck: FileUpload.validateFileUpload
}),
});
FileUpload.FileSystem = class FileUploadFileSystem extends FileUploadBase {
constructor(meta, file, data) {
super(meta, file, data);
this.handler = new UploadFS.Uploader({
store: FileSystemStore,
data: data,
file: meta,
onError: (err) => {
var uploading = Session.get('uploading');
if (uploading != null) {
let item = _.findWhere(uploading, {
id: this.id
});
if (item != null) {
item.error = err.reason;
item.percentage = 0;
}
return Session.set('uploading', uploading);
}
},
onComplete: (fileData) => {
var file = _.pick(fileData, '_id', 'type', 'size', 'name', 'identify');
file.url = fileData.url.replace(Meteor.absoluteUrl(), '/');
Meteor.call('sendFileMessage', this.meta.rid, null, file, () => {
Meteor.setTimeout(() => {
var uploading = Session.get('uploading');
if (uploading != null) {
let item = _.findWhere(uploading, {
id: this.id
});
return Session.set('uploading', _.without(uploading, item));
}
}, 2000);
});
}
});
}
start() {
return this.handler.start();
}
getProgress() {
return this.handler.getProgress();
}
stop() {
return this.handler.stop();
}
};
/* globals FileUploadBase, UploadFS, FileUpload:true */
FileUpload.GridFS = class FileUploadGridFS extends FileUploadBase {
constructor(meta, file, data) {
super(meta, file, data);
......@@ -6,10 +7,9 @@ FileUpload.GridFS = class FileUploadGridFS extends FileUploadBase {
data: data,
file: meta,
onError: (err) => {
var item, uploading;
uploading = Session.get('uploading');
var uploading = Session.get('uploading');
if (uploading != null) {
item = _.findWhere(uploading, {
let item = _.findWhere(uploading, {
id: this.id
});
if (item != null) {
......@@ -26,9 +26,9 @@ FileUpload.GridFS = class FileUploadGridFS extends FileUploadBase {
Meteor.call('sendFileMessage', this.meta.rid, null, file, () => {
Meteor.setTimeout(() => {
uploading = Session.get('uploading');
var uploading = Session.get('uploading');
if (uploading != null) {
item = _.findWhere(uploading, {
let item = _.findWhere(uploading, {
id: this.id
});
return Session.set('uploading', _.without(uploading, item));
......@@ -49,4 +49,4 @@ FileUpload.GridFS = class FileUploadGridFS extends FileUploadBase {
stop() {
return this.handler.stop();
}
}
};
/* globals FileUpload:true */
FileUpload = {
validateFileUpload(file) {
if (file.size > maxFileSize) {
throw new Meteor.Error('file-too-large', 'File is too large');
}
if (!RocketChat.fileUploadIsValidContentType(file.type)) {
throw new Meteor.Error('invalid-file-type', 'File type is not accepted');
}
return true;
}
};
var maxFileSize = 0;
RocketChat.settings.get('FileUpload_MaxFileSize', function(key, value) {
maxFileSize = value;
});
FileUpload = {}
FileUploadBase = class FileUploadBase {
constructor(meta, file, data) {
this.id = Random.id();
......
......@@ -10,16 +10,24 @@ Package.describe({
Package.onUse(function(api) {
api.versionsFrom('1.2.1');
api.use('ecmascript');
api.use('rocketchat:file');
api.use('jalik:ufs');
api.use('jalik:ufs-local@0.2.5');
api.use('edgee:slingshot');
api.use('peerlibrary:aws-sdk');
api.use('rocketchat:lib');
api.use('random');
api.use('underscore');
api.use('tracker');
api.use('webapp');
api.addFiles('globalFileRestrictions.js');
api.addFiles('client/lib/FileUploadBase.js', 'client');
// commom lib
api.addFiles('lib/FileUpload.js');
api.addFiles('lib/FileUploadBase.js');
api.addFiles('client/lib/FileUploadFileSystem.js', 'client');
api.addFiles('client/lib/fileUploadHandler.js', 'client');
api.addFiles('client/lib/FileUploadAmazonS3.js', 'client');
api.addFiles('client/lib/FileUploadGridFS.js', 'client');
......@@ -28,6 +36,7 @@ Package.onUse(function(api) {
api.addFiles('server/lib/requests.js', 'server');
api.addFiles('server/config/configFileUploadAmazonS3.js', 'server');
api.addFiles('server/config/configFileUploadFileSystem.js', 'server');
api.addFiles('server/config/configFileUploadGridFS.js', 'server');
api.addFiles('server/methods/sendFileMessage.js', 'server');
......
/* globals createS3Directive:true, Slingshot, FileUpload, AWS */
/* globals Slingshot, FileUpload, AWS */
var crypto = Npm.require('crypto');
var S3accessKey, S3secretKey;
......@@ -34,7 +34,7 @@ FileUpload.addHandler('s3', {
}
});
createS3Directive = _.debounce(() => {
var createS3Directive = _.debounce(() => {
var directiveName = 'rocketchat-uploads';
var type = RocketChat.settings.get('FileUpload_Storage_Type');
......@@ -99,17 +99,11 @@ createS3Directive = _.debounce(() => {
}
}, 500);
RocketChat.settings.get('FileUpload_Storage_Type', function() {
createS3Directive();
});
RocketChat.settings.get('FileUpload_Storage_Type', createS3Directive);
RocketChat.settings.get('FileUpload_S3_Bucket', function() {
createS3Directive();
});
RocketChat.settings.get('FileUpload_S3_Bucket', createS3Directive);
RocketChat.settings.get('FileUpload_S3_Acl', function() {
createS3Directive();
});
RocketChat.settings.get('FileUpload_S3_Acl', createS3Directive);
RocketChat.settings.get('FileUpload_S3_AWSAccessKeyId', function(key, value) {
S3accessKey = value;
......@@ -121,14 +115,8 @@ RocketChat.settings.get('FileUpload_S3_AWSSecretAccessKey', function(key, value)
createS3Directive();
});
RocketChat.settings.get('FileUpload_S3_CDN', function() {
createS3Directive();
});
RocketChat.settings.get('FileUpload_S3_CDN', createS3Directive);
RocketChat.settings.get('FileUpload_S3_Region', function() {
createS3Directive();
});
RocketChat.settings.get('FileUpload_S3_Region', createS3Directive);
RocketChat.settings.get('FileUpload_S3_BucketURL', function() {
createS3Directive();
});
RocketChat.settings.get('FileUpload_S3_BucketURL', createS3Directive);
/* globals FileSystemStore:true, FileUpload, UploadFS, RocketChatFile */
let storeName = 'fileSystem';
FileSystemStore = null;
let createFileSystemStore = _.debounce(function() {
let stores = UploadFS.getStores();
if (stores[storeName]) {
delete stores[storeName];
}
FileSystemStore = new UploadFS.store.Local({
collection: RocketChat.models.Uploads.model,
name: storeName,
path: RocketChat.settings.get('FileUpload_FileSystemPath'),//'/tmp/uploads/photos',
filter: new UploadFS.Filter({
onCheck: FileUpload.validateFileUpload
}),
transformWrite: function(readStream, writeStream, fileId, file) {
var identify, stream;
if (RocketChatFile.enabled === false || !/^image\/.+/.test(file.type)) {
return readStream.pipe(writeStream);
}
stream = void 0;
identify = function(err, data) {
var ref;
if (err != null) {
return stream.pipe(writeStream);
}
file.identify = {
format: data.format,
size: data.size
};
if ((data.Orientation != null) && ((ref = data.Orientation) !== '' && ref !== 'Unknown' && ref !== 'Undefined')) {
return RocketChatFile.gm(stream).autoOrient().stream().pipe(writeStream);
} else {
return stream.pipe(writeStream);
}
};
stream = RocketChatFile.gm(readStream).identify(identify).stream();
return;
}
});
}, 500);
RocketChat.settings.get('FileUpload_FileSystemPath', createFileSystemStore);
var fs = Npm.require('fs');
FileUpload.addHandler(storeName, {
get(file, req, res) {
let filePath = FileSystemStore.getFilePath(file._id, file);
try {
let stat = Meteor.wrapAsync(fs.stat)(filePath);
if (stat && stat.isFile()) {
res.setHeader('Content-Disposition', 'attachment; filename="' + encodeURIComponent(file.name) + '"');
res.setHeader('Last-Modified', file.uploadedAt.toUTCString());
res.setHeader('Content-Type', file.type);
res.setHeader('Content-Length', file.size);
FileSystemStore.getReadStream(file._id, file).pipe(res);
}
} catch (e) {
res.writeHead(404);
res.end();
return;
}
},
delete(file) {
return FileSystemStore.delete(file._id);
}
});
......@@ -60,7 +60,6 @@ FileUpload.addHandler('rocketchat_uploads', {
return readFromGridFS(file.store, file._id, file, req, res);
},
delete(file) {
console.log('will delete file from GridFS',file);
return Meteor.fileStore.delete(file._id);
}
});
/* globals FileUpload:true */
FileUpload = {
handlers: {},
addHandler(store, handler) {
this.handlers[store] = handler;
},
delete(fileId) {
let file = RocketChat.models.Uploads.findOneById(fileId);
FileUpload.handlers = {};
if (!file) {
return;
}
FileUpload.addHandler = function(store, handler) {
this.handlers[store] = handler;
};
FileUpload.delete = function(fileId) {
let file = RocketChat.models.Uploads.findOneById(fileId);
if (!file) {
return;
}
this.handlers[file.store].delete(file);
this.handlers[file.store].delete(file);
return RocketChat.models.Uploads.remove(file._id);
};
return RocketChat.models.Uploads.remove(file._id);
},
get(file, req, res, next) {
if (file.store && this.handlers && this.handlers[file.store] && this.handlers[file.store].get) {
this.handlers[file.store].get.call(this, file, req, res, next);
} else {
res.writeHead(404);
res.end();
return;
}
FileUpload.get = function(file, req, res, next) {
if (file.store && this.handlers && this.handlers[file.store] && this.handlers[file.store].get) {
this.handlers[file.store].get.call(this, file, req, res, next);
} else {
res.writeHead(404);
res.end();
return;
}
};
......@@ -29,6 +29,9 @@ RocketChat.settings.addGroup('FileUpload', function() {
}, {
key: 'AmazonS3',
i18nLabel: 'AmazonS3'
}, {
key: 'FileSystem',
i18nLabel: 'FileSystem'
}],
public: true
});
......@@ -85,4 +88,14 @@ RocketChat.settings.addGroup('FileUpload', function() {
i18nDescription: 'Override_URL_to_which_files_are_uploaded_This_url_also_used_for_downloads_unless_a_CDN_is_given.'
});
});
this.section('File System', function() {
this.add('FileUpload_FileSystemPath', '', {
type: 'string',
enableQuery: {
_id: 'FileUpload_Storage_Type',
value: 'FileSystem'
}
});
});
});
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment