#!/usr/bin/node const fs = require('fs'); const path = require('path'); const AWS = require('aws-sdk'); const Promise = require('bluebird'); const imagemin = require('imagemin'); const imageminJpegRecompress = require('imagemin-jpeg-recompress'); const config = { sslEnabled: true, bucket: process.env.AWS_BUCKET, region: process.env.AWS_REGION, accessKeyId: process.env.AWS_ACCESS_KEY, secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY }; AWS.config.update(config); const s3Bucket = config.bucket; const s3Endpoint = 's3.' + config.region + '.amazonaws.com'; const s3PublicEndpoint = 'https://' + config.bucket + '.s3.amazonaws.com/'; const s3 = new AWS.S3({ signatureVersion: 'v4', endpoint: s3Endpoint }); const optimizeImage = (image) => { let imageminOptions = { plugins: [ imageminJpegRecompress({ progressive: true, quality: 'high', accuracy: true, target: 0.995, min: 60, max: 95 }) ] }; return imagemin.buffer(image.Body, imageminOptions) .then((buffer) => { console.info('Optimizing Image Finished:', image.Key); console.log('Prev Size', Math.round(image.Body.toString().length / 1000) + 'KB'); console.log('New Size', Math.round(buffer.toString().length / 1000) + 'KB\n'); return { Body: buffer, Key: image.Key }; }) .catch((error) => { console.error('Image Optimization Error:', image.Key, error); }); }; const listImages = (params) => { return new Promise((resolve, reject) => { s3.listObjects(params, (error, images) => { return error ? reject(error) : resolve(images); }); }); }; const getImage = (image) => { let params = { Bucket: config.bucket, Key: image.Key }; return new Promise((resolve, reject) => { s3.getObject(params, (error, image) => { image ? image.Key = params.Key : null; return error ? reject(error) : resolve(image); }); }); }; const setImage = (image) => { if(!(image && image.Key && image.Body)) { return Promise.resolve(); } let params = { Body: image.Body, Key: image.Key, Bucket: config.bucket, ACL: "public-read", ContentType: "image/jpeg", CacheControl: "max-age=86400, public" }; return new Promise((resolve, reject) => { s3.putObject(params, (error) => { console.log('\nUploaded', params.Key, error ? error : ''); return error ? reject(error) : resolve(); }); }); }; const optimize = (image) => { return getImage(image) .then(optimizeImage) .then(setImage) .catch(console.error); }; const run = (Marker, oneRun) => { let params = { Bucket: config.bucket, MaxKeys: oneRun ? 1 : 100 }; params.Marker = Marker; console.log('\nNext Marker', Marker); return listImages(params) .then((data) => { console.log('\nTotal Length:', data.Contents.length); return Promise.map(data.Contents, optimize) .then(() => data.IsTruncated && !oneRun ? run(data.Contents.slice(-1)[0].Key) : null); }); }; return run(process.argv[2], process.argv[3]);