Allow {png,gif,jpg,pdf} output.
This commit is contained in:
parent
de668667d3
commit
16da2eee02
|
@ -9,9 +9,10 @@
|
|||
},
|
||||
"license": "CC0",
|
||||
"dependencies": {
|
||||
"dot": ">=1.0.2",
|
||||
"dot": "~1.0.2",
|
||||
"svgo": "~0.4.2",
|
||||
"canvas": "~1.1.2",
|
||||
"phantomjs": "~1.9.2-6",
|
||||
"es6-promise": "~0.1.1",
|
||||
"camp": "~13.11.9"
|
||||
},
|
||||
|
|
27
phantomjs-svg2png.js
Normal file
27
phantomjs-svg2png.js
Normal file
|
@ -0,0 +1,27 @@
|
|||
var page = require('webpage').create();
|
||||
var system = require('system');
|
||||
var svg = system.args[1];
|
||||
var svgUrl = 'data:image/svg+xml,' + window.encodeURI(svg);
|
||||
var tmpFile = system.args[2];
|
||||
|
||||
page.viewportSize = getSvgDimensions(svg);
|
||||
page.open(svgUrl, function(status) {
|
||||
if (status !== 'success') {
|
||||
console.error('Failed to load the following SVG data:');
|
||||
console.error(svgUrl);
|
||||
phantom.exit(1);
|
||||
} else {
|
||||
page.render(tmpFile);
|
||||
phantom.exit();
|
||||
}
|
||||
});
|
||||
|
||||
function getSvgDimensions(svg) {
|
||||
var frag = window.document.createElement('div');
|
||||
frag.innerHTML = svg;
|
||||
var svgRoot = frag.querySelector('svg');
|
||||
return {
|
||||
width: parseFloat(svgRoot.getAttribute('width') || 80),
|
||||
height: parseFloat(svgRoot.getAttribute('height') || 19)
|
||||
};
|
||||
}
|
36
server.js
36
server.js
|
@ -2,6 +2,7 @@ var camp = require('camp').start({
|
|||
port: process.env.PORT||+process.argv[2]||80
|
||||
});
|
||||
var badge = require('./badge.js');
|
||||
var svg2img = require('./svg-to-img.js');
|
||||
var serverStartTime = new Date((new Date()).toGMTString());
|
||||
|
||||
// Escapes `t` using the format specified in
|
||||
|
@ -18,12 +19,14 @@ function escapeFormat(t) {
|
|||
|
||||
function sixHex(s) { return /^[0-9a-fA-F]{6}$/.test(s); }
|
||||
|
||||
camp.route(/^\/(([^-]|--)+)-(([^-]|--)+)-(([^-]|--)+).svg$/,
|
||||
camp.route(/^\/(([^-]|--)+)-(([^-]|--)+)-(([^-]|--)+).(svg|png|gif|jpg|pdf)$/,
|
||||
function(data, match, end, ask) {
|
||||
var subject = escapeFormat(match[1]);
|
||||
var status = escapeFormat(match[3]);
|
||||
var color = escapeFormat(match[5]);
|
||||
ask.res.setHeader('Content-Type', 'image/svg+xml');
|
||||
var format = match[7];
|
||||
|
||||
// Cache management.
|
||||
var cacheDuration = (3600*24*1)|0; // 1 day.
|
||||
ask.res.setHeader('Cache-Control', 'public, max-age=' + cacheDuration);
|
||||
if (+(new Date(ask.req.headers['if-modified-since'])) >= +serverStartTime) {
|
||||
|
@ -32,6 +35,8 @@ camp.route(/^\/(([^-]|--)+)-(([^-]|--)+)-(([^-]|--)+).svg$/,
|
|||
return;
|
||||
}
|
||||
ask.res.setHeader('Last-Modified', serverStartTime.toGMTString());
|
||||
|
||||
// Badge creation.
|
||||
try {
|
||||
var badgeData = {text: [subject, status]};
|
||||
if (sixHex(color)) {
|
||||
|
@ -39,16 +44,31 @@ camp.route(/^\/(([^-]|--)+)-(([^-]|--)+)-(([^-]|--)+).svg$/,
|
|||
} else {
|
||||
badgeData.colorscheme = color;
|
||||
}
|
||||
badge(badgeData, function(res) {
|
||||
end(null, {template: streamFromString(res)});
|
||||
});
|
||||
badge(badgeData, makeSend(format, ask.res, end));
|
||||
} catch(e) {
|
||||
badge({text: ["error", "bad badge"], colorscheme: "red"}, function(res) {
|
||||
end(null, {template: streamFromString(res)});
|
||||
});
|
||||
badge({text: ["error", "bad badge"], colorscheme: "red"},
|
||||
makeSend(format, ask.res, end));
|
||||
}
|
||||
});
|
||||
|
||||
function makeSend(format, askres, end) {
|
||||
if (format === 'svg') {
|
||||
return function(res) { sendSVG(res, askres, end); };
|
||||
} else {
|
||||
return function(res) { sendOther(format, res, askres, end); };
|
||||
}
|
||||
}
|
||||
|
||||
function sendSVG(res, askres, end) {
|
||||
askres.setHeader('Content-Type', 'image/svg+xml');
|
||||
end(null, {template: streamFromString(res)});
|
||||
}
|
||||
|
||||
function sendOther(format, res, askres, end) {
|
||||
askres.setHeader('Content-Type', 'image/' + format);
|
||||
svg2img(res, format, askres);
|
||||
}
|
||||
|
||||
var stream = require('stream');
|
||||
function streamFromString(str) {
|
||||
var newStream = new stream.Readable();
|
||||
|
|
22
svg-to-img.js
Normal file
22
svg-to-img.js
Normal file
|
@ -0,0 +1,22 @@
|
|||
var fs = require('fs');
|
||||
var os = require('os');
|
||||
var path = require('path');
|
||||
var phantom = require('phantomjs');
|
||||
var childProcess = require('child_process');
|
||||
var phantomScript = path.join(__dirname, 'phantomjs-svg2png.js');
|
||||
|
||||
module.exports = function (svg, format, out, cb) {
|
||||
var tmpFile = path.join(os.tmpdir(),
|
||||
"svg2img-" + (Math.random()*2147483648|0) + "." + format);
|
||||
// Conversion to PNG happens in the phantom script.
|
||||
childProcess.execFile(phantom.path, [phantomScript, svg, tmpFile],
|
||||
function(err, stdout, stderr) {
|
||||
if (stdout) { console.log(stdout); }
|
||||
if (stderr) { console.log(stderr); }
|
||||
if (err != null) { console.error(err.stack); if (cb) { cb(err); } return; }
|
||||
var inStream = fs.createReadStream(tmpFile);
|
||||
inStream.pipe(out);
|
||||
// Remove the temporary file after use.
|
||||
inStream.on('end', function() { fs.unlink(tmpFile, cb); });
|
||||
});
|
||||
};
|
Loading…
Reference in New Issue
Block a user