Skip to content

Instantly share code, notes, and snippets.

@Robert-Wett
Created November 24, 2015 19:54
Show Gist options
  • Save Robert-Wett/7dde37db2288c77928b1 to your computer and use it in GitHub Desktop.
Save Robert-Wett/7dde37db2288c77928b1 to your computer and use it in GitHub Desktop.
POC lambda func to strip exif from jpegs; needs to use two different bucket sources though
var path = require( 'path' );
var aws = require( 'aws-sdk' );
var exec = require( 'child_process' ).exec;
var cmd = "exiftool -Orientation='' ";
var promise = require( 'bluebird' );
var fs = require( 'fs' );
var s3 = new aws.S3({apiVersion: '2006-03-01'});
function handler( event, context ) {
var bucketname = event.Records[0].s3.bucket.name || null;
var key = decodeURIComponent( event.Records[0].s3.object.key.replace(/\+/g, " ") ) || null;
if ( key === null || ['jpg', 'jpeg'].indexOf( getFileExtensionFromKey(key) ) ) {
console.log('Skipping this file');
context.succeed();
return;
}
getJobRecordObject( bucketname, key )
.then(ensureTmpDirectory)
.then(downloadFileToDisk)
.then(stripOrientationExifData)
.then(uploadNewImage)
.then(cleanupFile)
.catch(console.log);
.catch(promise.TimeoutError, function( timeoutError ) {
console.log(timeoutError);
context.fail();
})
.finally(function() {
context.succeed();
})
}
function getJobRecordObject( bucket, key ) {
var _filename = path.basename( key );
var _filepath = guid() + '_' + _filename;
return promise.resolve({
bucket: bucket,
key: key,
filename: _filename,
filepath: _filepath,
cmd: "exiftool -Orientation= -overwrite_original " + _filepath
});
}
function ensureTmpDirectory( opts ) {
return promise.try( function() {
if ( fs.existsSync( '/tmp' ) ) {
return opts;
}
fs.mkdir( '/tmp', function( err, response ) {
if ( err ) {
throw err;
}
return opts;
}).bind(this);
}).bind(this);
}
function downloadFileToDisk( opts ) {
return promise.race([
new promise( function( resolve, reject ) {
var writeStream = fs.createWriteStream( opts.filepath );
writeStream.on( 'error', function onWriteStreamError( writeStreamError ) {
return reject( writeStreamError );
});
writeStream.on( 'finish', function onWriteStreamFinish() {
writeStream = null;
return resolve( opts );
});
s3.getObject({Bucket: opts.bucket, Key: opts.key}, function getObjectHandler( getObjectError, data ) {
if ( getObjectError ) {
return reject( getObjectError );
}
else {
writeStream.pipe( data );
}
});
}),
new promise( function( resolve, reject ) {
setTimeout( reject, 10000 )
})
]);
}
function stripOrientationExifData( opts ) {
return new promise( function( resolve, reject ) {
exec( opts.cmd, function( err, stdout ) {
if ( err ) {
return reject( err );
}
if ( !~stdout.indexOf('1 image files updated') ) {
return reject( new Error( stdout ) );
}
resolve( opts );
}).bind(this)
}).bind(this)
}
function uploadNewImage( opts ) {
var imageBody = os.readFileSync( opts.filePath );
var uploadData = new Buffer( imageBody, 'binary' );
return new promise( function( resolve, reject ) {
s3.putObject(
{
Bucket: opts.bucket,
Key: opts.key,
Body: uploadData,
ACL: 'public-read-write',
ContentType: 'application/octet-stream'
},
function( putObjectError, results ) {
if ( putObjectError ) {
reject( putObjectError );
} else {
resolve( opts );
}
});
})
}
function cleanupFile( opts ) {
try {
os.removeSync( opts.filepath );
} catch ( e ) {
console.log( e );
}
}
function getFileExtensionFromKey( key ) {
return path.extname( path.basename( key ) ).slice(1).toLowerCase();
}
function guid() {
function s4() {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
}
return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
s4() + '-' + s4() + s4() + s4();
}
module.exports = handler;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment