Mercurial > eldonilo > avatar
changeset 20:e4916f1763e5
Deactivable debug; fix a stupid bug in gravatar; add a better default image and make it configurable.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Sat, 16 Jul 2011 13:54:47 +0200 |
parents | 9ff8f951da99 |
children | 46c42ec52680 |
files | avatar.js configuration.js.example |
diffstat | 2 files changed, 56 insertions(+), 29 deletions(-) [+] |
line wrap: on
line diff
--- a/avatar.js +++ b/avatar.js @@ -41,20 +41,23 @@ process.addListener('uncaughtException', console.log('[41;1mUncaught exception (' + err + '), this should never happen:[0m\n' + err.stack); }); -(function() { - var send = conn.send; - conn.send = function(s) { - util.log('Sent: [1;32m' + s + '[0m'); - send.call(conn, s); - }; -})(); +if (config.debug) + (function() { + var send = conn.send; + conn.send = function(s) { + console.log('Sent: [1;32m' + s + '[0m'); + send.call(conn, s); + }; + })(); conn.on('online', function () { - console.log('Connected'); + util.log('Connected'); }); conn.on('stanza', function (stanza) { - util.log('Recv: [1;34m' + stanza + '[0m'); + if (config.debug) + console.log('Recv: [1;34m' + stanza + '[0m'); + if (stanza.is('iq')) onIq(stanza); else @@ -73,12 +76,26 @@ var jids = {}; var sent = {}; var svgError = function(res, message) { + util.log('No avatar at all, display a default image with the error in the title.'); + res.writeHead(200, {'Content-Type': 'image/svg+xml'}); res.write('<?xml version="1.0" encoding="UTF-8"?>\n'); - res.write('<svg xmlns="http://www.w3.org/2000/svg" viewBox="-32 -36 64 64">\n'); - res.write('\t<title>'+message+'</title>\n'); - res.write('\t<rect x="-32" y="-36" width="64" height="64" fill="white"/>\n'); - res.write('\t<text font-family="sans-serif" font-weight="bold" text-anchor="middle">Error</text>\n'); + res.write('<svg xmlns="http://www.w3.org/2000/svg"'); + + if (config.defaultImage) + res.write(' xmlns:xlink="http://www.w3.org/1999/xlink"'); + + res.write(' viewBox="0 0 64 64">\n'); + res.write('\t<title>' + message + '</title>\n'); + + if (config.defaultImage) + res.write('\t<image width="64" height="64" xlink:href="' + config.defaultImage + '"/>\n'); + else { + res.write('\t<rect width="64" height="64" fill="silver"/>\n'); + res.write('\t<circle cx="32" cy="26" r="14" fill="white"/>\n'); + res.write('\t<ellipse cx="32" cy="64" rx="24" ry="26" fill="white"/>\n'); + } + res.end('</svg>\n'); } @@ -92,14 +109,16 @@ var makeError = function(response) { } if (config.useGravatar) - var noAvatar = function(res, from, message) { + var noAvatar = function(res, to, message) { var options = { host: 'gravatar.com', port: 80, - path: '/avatar/' + hash('md5').update(from).digest('hex') + '?d=404', + path: '/avatar/' + hash('md5').update(to).digest('hex') + '?d=404', method: 'GET' }; + util.log('No XMPP avatar, falling back to Gravatar for ' + to + '.'); + var r = http.request(options, function(r) { if (r.statusCode != 200) return svgError(res, message + ' Additionaly, no gravatar available.'); @@ -121,7 +140,8 @@ if (config.useGravatar) return r.end(); }; else - var noAvatar = function(res, _, message) { + var noAvatar = function(res, to, message) { + util.log('No XMPP avatar for ' + to + '.'); return svgError(res, message); }; @@ -148,12 +168,12 @@ function onIq(stanza) { var err = 'none'; } - return noAvatar(res, from, 'Error during query of this user’s vCard: “'+err+'”.'); + return noAvatar(res, to, 'Error during query of this user’s vCard: “'+err+'”.'); } var vCard = stanza.getChild('vCard', 'vcard-temp'); if (!vCard) - return noAvatar(res, from, 'Error: this user doesn’t have a vCard.'); + return noAvatar(res, to, 'Error: this user doesn’t have a vCard.'); try { var photo = vCard.getChild('PHOTO', 'vcard-temp'); @@ -165,7 +185,7 @@ function onIq(stanza) { if (config.guessType) type = 'image/png'; // FIXME: use magic. else - return noAvatar(res, from, 'Error: this user’s vCard doesn’t specify the MIME type of its avatar.'); + return noAvatar(res, to, 'Error: this user’s vCard doesn’t specify the MIME type of its avatar.'); } var ext; @@ -176,7 +196,7 @@ function onIq(stanza) { // Here we don’t try to guess the extension even if the option is set. if (ext === undefined) { console.log('Unknown MIME type: '+type); - return noAvatar(res, from, 'Error: this user’s avatar is in an unknown format.'); + return noAvatar(res, to, 'Error: this user’s avatar is in an unknown format.'); } var binval = new Buffer(base64.replace(/\n/g, ''), 'base64'); @@ -186,7 +206,7 @@ function onIq(stanza) { showImage(to, res); }); } catch (e) { - return noAvatar(res, from, 'Error: this user doesn’t have an avatar in his/her vCard.'); + return noAvatar(res, to, 'Error: this user doesn’t have an avatar in his/her vCard.'); } } @@ -250,11 +270,11 @@ fs.readdir(config.directory, function(er }); http.createServer(function (req, res) { - console.log('Connection from ' + (req.headers['x-forwarded-for'] || req.client.remoteAddress) + ' (' + req.headers['user-agent'] + ') to ' + req.method.toLocaleLowerCase() + ' “' + req.url + '”.'); + util.log('Connection from ' + (req.headers['x-forwarded-for'] || req.client.remoteAddress) + ' (' + req.headers['user-agent'] + ') to ' + req.method.toLocaleLowerCase() + ' “' + req.url + '”.'); var easterEggs = { source: { - re: new RegExp(config.webRoot + 'source/code$'), + re: new RegExp('^' + config.webRoot + 'source/code$'), file: process.argv[1], mime: 'application/ecmascript', error: 'source code unavailable! oO' @@ -273,11 +293,11 @@ http.createServer(function (req, res) { for (var i in easterEggs) { var ee = easterEggs[i]; var file = ee.file || i; - var re = ee.re || new RegExp(config.webRoot + file + '$'); + var re = ee.re || new RegExp('^' + config.webRoot + file + '$'); if (re.test(req.url)) { fs.readFile(file, function(err, content) { if (err) - return noAvatar(res, from, 'Error: ' + (ee.error || file + ' unavailable.')); + return noAvatar(res, to, 'Error: ' + (ee.error || file + ' unavailable.')); res.writeHead(200, {'Content-Type': ee.mime || 'text/plain'}); res.end(content); @@ -286,7 +306,7 @@ http.createServer(function (req, res) { } } - var jid = unescape(req.url.replace(new RegExp(config.webRoot), '')); + var jid = unescape(req.url.replace(new RegExp('^' + config.webRoot), '')); if (jid === 'redirect') { if (req.method !== 'POST') {
--- a/configuration.js.example +++ b/configuration.js.example @@ -21,11 +21,11 @@ var config = exports; // The JID and password of the account used. -config.jid = 'avatar.example.org'; +config.jid = 'avatar@example.org'; config.password = 'hellohello'; // Root of the webservice, useful if you want to proxy it. -config.webRoot = '^/avatar/'; +config.webRoot = '/avatar/'; // These are the host and the port on which the web service will // listen. If you want IPv4 connection only, instead of both IPv4 and @@ -54,5 +54,12 @@ config.extensions = { gif: 'image/gif' }; +// Image to use as fallback when there is no usable avatar. If not set, +// a SVG image will be displayed. +//config.defaultImage = 'http://example.org/default.svg'; + // Try Gravatar if there is a problem during XMPP avatar retrieving. -config.useGravatar = true; +//config.useGravatar = false; + +// Prints XMPP stanzas +config.debug = false;