2015-04-01 79 views
0

我对节点相对比较陌生,并且希望编写一个模块,它从S3存储桶中获取图像,调整大小并将其保存到亚马逊的新Lambda服务的临时目录中,然后上传图像回到桶。节点调整图像大小并上传到AWS

当我运行代码时,我的函数似乎没有被调用(download,transformupload)。我正在使用tmp创建临时目录,并使用graphicsMagick来调整图像大小。

我的代码有什么问题?

我已经定义了模块外的依赖关系和数组,因为我有另一个依赖于这些的模块。

// dependencies 
var AWS = require('aws-sdk'); 
var gm = require('gm').subClass({ imageMagick: true }); 
var fs = require("fs"); 
var tmp = require("tmp"); 

// get reference to S3 client 
var s3 = new AWS.S3(); 

var _800px = { 
    width: 800, 
    destinationPath: "large" 
}; 

var _500px = { 
    width: 500, 
    destinationPath: "medium" 
}; 

var _200px = { 
    width: 200, 
    destinationPath: "small" 
}; 

var _45px = { 
    width: 45, 
    destinationPath: "thumbnail" 
}; 

var _sizesArray = [_800px, _500px, _200px, _45px]; 

var len = _sizesArray.length; 

exports.AwsHandler = function(event) { 
    // Read options from the event. 
    var srcBucket = event.Records[0].s3.bucket.name; 
    var srcKey = event.Records[0].s3.object.key; 
    var dstnKey = srcKey; 

    // create temporary directory 
    var tmpobj = tmp.dirSync(); 

    // function to determine paths 
    function _filePath (directory, i) { 
     if (!directory) { 
      return "dst/" + _sizesArray[i].destinationPath + "/" + dstnKey; 
     } else { 
      return directory + "/dst/" + _sizesArray[i].destinationPath + "/" + dstnKey; 
     } 
    }; 


    // Infer the image type. 
    var typeMatch = srcKey.match(/\.([^.]*)$/); 
    if (!typeMatch) { 
     console.error('unable to infer image type for key ' + srcKey); 
     return; 
    }; 

    var imageType = typeMatch[1]; 

    if (imageType != "jpg" && imageType != "png") { 
     console.log('skipping non-image ' + srcKey); 
     return; 
    }; 


    (function resizeImage() { 
     function download() { 

      console.log("started!"); 

      s3.getObject({ 
        Bucket: srcBucket, 
        Key: srcKey 
       }, 
       function (err, response) { 
        if (err) { 
         console.error(err); 
        } 
        // call transform if successful 
        transform (response); 
       } 
      ); 
     }; 

     function transform (response) { 

      for (var i = 0; i<len; i++) { 

       // define path for image write 
       var _Key = _filePath (tmpobj, i); 

       // resize images 
       gm(response.Body, srcKey) 
        .resize(_sizesArray[i].width) 
        .write(_Key, function (err) { 
         if (err) { 
          console.error(err); 
         } 
         upLoad(); 
        }); 
      } 
     }; 

     function upLoad() { 

      for (var i = 0; i<len; i++) { 

       var readPath = _filePath (tmpobj, i); 

       var writePath = _filePath (i); 

       // read file from temp directory 
       fs.readFile(readPath, function (err, data) { 
        if (err) { 
         console.error(err); 
        } 

        // upload images to s3 bucket 
        s3.putObject({ 
         Bucket: srcBucket, 
         Key: writePath, 
         Body: data, 
         ContentType: data.type 
        }, 
        function (err) { 
         if (err) { 
          console.error(err); 
         } 
         console.log("Uploaded with success!"); 
        }); 
       }) 
      } 
      // Manual cleanup of temporary directory 
      tmpobj.removeCallback(); 
     }; 
    }()); 
}; 
+0

你从没叫过'下载()' – Plato 2015-04-01 15:04:26

+0

我的印象是,LAMBDA叫它下。不过,我刚刚发现,我需要配置它必须调用哪个函数。这是否意味着我的节点代码被正确写入了? – hyprstack 2015-04-01 15:07:35

+0

这有点复杂,你可以使它更清洁,但我没有注意到任何明显的错误。 lambda将运行,但它所做的是在内部定义三个函数:download,transform,upLoad。那么它会调用tmpObj.removeCallback()。 – Plato 2015-04-01 15:23:24

