Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Write using saved mime type #403

Merged
merged 8 commits into from
Aug 5, 2018
Merged

Conversation

qw3n
Copy link
Contributor

@qw3n qw3n commented Feb 12, 2018

This allows filenames without a suffix to save properly using the already established MIME type. Closes #114. Though, this doesn't add any functionality for changing the mime type as referenced in the issue #114.

Note: MIME.lookup(path) is actually already being used to obtain the value that this.getMIME() references.

This allows filenames without a suffix to save properly using the already established MIME type. Closes jimp-dev#114. Though, this doesn't add any functionality for changing the mime type as referenced in the issue jimp-dev#114.

Note: MIME.lookup(path) is actually already being used to obtain the value that this.getMIME() references.
@hipstersmoothie
Copy link
Collaborator

@qw3n If you update this I'll merge it

@hipstersmoothie
Copy link
Collaborator

make the same update to line 230 in the README too https://github.com/oliver-moran/jimp/pull/429/files

@qw3n
Copy link
Contributor Author

qw3n commented Jul 31, 2018

Are the updates your referencing the resolution of the conflicts and the readme or is there something else?

@hipstersmoothie
Copy link
Collaborator

Yeah. I need you to:

  1. resolve conflicts (I can help if you need)
  2. Update the readme to reflect the ability to infer the mime type
  3. A test would be cool too

qw3n added 5 commits July 31, 2018 14:23
If neither is set getMIME defaults to type PNG
Added an example to the code as well as mentioning that it all defaults to PNG
@qw3n
Copy link
Contributor Author

qw3n commented Jul 31, 2018

I'm looking at writing a test, but I don't see one for the write method. So starting from scratch I'm not sure what the best method is for testing that function specifically. For example is there a way of testing it without actually saving the image or even needing a sample image.

@hipstersmoothie
Copy link
Collaborator

Look at the async tests. the one called 'write returns promise' writes and deletes a file

@qw3n
Copy link
Contributor Author

qw3n commented Aug 1, 2018

So I'm having a little trouble figuring out how to test for the MIME type of the image without using the path extension. Do you have any suggestions?

src/index.js Outdated
@@ -397,7 +397,7 @@ class Jimp extends EventEmitter {
return throwError.call(this, 'cb must be a function', cb);
}

const mime = MIME.getType(path);
const mime = MIME.getType(path) || this.getMime();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't the name of the function. It's actually getMIME

@hipstersmoothie
Copy link
Collaborator

hipstersmoothie commented Aug 1, 2018

    it('write uses original MIME type', done => {
        const writePath = './test.png';

        if (process.env.BABEL_ENV === undefined) {
            return done();
        }

        new Jimp(imagesDir + '/dice.png', function(err) {
            if (err) done(err);

            this.write(writePath.split('.png')[0], (err, image) => {
                if (err) done(err);

                should.exist(image);
                fs.existsSync(writePath).should.be.true();
                fs.unlinkSync(writePath);
                done();
            });
        });
    });

@qw3n
Copy link
Contributor Author

qw3n commented Aug 1, 2018

So you're saying if there is no extension the code should force add it to the path name.

The original reason I ran into this was in working with file uploads. You can say where you want to save the file, but the default multer naming mechanism merely gives it a hash name with no extension. Which didn't seem to be a problem since I was storing the name in a database and I had already limited uploads to jpg and png. With this though I would have to have another step to adjust the database entry after jimp has modified the file name. Just something to consider.

Also, this was supposed to be a simple edit didn't realize it would get quite so complicated.

@hipstersmoothie
Copy link
Collaborator

hipstersmoothie commented Aug 1, 2018 via email

@hipstersmoothie
Copy link
Collaborator

Couldn’t you just get the buffer and ace as you want to? That would probably be simpler than having jimp wrote the file @qw3n

@qw3n
Copy link
Contributor Author

qw3n commented Aug 1, 2018

I know you can write without extensions, because six months ago I modified my local jimp copy with the code from the original pull request and it worked fine.

In my particular use case with multer I wasn't using jimp to write the original file. I was using it to create a thumbnail copy in a thumbs folder with the same name as the original. Multer comes with an option to automatically name uploaded files based on a hash, however, you don't have any control over the name. If I had absolutely had to have extensions multer provides a hook to name a file, but then I would have had to pull in a package to do the exact same hashing etc. all so I could then add an extension on the end.

This is just my experience, but given the way multer worked it just seemed easier to ignore extensions since the browser uses content headers not extensions to determine filetype.

Also, assuming you decide extensions aren't required, then you could use the file-type module to get the MIME type of the generated image, but the image would have to loaded and then converted to a buffer. Is that feasible or would that slow down the tests to much?

@hipstersmoothie
Copy link
Collaborator

I'm fine with saving without an extension. I just can't get the code to work

Here is my current write function with your changes

    write(path, cb) {
        if (!FS || !FS.createWriteStream) {
            throw new Error(
                'Cant access the filesystem. You can use the getBase64 method.'
            );
        }

        if (typeof path !== 'string') {
            return throwError.call(this, 'path must be a string', cb);
        }

        if (typeof cb === 'undefined') {
            cb = noop;
        }

        if (typeof cb !== 'function') {
            return throwError.call(this, 'cb must be a function', cb);
        }

        const mime = MIME.getType(path) || this.getMIME();
        const pathObj = Path.parse(path);

        if (pathObj.dir) {
            MkDirP.sync(pathObj.dir);
        }

        this.getBuffer(mime, (err, buffer) => {
            if (err) {
                return throwError.call(this, err, cb);
            }

            const stream = FS.createWriteStream(path);

            stream
                .on('open', () => {
                    stream.write(buffer);
                    stream.end();
                })
                .on('error', err => {
                    return throwError.call(this, err, cb);
                });
            stream.on('finish', () => {
                return cb.call(this, null, this);
            });
        });

        return this;
    }

and the test i provided I keep getting this error:

  1) FileType
       write uses original MIME type:
     Error: EISDIR: illegal operation on a directory, open './test

@qw3n
Copy link
Contributor Author

qw3n commented Aug 1, 2018

The error itself was telling us the problem. Took me way to long to realize we already have a test directory so that is what fs is establishing a connection to. If you change the name to ./test1 or ./imgs/test it works.

@hipstersmoothie hipstersmoothie added the enhancement a request for a new feature or change in behavior label Aug 4, 2018
@hipstersmoothie hipstersmoothie merged commit f6a04ad into jimp-dev:master Aug 5, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement a request for a new feature or change in behavior
Projects
None yet
Development

Successfully merging this pull request may close these issues.

write() to a filename w/o image extension triggers a mimetype error
2 participants