Skip to content

Instantly share code, notes, and snippets.

@stephencoe
Last active December 28, 2018 11:20
Show Gist options
  • Save stephencoe/a7a3581141582b02fc7e to your computer and use it in GitHub Desktop.
Save stephencoe/a7a3581141582b02fc7e to your computer and use it in GitHub Desktop.
Serve cached images from s3 instead of cloudinary. It needs tidying but it works and reduces bandwidth dramatically. - inspired by https://gist.github.com/dboskovic/23858511bf3c1cbebdbd
//...
Model.add({
content: {
type: Types.Html, wysiwyg: true, height: 400
},
hash : {
type : String,
hidden : true
},
cachedContent : {
type : Types.Html,
hidden : true
},
});
var jsdom = require('jsdom');
var crypto = require('crypto');
var request = require('request');
var path = require('path');
var fs = require('fs');
var s3 = require('s3');
var imageCache = keystone.list('ImageCache').model;
var tempDir = path.join(process.cwd(), 'temp/');
var s3Bucket = 'YOUR_BUCKET';
if (!fs.existsSync(tempDir)) {
fs.mkdirSync(tempDir);
}
//...
/**
* Parse the content and cache wysiwyg content
*/
locals.renderCachedContent = function(content, contentField){
if(content.cachedContent && content.hash === crypto.createHash('md5').update(content[contentField]).digest('hex')) {
console.log('content cached');
return content.cachedContent;
}
console.log('not cached', content.hash);
var _content = '';
jsdom.env(
content[contentField],
["http://code.jquery.com/jquery.js"],
function (errors, window) {
total = window.$("img").length;
var _content = content[contentField];
// loop all images
window.$.each(window.$("img"), function(i, v){
// not a cloudinary image
if(!/cloudinary/.test(v.src)) {
console.log('not cloudinary');
return false;
}
function saveImage($img) {
var fileName = hash + '.jpg';
request(v.src)
.pipe(fs.createWriteStream(tempDir + fileName))
.on('close', function (error, response, body) {
var params = {
localFile: tempDir + fileName,
s3Params: {
Bucket: s3Bucket,
Key: 'c/' + fileName,
ACL:'public-read',
ContentType:'image/jpeg'
},
};
var uploader = s3Client.uploadFile(params);
uploader.on('error', function(err) {
console.log('error caching image', err)
$img.remove()
})
.on('end', function() {
if(!$img) {
console.log('unknown issue');
return;
}
console.log('successful image upload', v.src)
$img.uploaded = true;
$img.save()
console.log($img);
});
});
}
var hash = crypto.createHash('md5').update(v.src).digest('hex');
imageCache.where({hash:hash})
.findOne(function(err,data){
// no cache found
if(!data){
imageCache.create({ hash:hash, uploaded: false},function(err, $img){
saveImage(data);
});
}
if(data && !data.uploaded) {
saveImage(data);
}
console.log('uploaded to s3');
_content = _content.replace(v.src, 'http://' + s3Bucket + '.s3.amazonaws.com/c/' + hash + '.jpg');
content.cachedContent = _content;
content.hash = crypto.createHash('md5').update(content[contentField]).digest('hex');
content.save();
});
}); //end each
console.log(content.hash, crypto.createHash('md5').update(content[contentField]).digest('hex'));
}
);
return content.content;
};
div!= renderCachedContent(model, 'content')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment