Skip to content

Instantly share code, notes, and snippets.

@raix
Last active October 13, 2023 00:08
Show Gist options
  • Save raix/9720064 to your computer and use it in GitHub Desktop.
Save raix/9720064 to your computer and use it in GitHub Desktop.
cfs image uploader example
<template name="imageUploader">
<h2>Picture</h2>
<p>
{{#each images}}
<img src="{{url}}" alt="">
<input type="button" value="remove" class="btnRemove"/>
{{else}}
No files uploaded.
{{/each}}
</p>
<p>Upload profile pic:</p>
<input name="files" id="files" type="file" multiple/><br/>
<br/>
<div id="dropzone" class="dropzone">
<div style="text-align: center; color: gray;">Drop file to upload</div>
</div>
<br/>
</template>
// This should set default store to thumbnail store
// Setting the store on the client could change the way things get uploaded/downloaded in the future
// eg. the s3 allows direct upload and direct download - but for security we are going to add signed urls
// future package: cfs-s3cloud storage adapter
var imageStore = new FS.Store.FileSystem("thumbnail");
var images = new FS.Collection("images", {
stores: [imageStore],
filter: {
allow: {
contentTypes: ['image/*']
}
}
});
Meteor.subscribe("images");
var images = new FS.Collection("images", {
stores: [imageStore],
filter: {
allow: {
contentTypes: ['image/*']
}
}
});
Template.imageUploader.images = function () {
return images.find();
};
Template.imageUploader.events({
'change #files': function(event, temp) {
console.log('files changed');
FS.Utility.eachFile(event, function(file) {
var fileObj = new FS.File(file);
fileObj.metadata = { owner: Meteor.userId() };
images.insert(fileObj);
});
},
'dropped #dropzone': function(event, temp) {
console.log('files droped');
FS.Utility.eachFile(event, function(file) {
var fileObj = new FS.File(file);
fileObj.metadata = { owner: Meteor.userId() };
images.insert(fileObj);
});
},
'click .btnRemove': function(event, temp) {
this.remove();
}
});
var imageStore = new FS.Store.S3("images", {
region: "us-east-1",
accessKeyId: "***********",
secretAccessKey: "*********",
bucket: "*******"
});
var gridfs = new FS.Store.GridFS('gridfsimages', {
transformWrite: function(fileObj, readStream, writeStream) {
// Store 10x10 px images
this.gm(readStream, fileObj.name).resize('10', '10').stream().pipe(writeStream);
// To pass through stream:
//readStream.pipe(writeStream);
}
});
var thumbnail = new FS.Store.FileSystem('thumbnail', {
path: '~/dev/test/collectionFS/thumbnails',
transformWrite: function(fileObj, readStream, writeStream) {
// Store 10x10 px images
this.gm(readStream, fileObj.name).resize('10', '10').stream().pipe(writeStream);
// To pass through stream:
//readStream.pipe(writeStream);
},
// we support transformRead function too - its same layout as transformRead
// and will transform data from the storage adapter to the reading stream.
// eg. if we want to have encrypt and decrypt data streams
// Node transform streams:
// http://nodejs.org/api/zlib.html
// http://nodejs.org/api/crypto.html
// But its also possible to pipe data from other stores on to fileObj or other files
// so data handling is flexible
});
// we place the thumbnail to be created first since we want the client to get a fast upload response
//
var images = new FS.Collection("images", {
stores: [thumbnail, gridfsimageStore, gridfs],
filter: {
allow: {
contentTypes: ['image/*']
}
}
});
images.allow({
insert: function(userId, fileObj) {
return !!userId; // we could check fileObj.metadata.owner?
},
update: function(userId, fileObj) {
return !!userId;
},
remove: function(userId, fileObj) {
return !!userId;
},
// Allow eg. only the user in metadata
// the shareId is being discussed - eg. for sharing urls
download: function(userId, fileObj/*, shareId*/) {
return true;
},
fetch: []
});
// Publish images with userId in owner - this regulates reading the
// filerecord data - use allow/deny for "download" for restricting the
// access to the actual data.
Meteor.publish("images", function() {
return images.find({ 'metadata.owner': this.userId });
});
@EBEKBOEV
Copy link

Hi!
Is there any way to upoad one picture and save it in 3 different sized files on server?

I try this but doesn't work(((

Images = new FS.Collection("images", {
    stores: [
        new FS.Store.FileSystem("images", {
        path: "~/uploads",
        transformWrite: function(fileObj, readStream, writeStream) {
            gm(readStream, fileObj.name("file1")).resize('500').stream().pipe(writeStream);
        }
    }),
        new FS.Store.FileSystem("thumbnails", {
            path: "~/uploads",
            transformWrite: function(fileObj, readStream, writeStream) {
                gm(readStream, fileObj.name("file2")).resize('50').stream().pipe(writeStream);
            }
        })]
});

@ovidb
Copy link

ovidb commented May 12, 2015

Is it possible to modify images (shrink them with gm) on the client only, and upload'em only after that?

@Noveltysa
Copy link

Hi
I need help. I am able to upload files(mp3) to server with gridfs and filesystem, and I can access the "data" only via the .url() (streaming) because .getfilerecord() returns null always.

Please help
I just need to get the file back in binary file for further manipulation to read id3 tags etc.

Thanks

@oreynaldocl
Copy link

Good example, I have a question, is it possible to create a copy of an image?

@Tevinthuku
Copy link

Thanks Raix

@JeanElliot
Copy link

Good example, Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment