From 81c51cdbbee577629f11619a6bb51d14423a2d6d Mon Sep 17 00:00:00 2001 From: jomo Date: Sun, 19 Oct 2014 23:28:21 +0200 Subject: [PATCH] do not extract face on every request, store face only --- routes/avatars.js | 17 ++++++----------- skins.js | 47 ++++++++++++++++++++++++++++++++++------------ skins/tmp/.gitkeep | 0 3 files changed, 41 insertions(+), 23 deletions(-) create mode 100644 skins/tmp/.gitkeep diff --git a/routes/avatars.js b/routes/avatars.js index f1c8035..73714a7 100644 --- a/routes/avatars.js +++ b/routes/avatars.js @@ -7,27 +7,22 @@ var valid_uuid = /^[0-9a-f]{32}$/; /* GET home page. */ router.get('/:uuid/:size?', function(req, res) { - //res.render('index', { title: 'Express' }); - //res.send("uuid is set to " + req.param("uuid")); - //console.log(req.param('size')) var uuid = req.param('uuid'); var size = req.param('size') || 180; console.log(uuid); if (valid_uuid.test(uuid)) { - var filename = 'skins/' + uuid + ".png"; - if (fs.existsSync(filename)) { - skins.extract_face(filename, size, function() { - skins.extract_face(filename, size, function(data) { - res.writeHead(200, {'Content-Type': 'image/png'}); - res.end(data); - }); + var filename = uuid + ".png"; + if (fs.existsSync("skins/" + filename)) { + skins.resize_img(filename, size, function(data) { + res.writeHead(200, {'Content-Type': 'image/png'}); + res.end(data); }); } else { skins.get_profile(uuid, function(profile) { var skinurl = skins.skin_url(profile); if (skinurl) { skins.skin_file(skinurl, filename, function() { - skins.extract_face(filename, size, function(data) { + skins.resize_img(filename, size, function(data) { res.writeHead(200, {'Content-Type': 'image/png'}); res.end(data); }); diff --git a/skins.js b/skins.js index fae3ad1..1f27951 100644 --- a/skins.js +++ b/skins.js @@ -8,6 +8,18 @@ var lwip = require('lwip'); * Skin retrieval methods are based on @jomo's CLI Crafatar implementation. * https://github.com/jomo/Crafatar */ + +function extract_face(inname, outname, callback) { + var outfile = fs.createWriteStream(outname); + lwip.open(inname, function(err, image) { + image.batch() + .crop(8, 8, 15, 15) + .writeFile(outname, function(err) { + callback(); + }); + }); +} + module.exports = { get_profile: function(uuid, callback) { https.get("https://sessionserver.mojang.com/session/minecraft/profile/" + uuid, function(res) { @@ -17,10 +29,14 @@ module.exports = { } res.on('data', function(d) { var profile = JSON.parse(d); - if (profile.error) callback(null); - callback(profile); + if (profile.error) { + console.error(profile.error); + callback(null); + } else { + callback(profile); + } }); - + }).on('error', function(e) { console.error(e); }); @@ -41,22 +57,29 @@ module.exports = { }, skin_file: function(url, filename, callback) { - var file = fs.createWriteStream(filename); + var tmpname = "skins/tmp/" + filename; + var outname = "skins/" + filename; + var tmpfile = fs.createWriteStream(tmpname); http.get(url, function(res) { res.on('data', function(data) { - file.write(data); + tmpfile.write(data); }).on('end', function() { - file.end(); - callback(); + tmpfile.end(); + extract_face(tmpname, outname, function() { + fs.unlink(tmpname, function(err) { // unlink = delete + if (err) console.error(err); + }); + callback(); // outside unlink callback cause we don't have to wait until it's deleted + }); }); }); }, - extract_face: function(infile, size, callback) { - lwip.open(infile, function(err, image){ + + resize_img: function(inname, size, callback) { + lwip.open("skins/" + inname, function(err, image) { image.batch() - .crop(8,8,15,15) - .resize(size, size, "nearest-neighbor") - .toBuffer('png', function(err, buffer){ + .resize(size, size, "nearest-neighbor") // nearest-neighbor doesn't blur + .toBuffer('png', function(err, buffer) { callback(buffer); }); }); diff --git a/skins/tmp/.gitkeep b/skins/tmp/.gitkeep new file mode 100644 index 0000000..e69de29