forked from sailyapp/aws-s3-lambda-thumbnail-generator
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
executable file
·121 lines (101 loc) · 3.33 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
var async = require("async");
var AWS = require("aws-sdk");
var gm = require("gm").subClass({imageMagick: true});
var fs = require("fs");
var mktemp = require("mktemp");
var THUMB_KEY_PREFIX = "thumbnails/",
THUMB_WIDTH = 300,
THUMB_HEIGHT = 300,
ALLOWED_FILETYPES = ['png', 'jpg', 'jpeg', 'bmp', 'tiff', 'pdf', 'gif'];
var utils = {
decodeKey: function(key) {
return decodeURIComponent(key).replace(/\+/g, ' ');
}
};
var s3 = new AWS.S3();
exports.handler = function(event, context) {
var bucket = event.Records[0].s3.bucket.name,
srcKey = utils.decodeKey(event.Records[0].s3.object.key),
dstKey = THUMB_KEY_PREFIX + srcKey.replace(/\.\w+$/, ".jpg"),
fileType = srcKey.match(/\.\w+$/);
if(srcKey.indexOf(THUMB_KEY_PREFIX) === 0) {
return;
}
if (fileType === null) {
console.error("Invalid filetype found for key: " + srcKey);
return;
}
fileType = fileType[0].substr(1);
if (ALLOWED_FILETYPES.indexOf(fileType) === -1) {
console.error("Filetype " + fileType + " not valid for thumbnail, exiting");
return;
}
async.waterfall([
function download(next) {
//Download the image from S3
s3.getObject({
Bucket: bucket,
Key: srcKey
}, next);
},
function createThumbnail(response, next) {
var temp_file, image;
if(fileType === "pdf") {
temp_file = mktemp.createFileSync("/tmp/XXXXXXXXXX.pdf")
fs.writeFileSync(temp_file, response.Body);
image = gm(temp_file + "[0]");
} else if (fileType === 'gif') {
temp_file = mktemp.createFileSync("/tmp/XXXXXXXXXX.gif")
fs.writeFileSync(temp_file, response.Body);
image = gm(temp_file + "[0]");
} else {
image = gm(response.Body);
}
image.size(function(err, size) {
/*
* scalingFactor should be calculated to fit either the width or the height
* within 150x150 optimally, keeping the aspect ratio. Additionally, if the image
* is smaller than 150px in both dimensions, keep the original image size and just
* convert to png for the thumbnail's display
*/
var scalingFactor = Math.min(1, THUMB_WIDTH / size.width, THUMB_HEIGHT / size.height),
width = scalingFactor * size.width,
height = scalingFactor * size.height;
this.resize(width, height)
.toBuffer("jpg", function(err, buffer) {
if(temp_file) {
fs.unlinkSync(temp_file);
}
if (err) {
next(err);
} else {
next(null, response.contentType, buffer);
}
});
});
},
function uploadThumbnail(contentType, data, next) {
s3.putObject({
Bucket: bucket,
Key: dstKey,
Body: data,
ContentType: "image/jpg",
ACL: 'public-read',
Metadata: {
thumbnail: 'TRUE'
}
}, next);
}
],
function(err) {
if (err) {
console.error(
"Unable to generate thumbnail for '" + bucket + "/" + srcKey + "'" +
" due to error: " + err
);
} else {
console.log("Created thumbnail for '" + bucket + "/" + srcKey + "'");
}
context.done();
});
};