Skip to content

Instantly share code, notes, and snippets.

@joeainsworth
Last active July 28, 2017 13:36
Show Gist options
  • Save joeainsworth/779863c80060569cd5dc98d5900826f5 to your computer and use it in GitHub Desktop.
Save joeainsworth/779863c80060569cd5dc98d5900826f5 to your computer and use it in GitHub Desktop.
const AWS = require('aws-sdk');
const bodyParser = require('body-parser');
const config = require('./config.json');
const cors = require('cors');
const express = require('express');
const fs = require('fs-extra');
const gm = require('gm');
const Promise = require('promise');
const uuidv1 = require('uuid/v1');
AWS.config.loadFromPath('./config.json');
const app = express();
const s3 = new AWS.S3({apiVersion: '2006-03-01'});
app.listen(3000, function () {
console.log('App listening on port 3000!')
});
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cors({ origin: 'http://off.aiir.com' }));
app.post('/', function(req, res) {
const s3Url = 'http://s3-'+config.region+'.amazonaws.com/'+config.S3bucket+'/';
const dir = './tmp/'+uuidv1()+'/'
fs.mkdirSync(dir);
let colour = '#ffffff';
if (req.body.background.startsWith('#')) colour = req.body.background;
const canvas = [
{ name: 'launch', size: [2048, 2048], logo: [1000, 1350], colour: colour },
{ name: 'icon', size: [2048, 2048], logo: [1750, 1700], colour: colour },
];
const background = { type: 'background', val: req.body.background }
const logo = { type: 'logo', val: req.body.logo }
const alerts = [];
function createCanvas(canvas) {
return Promise.all(canvas.map(canvas => {
return new Promise((resolve, reject) => {
const path = dir+canvas.name+'.png';
gm(canvas.size[0], canvas.size[1], canvas.colour)
.write(path, error => {
if (error) return reject(error);
canvas.path = path;
resolve(canvas);
})
});
}));
}
function getImage(image) {
return new Promise((resolve, reject) => {
s3.getObject({ Bucket: config.S3bucket, Key: image.val }, (error, data) => {
if (error) return reject(error);
image.data = data['Body'];
resolve(image);
});
});
}
function saveImage(image) {
return new Promise((resolve, reject) => {
const format = image.val.substr(image.val.lastIndexOf('.'));
const path = dir+image.type+format;
gm(image.data)
.write(path, error => {
if (error) return reject(error);
image.path = path;
resolve(image);
});
});
}
function imageSmallerThanCanvas(imageType, imageData, canvas) {
let size;
if (imageType == 'background') size = canvas.size;
else size = canvas.logo;
if (imageData.size.width < size[0] || imageData.size.height < size[1]) {
return true
}
}
function addBackgroundToCanvas(background) {
return Promise.all(canvas.map(canvas => {
return new Promise((resolve, reject) => {
gm(background.path).identify((error, image) => {
let path = dir+canvas.name+'.png';
let offset = [
((image.size.width-canvas.size[0])/2),
((image.size.height-canvas.size[1])/2)
];
if (imageSmallerThanCanvas(background.type, image, canvas)) {
gm(canvas.path)
.command('composite')
.in('-gravity', 'center')
.in('-geometry', `x${canvas.size[1]}`)
.in(background.path)
.write(path, error => {
if (error) return reject(error);
canvas.path = path;
resolve(background);
});
} else {
gm(canvas.path)
.command('convert')
.in('-crop', `${canvas.size[0]}x${canvas.size[1]}+${offset[0]}+${offset[1]}`)
.in(background.path)
.write(path, error => {
if (error) return reject(error);
canvas.path = path;
resolve(canvas);
});
}
});
});
}));
}
function addAlert(type, size, dimension) {
alerts.push({ type: type, size: size, message: 'Your ' + type + ' should be at least ' + size + ' px ' + dimension })
}
function imageSmallerThanCanvas(image, canvas) {
if ((image.size.width > image.size.height || image.size.width == image.size.height) && canvas.logo[0] > image.size.width) {
if (0 < alerts.length) {
alerts.forEach(function(alert) {
if (alert.type == 'logo' && canvas.logo[0] > alert.size) {
alert.size = canvas.logo[0];
alert.message = 'Your logo should be at least ' + canvas.logo[0] + 'px wide';
}
});
} else {
addAlert('logo', canvas.logo[0], 'wide');
}
} else if (canvas.logo[1] > logo.size.height) {
if (0 < alerts.length) {
alerts.forEach(function(alert, i) {
if (alert.type == 'logo' && canvas.logo[1] > alert.size) {
alert.size = canvas.logo[1];
alert.message = 'Your logo should be at least ' + canvas.logo[1] + 'px high';
}
});
} else {
addAlert('logo', canvas.logo[1], 'high');
}
}
}
function addLogoToCanvas(logo) {
return Promise.all(canvas.map(canvas => {
return new Promise((resolve, reject) => {
gm(logo.path).identify((error, image) => {
let path = dir+canvas.name+'.png';
imageSmallerThanCanvas(image, canvas);
gm(canvas.path)
.command('composite')
.in('-gravity', 'center')
.in('-geometry', `${canvas.logo[0]}x${canvas.logo[1]}`)
.in(logo.path)
.write(path, error => {
if (error) return reject(error);
canvas.path = path;
resolve(canvas);
});
});
});
}));
}
function uploadFiles(canvas) {
return Promise.all(canvas.map(canvas => {
return new Promise((resolve, reject) => {
const key = Date.now()+'_'+canvas.path.substr(canvas.path.lastIndexOf('/') + 1)
s3.putObject({
ACL: 'public-read',
Bucket: config.S3bucket,
Body: fs.createReadStream(canvas.path),
Key: key
}, (error, data) => {
if (error) return reject(error);
canvas.s3Url = s3Url+key;
resolve(canvas);
});
});
}));
}
function respond(status, images = null, alerts = null) {
res.status(status).send({ images: images, alerts: alerts });
}
function removeAssets() {
fs.remove(dir);
}
createCanvas(canvas)
.then(function(res) {
if (!background.val.startsWith('#')) return getImage(background);
})
.then(function(res) {
if (!background.val.startsWith('#')) return saveImage(background);
})
.then(function(res) {
if (!background.val.startsWith('#')) return addBackgroundToCanvas(background);
})
.then(function(res) {
return getImage(logo);
})
.then(function(res) {
return saveImage(logo);
})
.then(function(res) {
return addLogoToCanvas(logo);
})
.then(function(res) {
return uploadFiles(canvas);
})
.then(function(res) {
console.log(alerts);
respond(200, canvas, alerts);
removeAssets();
})
.catch(function (res) {
console.log(res)
respond(400);
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment