npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

s3-image-uploader

v1.0.7

Published

A Node.js module for resizing, and uploading files to Amazon S3 with capability to track progress using websockets.

Downloads

87

Readme

#s3-image-uploader

npm npm npm

A Node.js module for resizing, and uploading files to Amazon S3 with capability to track progress using websockets.

This module was created to use with little setup and customization as it's simply a wrapper of AWS SDK and gm. This module also utilizes Websockets, which can be optionally enabled to allow the server to send the client messages such as file upload completion and upload progress.

Installation

Install package with NPM and add it to your dependencies.

$ npm install s3-image-uploader --save

Dependencies

When you npm install this module - the module dependencies are added (s3, gm, ws), however you'll need to make sure GraphicsMagick is installed on your server. GraphicsMagick is the image manipulation library this module uses.

Also, you'll need to pay attention to how you're server handles timeouts.

I used the following code in my Express application to make sure the post didn't timeout:

app.post('/post-image', function(req, res, next){

  res.connection.setTimeout(0); // this could take a while
  // code to execute post here

});

Usage

Below is the basic configuration, but you can see full example code here

Server Side (Node)

Include the module.

var Uploader = require('s3-image-uploader');

Instantiation

Instantiate the uploader with options. Note that if we didn't want to use websockets functionality - we would add to our options websockets : false.

Also, note that we're using properties of the user environment, but these could be variables or hard coded if preferred (not ideal for security).

var uploader = new Uploader({
  aws : {
    key : process.env.NODE_AWS_KEY,
    secret : process.env.NODE_AWS_SECRET
  },
  websocketServer : server,
  websocketServerPort : 3004,
});

Resize

Width and height options denote the maximum size for the dimension (will be exact if the other dimension is set to 'auto'... but upsizing will not happen). If not defined or set to 'auto' - the dimension will be resized based on aspect ratio of the other. Aspect ratio is always maintained. If square : true is set and width/height are equal, the smaller dimension will be sized down and the larger will be trimmed off outside of the center.

fileId is important for the websockets functionality. It's referenced in messages sent to the client about the status. Therefore you may want to use this same identifier as a DOM selector in your client side code (maybe a data attribute) to target visual representations of the messages.

uploader.resize({
  fileId : 'someUniqueIdentifier',
  width : 600,
  height : 'auto',
  source : './public/tmp/myoldimage.jpg',
  destination : './public/uploads/mynewimage.jpg'
}, function(destination){
  console.error('resize success - new image here: ', destination);
  // execute success code
}, function(errMsg){
  console.error('unable to resize: ', errMsg);
  // execute error code
});

Validate File Type

This validates the content type referenced in the header of the file.

fileId is again referenced in messages sent to the client about the status.

if(uploader.validateType(file, fileId, ['image/jpeg', 'image/gif', 'image/png'])) {
  console.log('validation passed!');
  // execute success code
}

Get Exif Data

Get the exif data object.

uploader.getExifData(filePath, function(data){

  // normally I'd do something with this... like store it in a database
  console.log('exif data', data);

});

Get Image Size

Get dimension object from image. The below code will log something like this: { width: 1200, height: 900 } This method uses the GraphicsMagick size method. Find more documentation here.

uploader.getSize(filePath, function(data){

  console.log('image size data', data);

});

Upload

Upload the file to s3.

fileId is again referenced in messages sent to the client about the status.

uploader.upload({
  fileId : 'someUniqueIdentifier',
  bucket : 'somebucket',
  source : './public/tmp/myoldimage.jpg',
  name : 'mynewimage.jpg'
},
function(data){ // success
  console.log('upload success:', data);
  // execute success code
},
function(errMsg, errObject){ //error
  console.error('unable to upload: ' + errMsg + ':', errObject);
  // execute error code
});

Delete

Delete an array of files from AWS (array can include only one file if desired).

uploader.delete('somebucket', ['cat.jpg', 'dog.png', 'turtle.gif'], function(data){
  console.log('yay!', data);
}, function(err){
  console.log('fail!', err);
});

Options

new Uploader

  • @param {object} options - Configuration object. Required.
    • {object} options.aws - aws object. Required.
    • {string} options.aws.key - aws key string. Required.
    • {string} options.aws.secret - aws secret string. Required.
    • {object} options.websocketServer - WebSocket server object. Optional.
    • {number} options.websocketServerPort - WebSocket server port. Optional.
    • {object} options.s3Params - object that can extend the S3 parameters listed here http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html. Optional. Example: s3Params : { 'CacheControl' : 'max-age=3600'}