回答

0

以下是部分改进,请注意使用async库。你会在upLoad()中遇到问题,因为你立即发起了四次异步调用(在for循环中),并且没有简单的方法知道它们什么时候完成。 (当然,简单的方法是重写使用异步库的功能,如async.forEach)

// dependencies 
var AWS = require('aws-sdk'); 
var gm = require('gm').subClass({ imageMagick: true }); 
var fs = require("fs"); 
var tmp = require("tmp"); 
var async = require("async"); 

// get reference to S3 client 
var s3 = new AWS.S3(); 

var _800px = { 
    width: 800, 
    destinationPath: "large" 
}; 

var _500px = { 
    width: 500, 
    destinationPath: "medium" 
}; 

var _200px = { 
    width: 200, 
    destinationPath: "small" 
}; 

var _45px = { 
    width: 45, 
    destinationPath: "thumbnail" 
}; 

var _sizesArray = [_800px, _500px, _200px, _45px]; 

var len = _sizesArray.length; 

exports.AwsHandler = function(event) { 
    // Read options from the event. 
    var srcBucket = event.Records[0].s3.bucket.name; 
    var srcKey = event.Records[0].s3.object.key; 
    var dstnKey = srcKey; 

    // create temporary directory 
    var tmpobj = tmp.dirSync(); 

    // function to determine paths 
    function _filePath (directory, i) { 
    if (!directory) { 
     return "dst/" + _sizesArray[i].destinationPath + "/" + dstnKey; 
    } else { 
     return directory + "/dst/" + _sizesArray[i].destinationPath + "/" + dstnKey; 
    } 
    }; 


    // Infer the image type. 
    var typeMatch = srcKey.match(/\.([^.]*)$/); 
    if (!typeMatch) { 
    console.error('unable to infer image type for key ' + srcKey); 
    return; 
    }; 

    var imageType = typeMatch[1]; 

    if (imageType != "jpg" && imageType != "png") { 
    console.log('skipping non-image ' + srcKey); 
    return; 
    }; 


    // Actually call resizeImage, the main pipeline function: 
    resizeImage(function(err){ 
    // Done. Manual cleanup of temporary directory 
    tmpobj.removeCallback(); 
    }) 


    function resizeImage (callback) { 
    var s3obj = { 
     Bucket: srcBucket, 
     Key: srcKey 
    }; 
    download(s3obj, function(response){ 
     var gmConfigs = sizesArray.map(function(size, i){ 
     return { 
      width: size.width 
      _Key: _filePath (tmpobj, i) 
     } 
     }) 

     async.eachSeries(gmConfigs, 
     function(config, done){ 
     transform(response, config.width, config._Key, done) 
     }, 
     function(err){ 
     if(err){ 
      console.log(err); 
     } else { 
      upLoad(); 
      // Further work is required to identify if all the uploads worked, 
      // and to know when to call callback() here 
      // callback(); 
     } 
     }) 
    }) 
    } 

    function download (s3obj, callback) { 
    console.log("started!"); 

    s3.getObject(s3obj, function (err, response) { 
     if (err) { 
     console.error(err); 
     } 
     // call transform if successful 
     callback(response); 
    }); 
    }; 

    function transform (response, width, _Key, callback) { 
    // resize images 
    gm(response.Body, srcKey) 
    .resize(width) 
    .write(_Key, function (err) { 
     if (err) { 
     console.error(err); 
     } 
     callback(); 
    }); 
    }; 

    function upLoad() { 
    for (var i = 0; i<len; i++) { 
     var readPath = _filePath (tmpobj, i); 
     var writePath = _filePath (i); 
     // read file from temp directory 
     fs.readFile(readPath, function (err, data) { 
     if (err) { 
      console.error(err); 
     } 

     // upload images to s3 bucket 
     s3.putObject({ 
      Bucket: srcBucket, 
      Key: writePath, 
      Body: data, 
      ContentType: data.type 
     }, 
     function (err) { 
      if (err) { 
      console.error(err); 
      } 
      console.log("Uploaded with success!"); 
     }); 
     }) 
    } 
    }; 

};