You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Mar 14, 2019. It is now read-only.
Repository navigation
This repository was archived by the owner on Mar 14, 2019. It is now read-only.
While implementing v2 in an app, I'm coming across some irregularities and parts that I seem to be missing in the documentation or needs clarification, so I thought starting a thread to gather them here is useful, feel free to chip in, to help new adopters.
@raix@aldeed Can we keep this issue/thread open for now, to have a single go to place for api docs updates for the devel branch? If so, then I'll simply add issues here one by one, as I stumble upon them.
Missing
After having uploaded files serverside, eg. an image file for use as a graphics element in an app, a natural/intuitive/naive next step seems to be to show it (the single image) in a template. Either via a direct like as if it was uploaded to /public, or via a helper, eg. Template.[template].image = function () { return [fsCollectionName].findOne({_id: id}).url(); }; Maybe there is a better implementation already? What is the way to do this?
Irregularities
cfs-handlebars: is it still recommended or is it deprecated/obsolete due to integrated UI helpers in the new v2 API? (the current doc recommends it)
Insert One File From a Remote URL mentions FS.File.fromUrl, however this no longer works.
@casperanderseneu I thinks its a good idea - The issue will prop. grow long (we had a similar thread called "rewrite" - a google group could perhaps solve it better but what ever works)
So the id in the helper comes from some other document? I would say that the preferred way would be:
{{#with foo}}
My name is {{name}} and my image <imgsrc="{{image.url store='thumbnail'}}">
{{/with}}
Near full example (not tested but should show the intended use)
// We depend on gm - can this be done from app level yet?vargm=Npm.require('gm');// We have a regular meteor collectionvarfooList=newMeteor.Collection('fooList');// Our imagesvarimages=newFS.Collection('images',{stores: [newFS.FileSystem('thumbnail',{path: '/path/to/images',transform: function(fileObj/* or readStream, writeStream? */){// This api is WIP not implemented yet - gm(fileObj.createReadStream()).resize(10).stream().pipe(fileObj.createWriteStream('thumbnail'));}})]});// Add some data - this would normally be done via events// Insert + upload a filevarfileObj=images.insert(file);// Insert the mounted image into the normal collectionfooList.insert({name: 'bar',image: fileObj});// Template helperTemplate.hello.foo=function(){returnfooList.findOne();};
cfs-handlebars - is deprecating should be obsolete at some point - The current api is tightly integrated with the way Blaze works - We have added a package for dropped events - ui-dropped-event there is a very short code example on the package read me (only thing there is really)
Correct fromUrl no longer works - we use the attachData api now
varfileObj=newFS.File({name: 'myfile.ext'});fileObj.attachData(/* file/blob/Buffer/readStream/url */);images.insert(fileObj);// I think we will also support this directly or already does?varfileObj=images.insert(/* file/url */);varfileObj=images.insert('filename.ext',/* file/blob/Buffer/readStream/url */);
One point we need to add / stress in the docs - don't write your own Meteor.methods for insert/remove etc. its a common mistake to think thats any safer than letting the client-side api do the works. Its more secure to actually use the client-side api since we do check allow/deny rules on the server - and its basically Meteor.methods behind the scenes any way.
We are also talking about deprecating cfs-graphicsmagic since the streaming api in the transform function is basically pure gm api.
It would be possible to create transform helper functions eg. in separate packages:
// Our simple transformation function for resizing imagesFS.Transform.resizeImage=function(size){// Maybe it makes sense to serve the read and write streamreturnfunction(fileObj,readStream,writeStream){// This api is WIP not implemented yet - gm(readStream).resize(size).stream().pipe(writeStream);}};
@casperanderseneu, just to add one thing, we would accept PR to update the README. At the moment, the API has been changing almost daily so we have not yet bothered to update everything, but it will smooth out within 2 weeks. Often it seems that someone trying to understand from outside the development group is the best qualified to write documentation because they know what questions people will have.
But that said, we plan to release around the end of the month, and the docs will be updated at that point. We'll use this issue as a point of reference to see what we need to explain better.
I would say ok for meteor-collectionFS or meteor-cfs?
Docs would be ok too - agree that QA/tests/docs are tightly connected - I haven't tested https://hackpad.com but it may be useful in documentation case? - since (as I get it) we could discuss while forming a spec/project/task and it got syntax highlighting? thats the nice thing about having the discussion in git issues
Note: we have been discussing strategy for version numbers etc. target is 1.0.0 - this way we can follow the major version of Meteor (same goes for packages) - we have been using v1/v2 we should really have been saying "old" / "new" api I guess. My bad - so v1.0.0 release.
@aldeed could you confirm? I'm unsure if we actually agreed on this in reality or just in my head, I may have continued our discussion on my own :)
Truth is I really don't like google groups, but whatever works best for the most people is fine with me. IMO, github issues (which we can tag with discussion or question tag) serve the same purpose and give better code markdown, etc.
Yes, @raix, that sounds like what we decided about versions. :)
So you vote for keeping it simple? I'm fine with all - we could use the meteor talk for community discussions?
MDG uses google groups for feature requests - that pattern doesn't work well, its a black hole for new ideas - so we should avoid gg when discussing something we want to keep a track of.
We can tag in gg but it doesn't have syntax highlighting - why I like github - but discussion threads can become very long - why I'm thinking about hack pad for arc discussions etc. but haven't had the time to check it out.
@lleonard188, that example should still work. For limiting uploads, security for insert is done through allow/deny as if it's a normal collection, so you can run a search in a deny function to see how many files already belong to that user and return true if they already have the maximum. Also, for the example in the readme, if you use that code on the client, you would want to verify the owner ID is the current userId in a deny function as well, since client could set it to any user.
You client code could also do a redundant check for max uploads if all the user's files are published to the client, which would save you the server trip and processing.
@aldeed I'm still a bit confused. From what I've read the code below is what I've come up with for an upload-image-and-display-it app, but I don't know how I would find the images belonging to a particular user. Thanks in advance for any help.
I just went through the main package readme and attempted to get all the errors corrected. Still needs work but in general the API examples should be correct as of this moment.
Cool 👍 The api is settling, feels nice - Auto tests should be up and running, cfs-file may need some love, We need to work a bit on the worker etc. I'll try to update milestones etc. To get some overview of status.
Basically what you want to do is download the binary and attach it to the file object so that you can display it from a data URI. So:
Download the data:
Use fileObj.url({store: yourStoreName}) to get the URL. Then use an XMLHttpRequest to get the arraybuffer data from that URL.
Attach the data:
Pass the arraybuffer to attachData. (fileObj.attachData(arrayBuffer))
Get data URI:
fileObj.getDataUri(function(uri){//save URI to a reactive variable or set into img src});
For those first two steps, I think we can add an attachDataFromStore method on the client to make that simple, or maybe attachData({store: storeName}).
Update: FS.TempStore now uses the Storage Adapter api and defaults to FS.Store.FileSystem or FS.Store.GridFS depending on installed packages. Filesystem is preferred unless cfs-worker is in the project, then FS.Store.GridFS is preferred due to scalability over multiple instances of Meteor.
I think we have to rework some of the stuff to take better advantage of the simpler streaming api #239
I havent tested that part of the api, but I see a node fs dependency and thats potentially a problem when deploying.
But yes, the docs seems to be ok, we just need to align the api :)
would be great if examples of accessing data from code, not just templates were provided wherever possible . Took me some time to find this.
Also at the moment:
FS.HTTP.setBaseUrl('/files')
causes ReferenceError: mountUrls is not defined
Wasn't sure if it was doc error, as I saw some comments on the update api docs on this. (but not working for me yet)
Last note, @raix and @aldeed - this is becoming an incredibly useful project - right on par with Collections2 - my kudos for an amazing job. Hope we all have stable projects out for meteor 1.0
@casperanderseneu, currently I'm getting a "RangeError: Maximum call stack size exceeded" error when doing server-side insert of filepath or URL, like your example. I don't know if this is what you're getting, too. I couldn't figure out the cause at the moment, but maybe @raix will have an idea. Further discussion can move to #246.
@calculon0, what type is file? Is it a browser File object? DataMan should support it, especially because if you pass it to the FS.File constructor, it passes it along to attachData for you anyway.
@abuddenb, if you want to submit a PR with readme updates, we would accept that. There are also lots of examples in the unit tests for the cfs-file package, which could be linked to.
Activity
raix commentedon Mar 19, 2014
@casperanderseneu I thinks its a good idea - The issue will prop. grow long (we had a similar thread called "rewrite" - a google group could perhaps solve it better but what ever works)
So the
idin the helper comes from some other document? I would say that the preferred way would be:{{#with foo}} My name is {{name}} and my image <img src="{{image.url store='thumbnail'}}"> {{/with}}Near full example (not tested but should show the intended use)
fromUrlno longer works - we use theattachDataapi nowOne point we need to add / stress in the docs - don't write your own Meteor.methods for insert/remove etc. its a common mistake to think thats any safer than letting the client-side api do the works. Its more secure to actually use the client-side api since we do check allow/deny rules on the server - and its basically Meteor.methods behind the scenes any way.
raix commentedon Mar 19, 2014
We are also talking about deprecating
cfs-graphicsmagicsince the streaming api in the transform function is basically puregmapi.It would be possible to create transform helper functions eg. in separate packages:
Would simplify api:
aldeed commentedon Mar 19, 2014
@casperanderseneu, just to add one thing, we would accept PR to update the README. At the moment, the API has been changing almost daily so we have not yet bothered to update everything, but it will smooth out within 2 weeks. Often it seems that someone trying to understand from outside the development group is the best qualified to write documentation because they know what questions people will have.
But that said, we plan to release around the end of the month, and the docs will be updated at that point. We'll use this issue as a point of reference to see what we need to explain better.
raix commentedon Mar 20, 2014
I would say ok for meteor-collectionFS or meteor-cfs?
Docs would be ok too - agree that QA/tests/docs are tightly connected - I haven't tested https://hackpad.com but it may be useful in documentation case? - since (as I get it) we could discuss while forming a spec/project/task and it got syntax highlighting? thats the nice thing about having the discussion in git issues
Note: we have been discussing strategy for version numbers etc. target is 1.0.0 - this way we can follow the major version of Meteor (same goes for packages) - we have been using v1/v2 we should really have been saying "old" / "new" api I guess. My bad - so v1.0.0 release.
@aldeed could you confirm? I'm unsure if we actually agreed on this in reality or just in my head, I may have continued our discussion on my own :)
aldeed commentedon Mar 20, 2014
Truth is I really don't like google groups, but whatever works best for the most people is fine with me. IMO, github issues (which we can tag with
discussionorquestiontag) serve the same purpose and give better code markdown, etc.Yes, @raix, that sounds like what we decided about versions. :)
raix commentedon Mar 20, 2014
So you vote for keeping it simple? I'm fine with all - we could use the meteor talk for community discussions?
MDG uses google groups for feature requests - that pattern doesn't work well, its a black hole for new ideas - so we should avoid gg when discussing something we want to keep a track of.
We can tag in gg but it doesn't have syntax highlighting - why I like github - but discussion threads can become very long - why I'm thinking about hack pad for arc discussions etc. but haven't had the time to check it out.
lleonard188 commentedon Mar 21, 2014
For the section "Securing Based on User Information" , has that code changed? I'm trying to attach Meteor userIDs to images.
Also, is there a way to limit how many files a user can upload?
aldeed commentedon Mar 22, 2014
@lleonard188, that example should still work. For limiting uploads, security for insert is done through allow/deny as if it's a normal collection, so you can run a search in a deny function to see how many files already belong to that user and return
trueif they already have the maximum. Also, for the example in the readme, if you use that code on the client, you would want to verify the owner ID is the currentuserIdin a deny function as well, since client could set it to any user.You client code could also do a redundant check for max uploads if all the user's files are published to the client, which would save you the server trip and processing.
lleonard188 commentedon Mar 23, 2014
@aldeed I'm still a bit confused. From what I've read the code below is what I've come up with for an upload-image-and-display-it app, but I don't know how I would find the images belonging to a particular user. Thanks in advance for any help.
HTML
client
server
raix commentedon Mar 23, 2014
@lleonard188: image-uploader example gist
aldeed commentedon Mar 24, 2014
I just went through the main package readme and attempted to get all the errors corrected. Still needs work but in general the API examples should be correct as of this moment.
raix commentedon Mar 24, 2014
Cool 👍 The api is settling, feels nice - Auto tests should be up and running, cfs-file may need some love, We need to work a bit on the worker etc. I'll try to update milestones etc. To get some overview of status.
13 remaining items
aldeed commentedon Mar 26, 2014
Basically what you want to do is download the binary and attach it to the file object so that you can display it from a data URI. So:
Download the data:
Use
fileObj.url({store: yourStoreName})to get the URL. Then use an XMLHttpRequest to get the arraybuffer data from that URL.Attach the data:
Pass the arraybuffer to
attachData. (fileObj.attachData(arrayBuffer))Get data URI:
For those first two steps, I think we can add an
attachDataFromStoremethod on the client to make that simple, or maybeattachData({store: storeName}).raix commentedon Mar 29, 2014
Update:
FS.TempStorenow uses theStorage Adapterapi and defaults toFS.Store.FileSystemorFS.Store.GridFSdepending on installed packages. Filesystem is preferred unlesscfs-workeris in the project, thenFS.Store.GridFSis preferred due to scalability over multiple instances of Meteor.Added code documentation
FS.TempStorehttps://github.com/CollectionFS/Meteor-cfs-tempstoreraix commentedon Mar 31, 2014
I think we have to rework some of the stuff to take better advantage of the simpler streaming api #239
I havent tested that part of the api, but I see a node fs dependency and thats potentially a problem when deploying.
But yes, the docs seems to be ok, we just need to align the api :)
aaronjudd commentedon Apr 2, 2014
Two comments, in the above example:
would be great if examples of accessing data from code, not just templates were provided wherever possible . Took me some time to find this.
Also at the moment:
causes ReferenceError: mountUrls is not defined
Wasn't sure if it was doc error, as I saw some comments on the update api docs on this. (but not working for me yet)
Last note, @raix and @aldeed - this is becoming an incredibly useful project - right on par with Collections2 - my kudos for an amazing job. Hope we all have stable projects out for meteor 1.0
aldeed commentedon Apr 3, 2014
@aaronjudd, I fixed the setBaseUrl issue now.
aldeed commentedon Apr 3, 2014
@casperanderseneu, currently I'm getting a "RangeError: Maximum call stack size exceeded" error when doing server-side insert of filepath or URL, like your example. I don't know if this is what you're getting, too. I couldn't figure out the cause at the moment, but maybe @raix will have an idea. Further discussion can move to #246.
calculon0 commentedon Apr 7, 2014
The current README uses
in a few locations. But that throws an error of "DataMan constructor received data that it doesn't support". Changing it to
makes it work.
aldeed commentedon Apr 8, 2014
@calculon0, what type is
file? Is it a browserFileobject? DataMan should support it, especially because if you pass it to theFS.Fileconstructor, it passes it along toattachDatafor you anyway.calculon0 commentedon Apr 8, 2014
@aldeed I think the issue is the error is being thrown when the constructor is empty. I don't think DataMan allows an empty constructor.
aldeed commentedon Apr 8, 2014
OK, I guess that's correct behavior then, but we could add a more specific error.
abuddenb commentedon Aug 22, 2014
An example of how to insert a Buffer would be great. I wrestled with it all afternoon:
The options object on attachData() could really use a writeup.
aldeed commentedon Aug 22, 2014
@abuddenb, if you want to submit a PR with readme updates, we would accept that. There are also lots of examples in the unit tests for the
cfs-filepackage, which could be linked to.https://github.com/CollectionFS/Meteor-cfs-file/blob/master/tests/file-tests.js#L123