resize

  • @param {object} options - Configuration object. Required.
    • {string} options.fileId - Used to uniquely identify file. Required.
    • {number || 'auto'} options.width - Maximum width allowed for resized image. Otherwise if not defined or set to 'auto' - width will be resized based on aspect ratio of height. Optional. Default is 'auto'.
    • {number || 'auto'} options.height - Maximum height allowed for resized image. Otherwise if not defined or set to 'auto' - height will be resized based on aspect ratio of width. Optional. Default is 'auto'.
    • {string} options.source - Path to the image to be resized. Required.
    • {string} options.destination - Path to new image after resize. Required.
    • {number} options.quality - Quality for resized image (1-100... 100 is best). Optional. Default is 100.
    • {boolean} options.square - boolean flag set to true if the image needs to be square. Optional. Default is false.
    • {boolean} options.noProfile - boolean flag set to true if exif data should be removed (minimizing file size). Optional. Default is true.
    • {number || boolean} options.maxFileSize - can be a number or boolean false. The number represents file size in MegaBytes. Optional. Default is false.
  • @param {function} successCallback - Callback function. Receives one argument - {string} path to resized file. Required.
  • @param {function} errorCallback - Callback function. Receives one argument - {string} error message. Required.

validateType

  • @param {object} file - Post object. Required.
  • @param {string} id - Used to uniquely identify file. Required.
  • @param {array} types - Array of string file content types (example: ['image/jpeg', 'image/gif', 'image/png']). Required.

getExifData

  • @param {string} source - Path of image. Required.
  • @param {function} callback - Callback that receives argument of false or data object. Required.

getSize

  • @param {string} source - Path of image. Required.
  • @param {function} callback - Callback that receives argument of false or data object. Required. The received data object will be in a format similar to this: { width: 1200, height: 900 }

upload

  • @param {object} options - Configuration object. Required.
    • {string} options.fileId - Used to uniquely identify file. Required.
    • {string} options.bucket - S3 bucket. Required.
    • {string} options.source - Path to the image to be uploaded. Required.
    • {string} options.name - Name to be used for new file uploaded to S3. Required.
    • {number || boolean} options.maxFileSize - can be a number or boolean false. The number represents file size in MegaBytes. Optional. Default is false.
  • @param {function} successCallback - Callback function. Receives one argument - {object} status object. Required.
  • @param {function} errorCallback - Callback function. Receives two arguments - {string} error message. {object} error stack trace. Required.

delete

  • @param {string} bucket - AWS bucket name. Required.
  • @param {array} fileNames - Array of string filenames (example: ['cat.jpg', 'dog.png', 'turtle.gif']). Required.
  • @param {function} successCallback - Callback that receives data object. Required.
  • @param {function} errorCallback - Callback that receives error object. Optional.

On the Client Side

Please see a full example here.

The most important thing to consider here is that we're receiving fileId from the server as id to uniquely identify the upload. We receive message objects via websockets. Below are examples of different messages we might receive on the client.

Error message

{
  type : 'error',
  id : 'someUniqueIdentifier',
  message : 'There was a problem uploading this file.'
}

Upload progress message

{
  type : 'progress',
  id : 'someUniqueIdentifier',
  progressAmount : 5276653, // represents bytes
  progressTotal : 6276653 // represents bytes
}

Upload success message

{
  type : 'result',
  id : 'someUniqueIdentifier',
  path : '/mybucket/myimage.jpg'
}

Resize success message

{
  type : 'resize',
  id : 'someUniqueIdentifier',
  size : '100x100'
}

So, a simple implementation of this might look something like this.

Make the websocket connection.

var host = window.document.location.host.replace(/:.*/, '');
var ws = new WebSocket('ws://' + host + ':8080');

Handle messages from the server about the progress of our upload/s and resizing.

ws.onmessage = function(event){
  var message = JSON.parse(event.data);
  if(typeof message.type !== 'undefined') {
    if(message.type === 'progress') // execute code for progress
    else if(message.type === 'result') // execute code for result
    else if(message.type === 'resize') // execute code for resize status
    else if(message.type === 'error') // execute code for error messages
  }
};