Last active
July 28, 2017 13:36
-
-
Save joeainsworth/779863c80060569cd5dc98d5900826f5 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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