heapsource / mongoose-attachments Goto Github PK
View Code? Open in Web Editor NEWAttachments Plugin for Mongoose.js with Support for ImageMagick Styles and Multiple Storage Backends
License: MIT License
Attachments Plugin for Mongoose.js with Support for ImageMagick Styles and Multiple Storage Backends
License: MIT License
Hi I am new to mongoose-attachments. When I try the example I get a TypeError: Object { _id: 5219f3858ec1ba1c28000001 } has no method 'attach' .
I have tried everything please advise if I am doing anything wrong. I use the latest versions of Mongoosejs, Node and Express.
I tried to use it with all providers but no luck.
When I attach an image, this is what req.file.image returns. The path does not include an extension although that seems to be where mongoose-attachments is grabbing the extension. Would it be better to grab it from name? Will that always include the extension?
Here's a returned file image object example:
{ domain: null,
_events: null,
_maxListeners: 10,
size: 39907,
path: '/var/folders/0p/j35t5_z11zj_qv9nnqqzvmtw0000gr/T/65bd99d6a382b583ad8e9b2c39728b76',
name: 'image-name.jpg',
type: 'image/jpeg',
hash: null,
lastModifiedDate: Sat Jun 29 2013 16:43:31 GMT-0700 (PDT),
_writeStream:
{ domain: null,
_events: null,
_maxListeners: 10,
path: '/var/folders/0p/j35t5_z11zj_qv9nnqqzvmtw0000gr/T/65bd99d6a382b583ad8e9b2c39728b76',
fd: 24,
writable: false,
flags: 'w',
encoding: 'binary',
mode: 438,
bytesWritten: 39907,
busy: false,
_queue: [],
_open: [Function],
drainable: true,
flush: [Function],
write: [Function],
end: [Function],
destroy: [Function],
destroySoon: [Function],
pipe: [Function],
setMaxListeners: [Function],
emit: [Function],
addListener: [Function],
on: [Function],
once: [Function],
removeListener: [Function],
removeAllListeners: [Function],
listeners: [Function] },
open: [Function],
toJSON: [Function],
write: [Function],
end: [Function],
setMaxListeners: [Function],
emit: [Function],
addListener: [Function],
on: [Function],
once: [Function],
removeListener: [Function],
removeAllListeners: [Function],
listeners: [Function] }
Can the path be a absolute URL to a remote file?
Hi, Im using mongoose-attachments-aws2js, I had the next error the first time I used it:
TypeError: Object {xxxxx} has no method 'attach'
I was loading it with:
attachments = require("mongoose-attachments-aws2js")
I fixed it doing the next:
require("mongoose-attachments-aws2js")
attachments = require("mongoose-attachments")
But now, when I deploy it on heroku i get this error:
Error: Storage Provider "aws2js" can not be found
What can I do?
Hi,
my application checks for mime type image/* and allows everything that comes along. Now, a BMP fails as it is not by default in the list of supportedDecodingFormats (line 30 of attachements.js).
It came as a bit of a surprise that there is such a list of supported formats, in the first place. Might be a bit naive of me (?) but I would have thrown everything at ImageMagick which could be handled by its "identify" method. This just seems like an unnecessary restriction at this point.
With this white list I'm quite stuck. Can we agree on a possibility to make it optional? Something like "if the list is not empty: use it - otherwise do not use it"? Maybe make it even the default not to use it?
I could create a pull request for that solution. Or is there some other, better way?
events.js:72
throw er; // Unhandled 'error' event
^
Error: spawn ENOENT
at errnoException (child_process.js:975:11)
at Process.ChildProcess._handle.onexit (child_process.js:766:34)
I use this the following to convert multi-page pdfs to thumbs. Makes the process much faster:
convert -thumbnail x300 source.pdf[0] dest.jpg
(notice the [0])
How can I reproduce this with mongoose-attachments?
If filenameId is not defined in the settings now, all files are saved as 'undefined-style.extension' - selfModel.id does not seem to be defined.
For now it can be worked around by always setting "fileNameID": "_id"
Currently, to use mongoose-attachments you need to require the provider as well as the core module. The Readme is not completely clear about this. It says that mongoose-attachments comes bundled with each provider but the examples still show the old way. (Or maybe I'm just reading it wrong?)
Anyway, I think it would be a good thing to allow:
var attachments = require('mongoose-attachments-localfs');
(for all providers)
The steps for this are:
This is a requirement for #15 .
Cool plugin..
I don't see an obvious way to define and utilize this plugin as an array of attachments. Is this a feature your planning?
Hello,
My uses cases required me to have more than one mongoose-field in my schema and I did that, applying the plugin in this way:
pageSchema.plugin(mongooseAttachments, {
directory: 'images',
storage: {
providerName: 's3',
options: {
key: 'my aws key'
secret: 'my aws secret'
bucket: 'my aws bucket'
}
},
properties: {
design_background_image: {
styles: {
original: {
//keep the original file
},
ipad_2_landscape: {
resize: '1024x768>',
blur: '3x3'
},
ipad_2_portrait: {
resize: '768x1024>',
blur: '3x3'
}
},
design_banner_image: {
styles: {
original: {
// keep the original file
},
ipad_2_landscape: {
resize: '1024x768>'
},
ipad_2_portrait: {
resize: '768x1024>'
}
}
},
avatar: {
styles: {
original: {
// keep the original file
}
}
}
}
});
The plugin works fine but I realized that if the two or more files to upload in two or more of the specified fields had the same extension then the files uploaded for each transformation were the same for all of them and it was one file between them.
After debugging to try to solve that issue and I could continue using this awesome module, I realized that the problem was (and is because I checked the code in the current file of the tag 0.0.4) in the line 170 of the file lib/attachments.js,
var storageStylePath = '/' + options.directory + '/' + selfModel.id + '-' + styleName + ext;
and it may fix it quite easy only using the original file name which is figured in the line 151 rather than the document id.
However to avoid to remove the file extension of the file name in each call to forEach function I declared a new variable after the line 160 and I used that variable in the line 170, so the result was something like:
// Below the line 160
var fileNameNoExt = path.basename(attachmentInfo.name, fileExt);
........
// line 170 replaced by
var storageStylePath = '/' + options.directory + '/' + fileNameNoExt + '-' + styleName + ext;
I solved my use case however I am calling 'attach' with and stand-alone rather than using express uploads, and although I think that it would also work well, I cannot be 100% sure, because I haven't tested it in that way.
Could you update the release of npm to carry on using the module from npm rather than use like a local library in my development?
Thanks so much.
I've been trying to work out how get a proper directory structure using this app. What I want is this:
3 main image types:
userImage and userBackground will be attached to the user model, while the postImages will be attached to the individual post documents.
I'd like to end up with the following structure so deleting a user and all of their content from the S3 is as easy as possible:
Example based on userImage:
user.ObjectID/model.Name/imageName/imageStyleName.extension
5224a679aeac8a241e000001/user/userImage/small.jpg
5224a679aeac8a241e000001/user/userImage/medium.jpg
5224a679aeac8a241e000001/user/userImage/large.jpg
Example based on postImage
user.ObjectID/user/post/post.ObjectID/imageID-style.extension
5224a679aeac8a241e000001/posts/5224a679aeac8a241e000001/5224a679aeac8a241e000001-large.jpg
When I delete the user, this way I can just tell it to delete the users folder and all of their files are gone from S3.
For the life of me I can't seem to achieve it. I can't get the id of the user being saved from 'this.id' or figure out a way to add any parameters to the filename aside from -style.extention
How would I accomplish this?
In my app I have default image headers for places. When the imagemagick conversion fires, it is dumping the converted files into the same directory as the original file, causing pollution and breaking my apps logic as the default files all have a specific naming convention. readdirSync does not support specifying file patterns and will read all files in the dir.
I want imagemagick to put the converted images into temp or a cache directory away from my originals. How can I do this?
the master branch's test are currently red.
I could not find any doc on how specify the image when updating a document.
I could not use findById to get the document and then call "attach" as the method is not on the document, it is available only on the model itself.
This line var attachments = require('mongoose-attachments-aws2js');
in the readme indicates that you can pass this directly to TargetSchema.plugin(attachments)
.
In practice, this didn't work. I inspected attachments
and got this.
function S3Storage(options) {
attachments.StorageProvider.call(this, options);
s3.setCredentials( options.key, options.secret );
s3.setBucket( options.bucket );
this.acl = options.acl || false;
this.client = s3;
this.endpoint = options.endpoint || ( 'https://' + options.bucket + '.s3.amazonaws.com' );
}
Whereas when i used var attachments = require('mongoose-attachments'), attachments_s3 = require('mongoose-attachments-aws2js');
I got this when I inspected attachments
function (schema, options) {
options = options || {};
if(typeof(options.directory) !== 'string') throw new Error('option "directory" is required');
if(typeof(options.properties) !== 'object') throw new Error('option "properties" is required');
if(typeof(options.storage) !== 'object') throw new Error('option "storage" is required');
var storageOptions = options.storage;
storageOptions.schema = schema;
if(typeof(storageOptions.providerName) !== 'string') throw new Error('option "storage.providerName" is required');
var providerPrototype = findProvider(storageOptions.providerName)
//truncated for brevity
You get the point, the actual plugin code that patches the schema seem to only be exposed when requiring the core plugin, requiring the storage provider mongoose-attachments-aws2js
only exports the storage provider itself?
Not sure if this is an issue on my end, or an issue with the docs but I thought I would bring it to your attention.
or has it been abandoned in favor to mongoose-crate?
Hello.
How to remove files? I call doc.remove() it's popped out of mongo, but images are still on the s3...
How's gonna clear that stuff? Can't find the subject in the docs...
Thank you,
Serge
Currently for S3 integration the module requires we specify an AWS key and secret. This makes sense if your app is not running on EC2 but if your app is running on EC2 the AWS best practices state that you should use an IAM Role when you need one service to access another.
We recently started converting our services to use IAM Roles but then hit a wall when we noticed that the AWS keys are required for mongoose-attachments to work.
In order to reflect recent changes, We need to:
I have the following code in my tests, but the callback function is never actually called so I presume something is wrong when attach executes. Could this be related to node's 0.8.x migration? I changed the path.exists to fs.exists per the pull request but it still won't work?
var testPhoto = new Photo({ owner : 'test',
caption : 'test caption',
ratings : [] });
testPhoto.attach('image', { path: 'test/resources/test.png' }, function(err) {
testPhoto.save();
photosToRemove.push(testPhoto);
});
Hi @thepumpkin1979
the tag 0.1.0 is outdated because my last merges add to the content of 0.1.0 but occurred only after the tagging. As my last merges are fixes to the code so that it behaves as already documented for 0.1.0, they should be part of 0.1.0, I guess?
See for example #31 (comment) and my follow-up comment.
Cheers!
The attach
method deletes the image it just attached when it's done.
My integration tests attach images to object. In tests, I have to read my fixture file, create a tmp file for it, then attach it since mongoose-attachments is going to delete it. That's a lot of overhead for something the library shouldn't be doing.
Hello, I have this problem:
When I upload an image, in the controller I do
obj.attach('image', req,body.file, function(err){
if(err)
{ console.log("Error "+error)}
else
{console.log("No error")});
And in the console it says attachmentInfo is not valid.
I have copy-pasted the codes from your github readme, and my credentials are correct too. So I'm wondering why this is happening.
Code:
ImageSchema.plugin attachments,
directory: "exlab"
storage:
providerName: "s3"
options:
key: ""
secret: ""
bucket: ""
properties:
image:
styles:
original:
"adaptive-resize": "1200x900\>"
"$format": "jpg"
small:
gravity: "Center"
"thumbnail": "66x"
crop: "66x47"
"$format": "jpg"
Causes:
{ [Error: Command failed: identify: unable to open image `/tmp/e0981b54de9870451df7ede2292d258b-small.jpg': No such file or directory @ error/blob.c/OpenBlob/2638.
] timedOut: false, killed: false, code: 1, signal: null }
Error: Command failed: identify: unable to open image `/tmp/e0981b54de9870451df7ede2292d258b-small.jpg': No such file or directory @ error/blob.c/OpenBlob/2638.
As I can guess -small.jpg
shouldn't be added to the file name
Can non image file types be attached?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.